Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Problems understanding DAQmxReadAnalogF64

I have big problems to understand how excatly the DAQmxReadAnalogF64 function works so any help on the following would be more than welcome.
 
I create a task and I set up my analog channel for a continuous data acquisition at 1kHz as below:
 
DAQmxCreateAIVoltageChan(taskHandle,"Dev1/ai1","",DAQmx_Val_Cfg_Default,-5,5,DAQmx_Val_Volts,NULL);

DAQmxCfgSampClkTiming(taskHandle,"",1000,DAQmx_Val_Rising,DAQmx_Val_ContSamps,5000);

So if I get the documentation right, as I am entering the parameter DAQmx_Val_ContSamps in the DAQmxCfgSampClkTiming function the number 5000 will determine the size of my buffer for the acquisition.
 
So that being done I start the task.
 
Every 1sec I call the DAQmxReadAnalogF64 function which is set up as bellow:
 
DAQmxReadAnalogF64(taskHandle,-1,10.0,DAQmx_Val_GroupByScanNumber,data,5000,&read,NULL);
 
Which means from what I understand reading the documentation that I will read in my data array as many samples as currently avalaible in the buffer as I set up the numSampsPerChan parameter to -1.
 
So what I expect is that:
After 1sec, 1000 samples avaible, the data array will contain 1000 samples
After 2sec, 2000 samples avaible, the data array will contain 2000 samples
After 3sec, 3000 samples avaible, the data array will contain 3000 samples
After 4sec, 4000 samples avaible, the data array will contain 4000 samples
After 5sec, 5000 samples avaible, the data array will contain 5000 samples
After 6sec, 5000 samples avaible still as the bufferzise is reached, the data array will contain 5000 samples
etc
 
But I don't see that happening, all I have is 1000 samples (checked both ways by looking at the data array and the read parameter) as if the buffer size was determined by the delay between two DAQmxReadAnalogF64 function calls.
 
 
So if someone could explain me what is exactly happening. Am I mistaken in the way I understand the whole thing?
 
Thank you,
 
Antoine
 
 
0 Kudos
Message 1 of 11
(7,080 Views)

Hi,

You can found in your computer a documentation for all C function, you can found it on this directory : C:\Program Files\National Instruments\NI-DAQ\docs\cdaqmx.chm

On DAQmxReadAnalogF64, you need put the array size for your data :

int32 DAQmxReadAnalogF64 (TaskHandle taskHandle, int32 numSampsPerChan, float64 timeout, bool32 fillMode, float64 readArray[], uInt32 arraySizeInSamps, int32 *sampsPerChanRead, bool32 *reserved);

arraySizeInSamps uInt32 The size of the array, in samples, into which samples are read.

On your program, you have choose to put a array with 5000 samples (no more), have you try to increase this parameter ?

Regards,

Christophe S.
Account Manager East of France І Certified LabVIEW Associate Developer І National Instruments France

0 Kudos
Message 2 of 11
(7,036 Views)
Thank you for your answer but this does not help me to understand how it works and as said in my first message I have read the documentation though.
 
You are telling me to try and increase the size of the array from where the data is read but the thing is, if you read my first message, that data array is already not filled completely.
I am only able to gather 1000 samples every 1 sec at 1kHz.
 
This is like if the buffer which the documentation talks about was reseted after each DAQmxReadAnalogF64 function call instead of being reseted only when you call the function to stop the acquisition task.
 
 
Antoine
0 Kudos
Message 3 of 11
(7,019 Views)

I have made my program to output the time when the DAQmxReadAnalogF64 function, ie the Read function, is called and how many samples are read on each call, here are the results:

Start of the acquisition

Calling Read function, time elapsed since acquistion started: 109ms

Read function called, number of sample read on this call: 0

Calling Read function, time elapsed since last call: 1000ms

Read function called, number of sample read on this call: 96

Calling Read function, time elapsed since last call: 1000ms

Read function called, number of sample read on this call: 992

Calling Read function, time elapsed since last call: 1000ms

Read function called, number of sample read on this call: 992

Calling Read function, time elapsed since last call: 1000ms

Read function called, number of sample read on this call: 1024

Calling Read function, time elapsed since last call: 1000ms

Read function called, number of sample read on this call: 992

Calling Read function, time elapsed since last call: 1000ms

Read function called, number of sample read on this call: 992

Calling Read function, time elapsed since last call: 1000ms

Read function called, number of sample read on this call: 992

Calling Read function, time elapsed since last call: 1000ms

Read function called, number of sample read on this call: 992

Calling Read function, time elapsed since last call: 1000ms

Read function called, number of sample read on this call: 1024

Calling Read function, time elapsed since last call: 1000ms

Read function called, number of sample read on this call: 992

Calling Read function, time elapsed since last call: 1000ms

Read function called, number of sample read on this call: 992

Calling Read function, time elapsed since last call: 1000ms

Read function called, number of sample read on this call: 1024

Calling Read function, time elapsed since last call: 1000ms

Read function called, number of sample read on this call: 992

End of the acquisition

 

So as you can see, the maximum number of samples  read is 1024, while my buffer size and data array size is 5000. What I would expect is the number of samples read adding up after each call until it reaches the buffer size of 5000 and then remain at 5000 but it is not working like that, instead it is working as if the buffer was totally cleared after a DAQmxReadAnalogF64 function call. The documentation is quite blurry on that point and the more I read the definition of the DAQmxStartTask function the more I think this is weird and that the buffer should only be "updated" (shifiting the data inside it) on a DAQmxReadAnalogF64 call and cleared only when one calls the DAQmxStopTask.

 

Antoine

0 Kudos
Message 4 of 11
(7,014 Views)
Hi Antoine,
Look at the following example  Smiley Very Happy
DAQmxCfgSampClkTiming  allows us to create the buffer size in RAM.
Indeed as it is a continuous acquisition you have a circular buffer filling in continuous from the DAQ device.

In your application you recover the datas drom this buffer...
Specifying the  same parameters as me in  DAQmxReadAnalogF64 you will recover exactly 1000 samples in each iteration.
   DAQmxCreateTask ("", &toto);
   DAQmxCreateAIVoltageChan (toto, "Dev2/ai0", "", DAQmx_Val_Cfg_Default, -5.0, 5.0, DAQmx_Val_Volts, "");
   DAQmxCfgSampClkTiming (toto, "OnboardClock", 1000, DAQmx_Val_Rising, DAQmx_Val_ContSamps, 5000);
   DAQmxStartTask (toto);
     while (flag==1)
   {
   DAQmxReadAnalogF64 (toto, 1000, 10.0, DAQmx_Val_GroupByChannel, titi, 1000, &read, 0);
   ProcessSystemEvents ();
   DebugPrintf ("%d\n", read);
   }
 
Let me know if you have questions...
   
 
Kamal
NIF
0 Kudos
Message 5 of 11
(7,009 Views)

Thanks for your time Kamal but your code is not answering my questions as I don't want to recover exactly 1000 samples per iterations.

My question is as this is a circular buffer as you mentioned how come it is only filling up to 1000 samples while it can contain 5000. I mean, as it is a circular buffer, my expectation would be to this the buffer works like described below:

 

buffer = [0*5000] (buffer of size 5000 filled with zeros)

start acquisition

1st iteration (after 1sec):  buffer = [0*4000 | 1000 samples from the 1st iteration ]

2nd iteration (after 1sec):  buffer = [0*3000 | 1000 samples from the 1st iteration | 1000 samples from the 2nd iteration]

3rd iteration (after 1sec):  buffer = [0*2000 | 1000 samples from the 1st iteration | 1000 samples from the 2nd iteration | 1000 samples from the 3rd iteration]

4th iteration (after 1sec):  buffer = [0*1000 | 1000 samples from the 1st iteration | 1000 samples from the 2nd iteration | 1000 samples from the 3rd iteration | 1000 samples from the 4th iteration]

5th iteration (after 1sec):  buffer = [1000 samples from the 1st iteration | 1000 samples from the 2nd iteration | 1000 samples from the 3rd iteration | 1000 samples from the 4th iteration | 1000 samples from the 5th iteration]

6th iteration (after 1sec):  buffer = [1000 samples from the 2nd iteration | 1000 samples from the 3rd iteration | 1000 samples from the 4th iteration | 1000 samples from the 5th iteration | 1000 samples from the 6th iteration]

7th iteration (after 1sec):  buffer = [1000 samples from the 3rd iteration | 1000 samples from the 4th iteration | 1000 samples from the 5th iteration | 1000 samples from the 6th iteration | 1000 samples from the 7th iteration]

etc...

 

However it seems to actually work like this:

 

buffer = [0*5000] (buffer of size 5000 filled with zeros)

start acquisition

1st iteration (after 1sec):  buffer = [0*4000 | 1000 samples from the 1st iteration ]

2nd iteration (after 1sec):  buffer = [4000*0 | 1000 samples from the 2nd iteration]

3rd iteration (after 1sec):  buffer = [4000*0 | 1000 samples from the 3rd iteration]

4th iteration (after 1sec):  buffer = [4000*0 | 1000 samples from the 4th iteration]

5th iteration (after 1sec):  buffer = [4000*0 | 1000 samples from the 5th iteration]

6th iteration (after 1sec):  buffer = [4000*0 | 1000 samples from the 6th iteration]

7th iteration (after 1sec):  buffer = [4000*0 | 1000 samples from the 7th iteration]

etc...

 

And I don't understand why considering I am entering -1 as parameter for the number of samples to retrieve from the acquisition buffer. I hope it makes more sense to you put this way.

 

Antoine

0 Kudos
Message 6 of 11
(7,004 Views)
Hi
You are doing a confusion between the buffer allocated in RAM and your buffer in your CVI application!!
In the RAM the driver daqmx allocate a circular buffer as the datas are transfered directly inside it by DMA.
Your array data allows us to recover data from this buffer.

You array data don't have the same behavior as your array.

Let me know if you have questions Smiley Very Happy
 
kamal
NI France


 
0 Kudos
Message 7 of 11
(6,999 Views)

Thanlk you. I have a few questions there:

In the DAQmxReadAnalogF64 function when it is written "buffer" it refers to the RAM buffer or to the CVI buffer?

And what do you mean by:

"Your array data allows us to recover data from this buffer.

You array data don't have the same behavior as your array."

 

Shall we continue in French?

 

Antoine

0 Kudos
Message 8 of 11
(6,995 Views)
Bjr
En ram le driver alloue un espace mémoire de 5000 éléments comme spécifié ds la fonction DAQmxCfgSampClkTiming
Comme tu fais de l'acquisition en Continue tu imagines bien que lorsque la carte à remplie ce buffer de 5000 pts les données du début sont écrasées....(Buffer circulaire)

le buffer "buffer" de la fonction DAQmxReadAnalogF64 récupère du buffer circulaire les X points spécifiés.

Kamal
NIF
0 Kudos
Message 9 of 11
(6,983 Views)
Ok merci, donc c'est bien ce que je pensais.
 
Mon probleme c'est que j'entre le parametre -1 pour le nombre de valeurs à récuperer dans le buffer ce qui signifie d'apres la doc que je recupere tout ce qui se trouve dans le buffer, en tout cas c'est comme ca que je le comprends. Donc je devrais recuperer 5000 points (au bout de 5sec au moins biensur) mais je n'en recupere que 1000 à chaque fois (1000 parce que j'appelle la fonction read toutes les 1 sec et que je suis 1kHz) dans mon tableau data.
 
Si le buffer est circulaire, et comme je rentre le parametre -1, mon tableau data que je rentre en parametre de la fonction DAQmxReadAnalogF64 pour copier les valeurs du buffer devrait en fait etre un tableau mirroir du buffer et avoir un comportement circulaire. Or ce n'est pas le cas puisque comme dit plus haut je ne recupere du buffer que les données entre les deux derniers appels de la fonction DAQmxReadAnalogF64 les precedentes n'etant plus accessibles
 
Donc c'est pour ca que je posais la question concernant le vidage du buffer, est ce que le buffer d'acquisiton est vidé apres chaque appel de DAQmxReadAnalogF64?
 
Cela expliquerait le comportement décrit dans un de mes precedents messages, la documentation restant tres ambigue je trouve à ce sujet. Donc si vous pouviez m'éclaircir sur ce point, ca me permettrait d'etre sur que si je fais un "buffer software" pour regler ce probleme je ne ferai pas un doublon de quelquechose qui existe deja mais que je n'utilise pas car je n'accede pas au buffer de la carte de la bonne maniere.
 
 
Antoine
0 Kudos
Message 10 of 11
(6,981 Views)