LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Code to display data from an ACS712 in LabWindows,Acs712 that is part of a lithium-ion battery charger

hello all.We made a charger for lithium ion batteries using, among others, ACS712, Arduino Uno and LCD 16X2. I would like to display the data read by the Acs 712 sensor also in labwindows.Through trials we arrived at the next skeleton of code. How can I fill in this code to achieve what I want?

Any suggestion would be welcome,thanks.

This is my skeleton code:

#include <utility.h>
#include <cvidef.h>
#include <userint.h>
#include <nidaqmx.h> // or the appropriate header for your hardware

#define sensorInput 0 // Aici introduce?i num?rul corect al canalului analogic pentru tensiune
#define CV_current 0.8 // Aici introduce?i valoarea corect? pentru curentul în modul CV
#define PANEL_NUMERIC_VOLTAGE 1 // Replace with the correct control ID
#define PANEL_NUMERIC_CURRENT 2 // Replace with the correct control ID
#define PANEL_PROGRESS_BAR 3 // Replace with the correct control ID
double batt_cap = 1000.0; // Aici introduce?i capacitatea bateriei în mAh
double currentReading = 0.0;
double voltageReading = 0.0;
double chargeLevel = 0.0; // Procentul de înc?rcare a bateriei

int panelHandle; // Declara?i variabila panelHandle aici
const char *PANEL = "Proiect.uir";

// Func?ia de citire a tensiunii ?i curentului
void ReadVoltageCurrent()
{
// Citire tensiune ?i curent
voltageReading = (double)GetAnalogChannelReading(0, sensorInput); // Aici trebuie s? configura?i corect canalul analogic
currentReading = voltageReading / 1000.0; // Conversie la amperi (sau ajusta?i pentru unitatea corect?)

// Calcul procent de înc?rcare (adaptat la pragurile dvs.)
if (currentReading <= 0.1 * batt_cap / 1000.0) // Aici ajusta?i pragurile ?i capacitatea bateriei
{
chargeLevel = 0.0;
}
else if (currentReading >= CV_current)
{
chargeLevel = 100.0;
}
else
{
chargeLevel = ((currentReading - 0.1 * batt_cap / 1000.0) / (CV_current - 0.1 * batt_cap / 1000.0)) * 100.0;
}

// Actualiza?i controalele pentru tensiune, curent ?i nivelul de înc?rcare
SetCtrlVal(panelHandle, PANEL_NUMERIC_VOLTAGE, voltageReading);
SetCtrlVal(panelHandle, PANEL_NUMERIC_CURRENT, currentReading);
SetCtrlVal(panelHandle, PANEL_PROGRESS_BAR, chargeLevel);
}

int main (int argc, char *argv[])
{
// Ini?ializarea LabWindows CVI aici

// Crea?i un panel pentru afi?are
panelHandle = LoadPanel(0, "Proiect.uir", 1); // 1 corresponds to loading a dialog

 


// Restul codului...

// Ini?ializa?i senzorul ?i alte set?ri
// ...

// Bucla principal?
while (1)
{
// Citirea ?i actualizarea datelor
ReadVoltageCurrent();

// Aici pute?i ad?uga logica pentru oprirea sau avertizarea în cazul une
}

// Închide?i panoul ?i elibera?i resursele
DiscardPanel(panelHandle);
return 0;
}

I have this erors momentary:Build Status (Proiect.prj - Debug)
ProiectMain.c - 1 error, 1 warning
23, 30 error: implicit declaration of function 'GetAnalogChannelReading' is invalid in C99. Make sure that you include the function prototype.
71, 5 warning: will never be executed
Build failed.

Download All
0 Kudos
Message 1 of 5
(1,643 Views)

Error text is quite clear: you must define your functions before you can use them. Add a definition for GetAnalogChannelReading () function at the beginning of your code and the build error will go away.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 5
(1,592 Views)

After multiple attempts I came to this version of code. I mention that this code compiles but when I try to run I have these 2 errors:

NON-FATAL RUN-TIME ERROR: "ProiectMain.c", line 95, col 19, thread id 7860: The callback function, PANEL_NUMERIC_VOLTAGE, specified in the UIR file, is not a known function. If you are using an external compiler, you must include the UIR callbacks object or source file in the executable or DLL.
FATAL RUN-TIME ERROR: "ProiectMain.c", line 102, col 14, thread id 7860: The program has caused a 'General Protection' fault at 0x645891C5.

This is my code:

#include <rs232.h>
#include <utility.h>
#include <cvidef.h>
#include <userint.h>
#include <nidaqmx.h> // sau alt header corespunz?tor pentru hardware-ul dvs.
#include <cvirte.h> // Incluziunea headerului CVI runtime corespunz?tor

#define sensorInput A0 // Num?rul corect al canalului analogic pentru tensiune
#define CV_current 0.8 // Valoarea corect? pentru curent în modul CV
#define PANEL_NUMERIC_VOLTAGE 2 // Înlocui?i cu ID-ul corect pentru controlul numeric
#define PANEL_NUMERIC_CURRENT 3 // Înlocui?i cu ID-ul corect pentru controlul numeric
#define PANEL_PROGRESS_BAR 4 // Înlocui?i cu ID-ul corect pentru bara de progres
double batt_cap = 2000.0; // Capacitatea bateriei în mAh
double currentReading = 0.0;
double voltageReading = 0.0;
double chargeLevel = 0.0; // Procentul de înc?rcare a bateriei

int panelHandle; // Declara?i variabila panelHandle aici
const char *PANEL = "Proiect.uir";
int numericControl = 1; // Înlocui?i cu ID-ul corect pentru controlul numeric

// Func?ia care cite?te datele seriale ?i le afi?eaz?
void ReadSerialData(int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
char buffer[256];
int bytesRead_serial = 0;
int serialPort = 1; // Sau num?rul portului serial corespunz?tor pe care dori?i s?-l utiliza?i
// Citirea datelor primite pe portul serial
bytesRead_serial = ComRdTerm(serialPort, buffer, sizeof(buffer), 1);

if (bytesRead_serial > 0)
{
// Conversia buffer-ului la un num?r, dac? este necesar
int sensorValue = atoi(buffer);

// Afi?a?i valoarea în controlul numeric din interfa?a utilizator
SetCtrlVal(panelHandle, 1, sensorValue);
// Update the voltage and current controls with sensor data
// Update the voltage and current controls with sensor data
SetCtrlVal(panelHandle, 2, sensorValue); // Assuming sensorValue holds the sensor data
SetCtrlVal(panelHandle, 3, currentReading); // Update currentReading with the current sensor data


}
}

// Func?ia de citire a tensiunii ?i curentului
void ReadVoltageCurrent()
{
TaskHandle taskHandle = 0; // Ini?ializa?i taskHandle

// Crea?i un task DAQmx pentru intrarea analogic?
DAQmxCreateTask("", &taskHandle);

// Ad?uga?i un canal de intrare analogic? (ajusta?i dup? nevoie)
DAQmxCreateAIVoltageChan(taskHandle, "A0", "", DAQmx_Val_Cfg_Default, -10.0, 10.0, DAQmx_Val_Volts, NULL);

// Citi?i datele de tensiune
DAQmxReadAnalogScalarF64(taskHandle, 10.0, &voltageReading, NULL);

// Închide?i task-ul
DAQmxClearTask(taskHandle);

// Converti?i tensiunea în curent (ajusta?i dup? nevoie)
currentReading = voltageReading / 1000.0;

// Calcula?i nivelul de înc?rcare ?i actualiza?i controalele
// Calcul procent de înc?rcare (adaptat la pragurile dvs.)
if (currentReading <= 0.1 * batt_cap / 1000.0) // Aici ajusta?i pragurile ?i capacitatea bateriei
{
chargeLevel = 0.0;
}
else if (currentReading >= CV_current)
{
chargeLevel = 100.0;
}
else
{
chargeLevel = ((currentReading - 0.1 * batt_cap / 1000.0) / (CV_current - 0.1 * batt_cap / 1000.0)) * 100.0;
}

// Actualiza?i controalele pentru tensiune, curent ?i nivelul de înc?rcare
SetCtrlVal(panelHandle, PANEL_NUMERIC_VOLTAGE, voltageReading);
SetCtrlVal(panelHandle, PANEL_NUMERIC_CURRENT, currentReading);
SetCtrlVal(panelHandle, PANEL_PROGRESS_BAR, chargeLevel);
}

int main(int argc, char *argv[])
{
int serialPort;
if (InitCVIRTE(0, argv, 0) == 0)
return -1;

// Crea?i un panou pentru afi?are
panelHandle = LoadPanel(0, "Proiect.uir", 1); // 1 corespunde înc?rc?rii unui dialog

// Configura?i portul serial pentru citirea datelor de la Arduino

int result;

// Deschide?i portul serial
result = OpenComConfig("A0", 9600, 0, 8, 1, 512, 512, &serialPort);

if (result < 0)
{
// A ap?rut o eroare la deschiderea portului serial
// Gestiunea erorilor aici
CloseCom(serialPort); // Închide?i portul serial în caz de eroare
return -1;
}

// Ini?ializa?i citirea datelor seriale
result = InstallComCallback(serialPort, LWRS_RXCHAR, 0, 0, ReadSerialData, 0);
if (result < 0)
{
// A ap?rut o eroare la instalarea handler-ului de citire
// Gestiunea erorilor aici
CloseCom(serialPort); // Închide?i portul serial în caz de eroare
return -1;
}

// Trimite?i un caracter pentru a ini?ia citirea datelor
char characterToSend = 'R';
result = ComWrt(serialPort, &characterToSend, 1);

if (result < 0)
{
// A ap?rut o eroare la trimiterea datelor seriale
// Gestiunea erorilor aici
CloseCom(serialPort); // Închide?i portul serial în caz de eroare
return -1;
}

// Rula?i interfa?a utilizatorului
RunUserInterface();

// Închide?i portul serial când închide?i aplica?ia
CloseCom(serialPort);

// Ini?ializa?i senzorul ?i alte set?ri
// ...

while (1)
{
// Citi?i ?i actualiza?i datele
ReadVoltageCurrent();
int conditionToExit = 0; // Defini?i ?i ini?ializa?i conditionToExit

// Aici pute?i ad?uga logica pentru oprirea sau avertizarea, dac? este necesar

// Verifica?i dac? trebuie s? încheia?i bucla ?i programul
if (conditionToExit) // Exemplu: dac? un anumit buton este ap?sat sau alt criteriu este îndeplinit
break;
}

// ...

// Închide?i panoul
DiscardPanel(panelHandle);

// Elibera?i resursele LabWindows CVI ?i ie?i?i din program
QuitUserInterface(0); // Exit the LabWindows CVI user interface

return 0;
}

How can I fix these problems, do I need help urgently?

 

Download All
0 Kudos
Message 3 of 5
(1,565 Views)

This is my code:
#include <rs232.h>
#include <utility.h>
#include <cvidef.h>
#include <userint.h>
#include <nidaqmx.h> // sau alt header corespunz?tor pentru hardware-ul dvs.
#include <cvirte.h> // Incluziunea headerului CVI runtime corespunz?tor

#define sensorInput A0 // Num?rul corect al canalului analogic pentru tensiune
#define CV_current 0.8 // Valoarea corect? pentru curent în modul CV
#define PANEL_NUMERIC_VOLTAGE 2 // Înlocui?i cu ID-ul corect pentru controlul numeric
#define PANEL_NUMERIC_CURRENT 3 // Înlocui?i cu ID-ul corect pentru controlul numeric
#define PANEL_PROGRESS_BAR 4 // Înlocui?i cu ID-ul corect pentru bara de progres
double batt_cap = 2000.0; // Capacitatea bateriei în mAh
double currentReading = 0.0;
double voltageReading = 0.0;
double chargeLevel = 0.0; // Procentul de înc?rcare a bateriei

int panelHandle; // Declara?i variabila panelHandle aici
const char *PANEL = "Proiect.uir";
int numericControl = 1; // Înlocui?i cu ID-ul corect pentru controlul numeric

// Func?ia care cite?te datele seriale ?i le afi?eaz?
void ReadSerialData(int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
char buffer[256];
int bytesRead_serial = 0;
int serialPort = 1; // Sau num?rul portului serial corespunz?tor pe care dori?i s?-l utiliza?i
// Citirea datelor primite pe portul serial
bytesRead_serial = ComRdTerm(serialPort, buffer, sizeof(buffer), 1);

if (bytesRead_serial > 0)
{
// Conversia buffer-ului la un num?r, dac? este necesar
int sensorValue = atoi(buffer);

// Afi?a?i valoarea în controlul numeric din interfa?a utilizator
SetCtrlVal(panelHandle, 1, sensorValue);
// Update the voltage and current controls with sensor data
// Update the voltage and current controls with sensor data
SetCtrlVal(panelHandle, 2, sensorValue); // Assuming sensorValue holds the sensor data
SetCtrlVal(panelHandle, 3, currentReading); // Update currentReading with the current sensor data


}
}

// Func?ia de citire a tensiunii ?i curentului
void ReadVoltageCurrent()
{
TaskHandle taskHandle = 0; // Ini?ializa?i taskHandle

// Crea?i un task DAQmx pentru intrarea analogic?
DAQmxCreateTask("", &taskHandle);

// Ad?uga?i un canal de intrare analogic? (ajusta?i dup? nevoie)
DAQmxCreateAIVoltageChan(taskHandle, "A0", "", DAQmx_Val_Cfg_Default, -10.0, 10.0, DAQmx_Val_Volts, NULL);

// Citi?i datele de tensiune
DAQmxReadAnalogScalarF64(taskHandle, 10.0, &voltageReading, NULL);

// Închide?i task-ul
DAQmxClearTask(taskHandle);

// Converti?i tensiunea în curent (ajusta?i dup? nevoie)
currentReading = voltageReading / 1000.0;

// Calcula?i nivelul de înc?rcare ?i actualiza?i controalele
// Calcul procent de înc?rcare (adaptat la pragurile dvs.)
if (currentReading <= 0.1 * batt_cap / 1000.0) // Aici ajusta?i pragurile ?i capacitatea bateriei
{
chargeLevel = 0.0;
}
else if (currentReading >= CV_current)
{
chargeLevel = 100.0;
}
else
{
chargeLevel = ((currentReading - 0.1 * batt_cap / 1000.0) / (CV_current - 0.1 * batt_cap / 1000.0)) * 100.0;
}

// Actualiza?i controalele pentru tensiune, curent ?i nivelul de înc?rcare
SetCtrlVal(panelHandle, PANEL_NUMERIC_VOLTAGE, voltageReading);
SetCtrlVal(panelHandle, PANEL_NUMERIC_CURRENT, currentReading);
SetCtrlVal(panelHandle, PANEL_PROGRESS_BAR, chargeLevel);
}

int main(int argc, char *argv[])
{
int serialPort;
if (InitCVIRTE(0, argv, 0) == 0)
return -1;

// Crea?i un panou pentru afi?are
panelHandle = LoadPanel(0, "Proiect.uir", 1); // 1 corespunde înc?rc?rii unui dialog

// Configura?i portul serial pentru citirea datelor de la Arduino

int result;

// Deschide?i portul serial
result = OpenComConfig("A0", 9600, 0, 8, 1, 512, 512, &serialPort);

if (result < 0)
{
// A ap?rut o eroare la deschiderea portului serial
// Gestiunea erorilor aici
CloseCom(serialPort); // Închide?i portul serial în caz de eroare
return -1;
}

// Ini?ializa?i citirea datelor seriale
result = InstallComCallback(serialPort, LWRS_RXCHAR, 0, 0, ReadSerialData, 0);
if (result < 0)
{
// A ap?rut o eroare la instalarea handler-ului de citire
// Gestiunea erorilor aici
CloseCom(serialPort); // Închide?i portul serial în caz de eroare
return -1;
}

// Trimite?i un caracter pentru a ini?ia citirea datelor
char characterToSend = 'R';
result = ComWrt(serialPort, &characterToSend, 1);

if (result < 0)
{
// A ap?rut o eroare la trimiterea datelor seriale
// Gestiunea erorilor aici
CloseCom(serialPort); // Închide?i portul serial în caz de eroare
return -1;
}

// Rula?i interfa?a utilizatorului
RunUserInterface();

// Închide?i portul serial când închide?i aplica?ia
CloseCom(serialPort);

// Ini?ializa?i senzorul ?i alte set?ri
// ...

while (1)
{
// Citi?i ?i actualiza?i datele
ReadVoltageCurrent();
int conditionToExit = 0; // Defini?i ?i ini?ializa?i conditionToExit

// Aici pute?i ad?uga logica pentru oprirea sau avertizarea, dac? este necesar

// Verifica?i dac? trebuie s? încheia?i bucla ?i programul
if (conditionToExit) // Exemplu: dac? un anumit buton este ap?sat sau alt criteriu este îndeplinit
break;
}

// ...

// Închide?i panoul
DiscardPanel(panelHandle);

// Elibera?i resursele LabWindows CVI ?i ie?i?i din program
QuitUserInterface(0); // Exit the LabWindows CVI user interface

return 0;
}

I have this erors after runing this code:NON-FATAL RUN-TIME ERROR: "ProiectMain.c", line 95, col 19, thread id 11236: The callback function, PANEL_NUMERIC_VOLTAGE, specified in the UIR file, is not a known function. If you are using an external compiler, you must include the UIR callbacks object or source file in the executable or DLL.
FATAL RUN-TIME ERROR: "ProiectMain.c", line 102, col 14, thread id 11236: The program has caused a 'General Protection' fault at 0x645891C5.

Download All
0 Kudos
Message 4 of 5
(1,565 Views)

I seem to understand that you are not familiar with CVI and you are trying to make this app work without the basic understanding of CVI workflow.

 

These are the most evident errors I can see in your code:

  • You have not included project.h (the include file associated to the .UIR file) in your project but you have incorporated part of its content directly into the source code. This is bad practice since every time you make a modifications to your .UIR file you should update the relevant instructions in the .c file. Including project.h in the source file will guarantee you that all modifications you make in the panels are reflected in the app
  • You are using numeric values to address panel and controls, like in panelHandle = LoadPanel(0, "Proiect.uir", 1); instruction. By including the .h file associated to the .uir file in the code, you can use panels and controls constant names instead, which is handy if you set meaningful names to UI elements ('2' means nothing, while MAINPANEL does). Additionally, if you change something in the UIR file that changes values associated to panels and controls you are likely to get strange errors (like addressing a wrong control in a function, which will result in "the control is not of the type expected by the function" runtime error which is hard to understand if you do not know CVI way of addressing UI objects)
  • You have completely misunderstood the meaning of Constant name and Callback Function while defining controls in the panel. If your panel is called PANEL, you must call controls NUMERIC_VOLTAGE in order to be able to set the control value using PANEL_NUMERIC_VOLTAGE macro in the code. You have set this text in Callback Function field instead and this is why the compiler is complaining that this function does not exist
  • What does 'A0' means in result = OpenComConfig("A0", 9600, 0, 8, 1, 512, 512, &serialPort); call? And why you are passing the address of a variable in OutputQueueSize parameter? The first parameter must be an integer and not a string, while the last one is an integer and not a pointer. Look at function help to understand the parameters to pass to the function

There are other items that are difficult to understand but my impression is that you are trying to develop a CVI app coming from a different language and/or IDE. I strongly suggest that you at least go through the Getting Started with LabWindows/CVI help topic before all and then go and revise your code. A look at some of the examples that come with CVI will additionally clarify how to build up a CVI project.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 5 of 5
(1,558 Views)