Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Simultaneously Reading and Writing problem NIDAQmx.h

Solved!
Go to solution
 

 Hello, I am using the NIDAQmx.h library to make measurements of a pressure sensor to determine the level of a tank(with DAQmxReadAnalogF64()) and write to a pump(with DAQmxWriteAnalogF64()), which gives water to this tank. For this, I have two methods called WritteVoltageLevel() and ReadVoltageLevel (), which work well. My problem is that when the WritteVoltageLevel () method writes a value of 0 (pump off) the reading of the pressure sensor is 1V, and when it changes to 5 (pump on) the reading is approximately 0V (even if the valves are closed, therefore it is not due to water). And the pressure sensors are independent of the pumps, therefore I do not know what this change in the readings is due to. Next I present my code:

 

 

 

#include <stdio.h>
#include "NIDAQmx.h"
#include <stdlib.h>
#include <time.h>

void ReadVoltageLevel()
{
TaskHandle taskHandle = 0;
int32 read;
float64 data[100]; 

DAQmxCreateTask("", &taskHandle);
DAQmxCreateAIVoltageChan(taskHandle, "Dev1/ai4", "", DAQmx_Val_NRSE, 0, 5, DAQmx_Val_Volts, NULL);
DAQmxCfgSampClkTiming(taskHandle, "", 1000, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, 25);
DAQmxStartTask(taskHandle);
DAQmxReadAnalogF64(taskHandle, 100, 10.0, DAQmx_Val_GroupByChannel, data, 100, &read, NULL);
DAQmxStopTask(taskHandle);
DAQmxClearTask(taskHandle);
printf("Tank 1 Level is: %f \n ", data[0]);
}

void WritteVoltageLevel()
{
TaskHandle taskHandle = 0;
float64 dataW[1000];
for(int i=0;i<1000;i++)
{
dataW[i]=0; //pump capacity
}

DAQmxCreateTask("", &taskHandle);
DAQmxCreateAOVoltageChan(taskHandle, "Dev1/ao0", "", -10, 10, DAQmx_Val_Volts , NULL);
DAQmxCfgSampClkTiming(taskHandle, "", 1000, DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, 250);
DAQmxStartTask(taskHandle);
DAQmxWriteAnalogF64(taskHandle, 1000, 0, 10.0, DAQmx_Val_GroupByChannel, dataW, NULL, NULL);
DAQmxStopTask(taskHandle);
DAQmxClearTask(taskHandle);
}


int main()
{
int i=0;

while(i==0){
ReadVoltageLevel();
WritteVoltageLevel();
}
return 0;
}

 

Thank you very much.

0 Kudos
Message 1 of 8
(3,845 Views)

You posted your question in the LabVIEW forum, but you are showing us text-based C code.  I'll move your thread to the Multifunction DAQ board since you are talking about DAQmx, but I have no idea where it would best go.

 

Tell us more which program you are using to write this code.

0 Kudos
Message 2 of 8
(3,811 Views)

Hello leoher96,

I see various things in your code that you shared, I will list them here:

First of all you are opening and closing your tasks in every iteration of you while loop, the best practice is to open and configure you tasks before the while loop, stop and clear your tasks after the while loop and inside the while loop do you writes and reads.

 

//Open tasks
//Configure tasks
while(1) //you could just use a 1 to make the while run indefinitely)
{
//reads and writes
}
//Stop tasks
//clear tasks

 

Next, in your ReadVoltageLevel() function, you read a finite array of measurements (you create an AI task and configure timing with 1 kHz sample rate and 25 samples per channel, then read 100 samples, and only print in console the first sample in the array, which clearly means you are reading a whole more sample than the ones you are using. If you are only interested in one sample, you could just configure a Software timed mode and acquire the sample when you request it. To do this, simply create the task as you have previously done, skip the configure timing function and use the DAQmxReadAnalogScalarF64() function, as this reads a single sample.

 

 

void ReadVoltageLevel() 
{
TaskHandle taskHandle = 0;
int32 read;
float64 data; 

DAQmxCreateTask("", &taskHandle);
DAQmxCreateAIVoltageChan(taskHandle, "Dev1/ai4", "", DAQmx_Val_NRSE, 0, 5, DAQmx_Val_Volts, NULL); 
DAQmxStartTask(taskHandle);
DAQmxReadAnalogScalarF64(taskHandle, 10.0, &data, 0);
DAQmxStopTask(taskHandle);
DAQmxClearTask(taskHandle);
printf("Tank 1 Level is: %f \n ", data);
}

 

The write voltage function has the same issue, you create an array of 1000 elements, all with 0 value, and write this to the analog output channel. When working with finite analog output, you should write the data BEFORE starting the task, that's why there is probably a mismatch between written values and read value. For your application, I would recommend following the single point analog output, to which you follow a similar code for the single point analog input.

 

 

void WritteVoltageLevel() 
{
TaskHandle taskHandle = 0;
float64 dataW;

dataW=0; //pump capacity 


DAQmxCreateTask("", &taskHandle);
DAQmxCreateAOVoltageChan(taskHandle, "Dev1/ao0", "", -10, 10, DAQmx_Val_Volts , NULL);
DAQmxStartTask(taskHandle);
DAQmxWriteAnalogScalarF64(taskHandle, 1, 10.0, dataW, 0);
DAQmxStopTask(taskHandle);
DAQmxClearTask(taskHandle);
}

 

If you are using LabWIndows/CVI, you can use some examples to start developing your code, I recommend the following ones (found in the NI Example Finder in LabWindows/CVI):

Hardware Input and Output > DAQmx > Analog Generation > Voltage > VoltUpdate.prj

Hardware Input and Output > DAQmx > Analog Measurements > Slow Varying Voltage Signals > OneSample.prj

 

I hope this information helps you and your application.

 


Fernando Becerra | Field Applications Engineer | National Instruments | CLA | CTD
0 Kudos
Message 3 of 8
(3,796 Views)
 

Thank you very much for your advice. I have made the changes that  you  recommended, however I still have the problem of the readings. Now I have removed the write function and filled the tanks from NIMAX, to see if the problem has to do with the writings, however I still have the same problem(I checked the example OneSample.prj and I'm being very faithful in the syntax). This is my code:

#include <stdio.h>
#include "NIDAQmx.h"
#include <stdlib.h>
#include <time.h>



void ReadTank(TaskHandle taskHandle){
	
	float64     value2;

	/*********************************************/
	// DAQmx Read Code
	/*********************************************/
	DAQmxReadAnalogScalarF64(taskHandle,10.0,&value2,0);


	printf("El nivel del tanque 1 corresponde a: %f  \n ", value2); 

}

int main(int argc, char **argv)
{
	TaskHandle taskHandle;
	
	/*********************************************/
	// DAQmx Configure Code
	/*********************************************/
	DAQmxCreateTask("",&taskHandle);
	DAQmxCreateAIVoltageChan(taskHandle, "Dev1/ai4", "", DAQmx_Val_Cfg_Default, 0, 5, DAQmx_Val_Volts, NULL);
	
	/*********************************************/
	// DAQmx Start Code
	/*********************************************/
	DAQmxStartTask(taskHandle);
	
	int i=1;
	while(i=1){
	ReadTank(taskHandle);
	}
	
	/*********************************************/
	// DAQmx Stop Code
	/*********************************************/
	DAQmxStopTask(taskHandle);
	DAQmxClearTask(taskHandle);

	
	return 0;


To better explain my error, I have a one-tank and one pump system. I want to read the level of the tank from a pressure sensor. When the pumps are off, the 0% level of the tank reads approximately 1V and 100% corresponds to approximately 3.6V. When I turn on the pumps at their maximum capacity the level of 0% is approximately 0.2V and 100% 4.8V, and if I turn on the pumps in intermediate values ​​of their capacity (for example 50%) the level 0% corresponds to approximately 0.6V and so on. So, I do not know if the problem has to do with the code directly, because a friend is working with the same tank but with LABVIEW and he obtains linear readings (between 1v and 5V) where they correspond respectively to 0% and 100% filling of the tank.

 

Thank you very much.

0 Kudos
Message 4 of 8
(3,777 Views)

Hello Juanma96, 

Your code is fine, both syntaxis and the logic seems to be fine.

Have you validated both signals with MAX Test Panels?


Fernando Becerra | Field Applications Engineer | National Instruments | CLA | CTD
0 Kudos
Message 5 of 8
(3,773 Views)

Yes, but it seems to have the same measurement problem. Below I attach an image of the behavior of the tank level graph against the time, of NIMAX, at the moment in which I go from having the pump turned off to 100%.

Problema Lectura.png

0 Kudos
Message 6 of 8
(3,768 Views)
Solution
Accepted by topic author leoher96

If the problems persists in NI MAX then it is most likely due to a signal problem or connection issue, could you make a diagram or take a picture of your setup?


Fernando Becerra | Field Applications Engineer | National Instruments | CLA | CTD
0 Kudos
Message 7 of 8
(3,766 Views)

Hi, it seems that I have a pin detached from the ground, so it does those crazy things, to fix it without having to touch the hardware, I changed the reading mode to RSE, when creating the analog channel.

 

Thank you very much for your help

0 Kudos
Message 8 of 8
(3,737 Views)