Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Reduce FIFO size in USB DAQ

Hi all,
 
I am now using USB DAQ 6016 to do Analog In measurement in C++ language. I use Continuous Sampling and take a sample rate at 200kS/s, then I have created a thread to read the returned sample continuously. However I found that the DAQ will only send back the samples to computer after the FIFO(4096Sample) is full. That means I need to wait for around 20ms to get the sample.
 
I have tried to use "DAQmxSetAIDataXferReqCond" . It only allows me to use "DAQmx_Val_OnBrdMemNotEmpty", "DAQmx_Val_OnbrdMemFull",  and "DAQmx_Val_OnBrdMemMoreThanHalfFull". I have tried my code with these three parameters and all got the same result that DAQ only send back the samples after FIFO full.
I would like to ask if I can reduce the FIFO size by using C++ functions. Or is there any solution to let me get the sample faster?
 
Thank you!
0 Kudos
Message 1 of 12
(3,176 Views)
Stsoi,

How are you calling your DAQmx read? Are you using a -1 as the number of samples per channel to acquire? This indicates that you wish to read any available samples in the PC buffer. Where are you calling the DAQmxSetAIDataXferReqCond function? Perhaps it would be helpful to post a bit of your code. Please let us know!

Regards,
Ryan Verret
Product Marketing Engineer
Signal Generators
National Instruments
0 Kudos
Message 2 of 12
(3,149 Views)
Dear Ryan,
 
Thank you so much for your kind reply.
 
Listed below are my code for initial the task:
 
///////////////////////////////////////////////////////////////////////
ErrChk( DAQmxCreateTask("",&AI) );
ErrChk( DAQmxCreateAIVoltageChan(AI,"Dev1/ai0:11","",DAQmx_Val_NRSE ,-10.0,10.0,DAQmx_Val_Volts,NULL) );
ErrChk( DAQmxCfgSampClkTiming(AI,"",200000/12,DAQmx_Val_Rising, DAQmx_Val_ContSamps,120000) );
ErrChk( DAQmxSetAIDataXferReqCond(AI,"Dev1/ai0:11",DAQmx_Val_OnBrdMemNotEmpty) );
ErrChk( DAQmxSetReadOverWrite(AI,DAQmx_Val_OverwriteUnreadSamps) );
ErrChk( DAQmxStartTask(AI) );
m_Running=true; // used to control the thread
AfxBeginThread(ReadAIThread, this,THREAD_PRIORITY_HIGHEST);
///////////////////////////////////////////////////////////////////////
 
And in the ReadAIThread :
///////////////////////////////////////////////////////////////////////
while(daqctrl->m_Running)
{
    int status=DAQmxReadAnalogF64(daqctrl->AI,-1,10.0,DAQmx_Val_GroupByScanNumber ,data,120000,&read,NULL);
    if (DAQmxFailed(status))  { /* do some error checking */ }
    else
    {
        if (read>0)  { /* get data from the "data" variable , and record the time need to use in one read cycle */ }
        else { /* call TRACE(".") and Sleep(1) and  to let me know there is no reading in a trial */ }
    }
}
///////////////////////////////////////////////////////////////////////
 
I got the result like this
/////////////////////////////////////////////////////////////////////
tai cycle : 13.31ms read : 342
.
tai cycle : 13.96ms read : 341
.
.
tai cycle : 28.70ms read : 341
/////////////////////////////////////////////////////////////////////
 
I can see some "dot"s in the output window, therefore I believe there is some trial cannot get the sample out.
 
Thanks for your help.
 
BR,
S.Tsoi

Message Edited by Stsoi on 02-25-2006 12:09 AM

0 Kudos
Message 3 of 12
(3,142 Views)
Sorry for re-submit...sorry...

Message Edited by Stsoi on 02-24-2006 11:59 PM

0 Kudos
Message 4 of 12
(3,140 Views)
Sorry for re-submit...sorry...

Message Edited by Stsoi on 02-24-2006 11:58 PM

0 Kudos
Message 5 of 12
(3,140 Views)
stsoi,

Actually, I believe that the behavior you are seeing (time delay) is consistent with the way the DAQmx driver and your USB device interact. I will double-check, but I belive things are working correctly. Acquiring at 200kHz, it would actually take something like 50msec. for the entire buffer to fill up.

Hope this helps,
Ryan Verret
Product Marketing Engineer
Signal Generators
National Instruments
0 Kudos
Message 6 of 12
(3,108 Views)

Dear Ryan,

 

Thanks for the reply again.

 

I would like to ask if you mean that the problem I faced is the limitation of USB DAQ. Is it means USB DAQ only transfer data (from FIFO in DAQ to the buffer in computer side) when the FIFO is full?

 

The 6016 in my site is now used as an electronic test controller. It will output digital and analog signals and get back voltage as result. 12 analog input voltages will be grabbed continuously. Each cycle is required not more than 10ms. Therefore I need to get the samples as fast as possible.

 

Could you give me any advice? Is there any solution to change data transfer condition? Or can we bypass the onboard FIFO to send back samples to computer directly?

 

Thanks for your kind attention.

 

BR

S.Tsoi

0 Kudos
Message 7 of 12
(3,092 Views)
S.Tsoi,

This is, in fact a limitation of the USB DAQ and the driver. Because there is a high latency in USB transfers, even with the data transfer request condition set to DAQmx_Val_OnBrdMemNotEmpty, the driver will enforce a minimum transfer size based on the sample rate. This is necessary to achieve the desired bandwidth. If we used smaller transfers more often, the bus overhead would be too great and transfer errors would occur more often. You may have more luck decreasing your sample rate until you find a "sweet spot" near one of the transition points where the driver changes the transfer size to the next lowest power of two.

I also noticed that you call Sleep(1) after trace, and that you only ever display one or two periods. What happens if you remove the Sleep(1)? It looks as if the application is yielding for more than one millisecond, as I would expect a greater number of milliseconds to elapse during this period. Also, in your output statement which produces:

tai cycle : 13.31ms read : 342

What is the 342?

Hope this helps,
Ryan Verret
Product Marketing Engineer
Signal Generators
National Instruments
0 Kudos
Message 8 of 12
(3,070 Views)

Dear Ryan,

The Sleep(1) is not a accurate one. It pause the thread around 5~10ms in our application. If I remove this function call, the result of same return is as same as before. And The read:342 means DAQReadAnalog command get 342 sample/channel in one cycle.

 

I have tried decrease the sample rate. However the result became worse. We need to wait for more milliseconds to get back the result.

 

Do you think it is possible that getting the updated AI sample in a cycle not more than 10ms by using USB DAQ? Or should I change to other DAQ device? If I want to do a remote (around 2~3m) measurement, which interface type is better for me?

 

Once again, thanks for the information you provided.

 

Best regards,

S.Tsoi

 

 

 

 

0 Kudos
Message 9 of 12
(3,053 Views)
S.Tsoi,

I am a little unclear as to how returning ~350 samples @ 200000kHz takes over 10ms. This should take just under 2ms. At the very least, you should be acquiring a larger number of points each iteration. Do you end up with the appropriate amount of data in the end (200000 samples per channel every second)?

As you decrease the rate, it does take longer as the driver waits for the same number of samples before a transfer, but since it is at a lower rate, this will take longer. As you continue to decrease the wait, the driver will eventually decrease the number of samples it waits for (by a factor of 2) and this should be the "turning point." Whether this will offer better performance, I do not know.

Finally, if it meets your sample rate needs, the USB-6009 does not transfer data in this manner. Instead, by performing a read, you initiate a transfer of the specified amount of data.

Hope this helps,


Ryan Verret
Product Marketing Engineer
Signal Generators
National Instruments
0 Kudos
Message 10 of 12
(3,046 Views)