LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

DAQmx: (nearly) Synchronous Continuous Acquisition / How to trigger board buffer transfer?

Solved!
Go to solution

Hi 🙂 🙂 🙂

 

We have a NI-USB 6289 acquisition card. I would like to continuously acquire an analog input in a "nearly" synchronous way. With "nearly" synchronous way, I mean that, when a DAQmx Read is executed (no matter when), I would like to be able to retrieve all the data present on the PC buffer AND all the data present on the onboard buffer of the card at the time of the read command.

 

In order to make a test of the behavior of the DAQmx Read, I have used the following DAQmx vi's (for a true continuous acquisition I would need a loop structure, but this is just a theoretical experiment):

 

DAQmx Create task

 

DAQmx Create Channel (polymorphic instance AI Voltage)

 

DAQmx Timing (polymorphic instance Sample Clock, Sample Mode set to Continuous Samples, Rate set to 1000)

 

DAQmx Start Trigger (polymorphic instance Start/None)  

 

DAQmx Start Task 

 

here the program waits for n (variable) seconds, and then 

 

DAQmx Read (polymorphic instance Analog Wfm/1Chan N Samp, Number of Samples per Channel set to -1).

 

The FIFO board buffer seems to be 8192 samples big. 

 

If the waiting time between the DAQmx Start and the DAQmx Read is less the roughly 8.2 seconds, the DAQmx Read doesn't retrieve anything, if it is more than 8.2 seconds, the DAQmx Read retrieves 8192 samples. I was expecting this behavior: the board buffer fills up and it triggers the transfer of all the data to the PC buffer, and as the DAQmx Read reads the PC buffer, it can only retrieve data after the transfer has taken place. 

 

What should I do in order to force the transfer of data from the board buffer (even if not full) to the PC buffer at the time of the DAQmx Read while the timing is in CONTINUOUS mode? I would like to be able to retrieve all the data from the PC buffer and the board buffer in order to have all the most recent data and without having to set up a finite samples acquisition and a software circular buffer. 

 

I have tried to use the DAQmx Channel Property Node Analog Input/General Properties/Advanced/Data Transfer and Memory/Data Transfer Mechanism and set it to Programmed I/O but it doesn't work or the DAQmx Channel Property Node Analog Input/General Properties/Advanced/Data Transfer and Memory/Data Request Condition and set it to Onboard Memory Custom Threshold but I couldn't have access to the Custom Threshold Property (it is not there!). 

 

I'm sure that there is an easy way of doing that but I haven't figured that out yet... 

 

Thank you!!! LucaQ

0 Kudos
Message 1 of 11
(6,175 Views)

Hi LucaQ,

 

Thanks for posting!  Instead of using "Custom Threshold" for the AI.DataXferReqCond, have you tried setting this property to "Onboard Memory not Empty"?  If this doesn't resolve the issue, could you please post your code or a screenshot if possible so I can see exactly how you have your task configured?

 

-John

John Passiak
0 Kudos
Message 2 of 11
(6,148 Views)

Dear John 🙂 🙂 🙂

 

Thanks for your reply! I have tried what you suggested but it doesn't seem to solve the problem. I have attached a subVi which should show the issue. After the time delay of 2 seconds and just before the onset of the for loop, the card should have already acquired 2000 samples. But at the first execution of the for loop, no data are retrieved. At the second execution, 250 milliseconds later, 2000 samples are read. At the third execution, again 250 milliseconds later, 250 samples are read. The fourth, fifth and so on executions behave as the third execution.

 

I have the impression that the DAQmx Read reads all the data in the PC buffer and only afterwards, it triggers the transfer of all data present in the onboard card buffer to the PC buffer. It seems that the latest acquired data, which reside on the onboard buffer, cannot be accessed at the time of the DAQmx Read but only at the time of the subsequent DAQmx Read. This behaviour is not "visible" while data are continuously coming in but I think that this time shift of 1 loop is nevertheless always present.

 

Is there a way to force the transfer of the onboard buffer before the DAQmx Read queries the PC buffer?

 

Thank you, LucaQ

0 Kudos
Message 3 of 11
(6,120 Views)

Hi LucaQ,

 

The data transfer from your hardware to the memory buffer takes place independent of your LabVIEW code--since you have a USB device the transfer is driven by interrupts.  If you insert the following property node (mentioned in my last post) into your code, do you receive the same behavior?

 

 

Property Node
 

 

 

I would imagine that modifying this property node should give you at least some different results since you can use it to specify when the device sends the interrupt to your PC.  If you post this into your code, could you send me a screenshot of the amount of samples you are reading per loop iteration?  See the following image for an example of how you could do this:

 

 

 

 

 

If this doesn't work let me know and I can continue to take a look into the issue.  You may want to try running the code on a different PC if possible to see if the problem is local to your computer.  Are you using USB 2.0?  Hope everything is going well, have a great evening!

 

-John 

Message Edited by John P on 02-16-2009 08:33 PM
John Passiak
Download All
0 Kudos
Message 4 of 11
(6,091 Views)

Dear John 🙂 🙂 🙂

 

Thank you so much for helping me!!! That's really cool. But I hope I'm not wasting too much of your time.

 

I tried to change the Memory Transfer property to Onboard Memory not Empty, as you suggested, but nothing happened. I have attached a screenshot of the front panel of the modified subVI (also attached). I have also recorded a timestamp just after the DAQmx Start and before the 2 seconds delay. Loop 0 retrieves an empty waveform, Loop 1 gets 2002 samples, Loop 2 and so on 251 samples. Checking the timestamps demonstrates that Loop 1 (which occurs 250 ms AFTER the end of the 2 seconds time delay) gets all the data acquired from the DAQmx Start until the onset of Loop 0, but not the 250 ms of data acquired from the start of Loop 0 and the start of Loop 1 (data which are already in the card buffer but not yet on the PC buffer). These most recent data are only acquired always one DAQmx Read later (in Loop 2 and so on).

 

I'm starting to fear that there is no way around the inner workings of the DMA of the card. I will try to use a PCI bus acquisition card to see if the issue persists or if the issue is linked to the USB bus. I tried to change PC and I have checked that the USB port is USB2.0. I also tried to put a DAQmx Read just after the DAQmx Start and before the 2 seconds delay. This has the effect of having Loop 0 retrieving 2 or 3 ms of data instead of nothing, Loop 1 and so on staying the same. This shows again that the DAQmx Read triggers the transfer of data from the card buffer ONLY AFTER having read the PC buffer and not before... This precludes access to the most recent data in continuous mode.

 

I have used other properties (like the Programmed I/O) but without success (the subVI crashes or the setting is said to be not available). I have tinkered with the idea of using Finite Acquisition but that cannot replace a Continuous Acquisition.

 

Thank you heaps!!! Have a wonderful and bright day!!!

 

LucaQ 

0 Kudos
Message 5 of 11
(6,071 Views)

Hi LucaQ,

 

Thanks for the update!  I have tested your code on both USB and PCI DAQ cards--it should work as you would expect on the PCI version which uses DMA transfers.

 

USB devices do not use DMA transfers, but rather a protocol unique to USB.  Keep in mind that we are not losing data, but it is just taking longer to get from your board to your PC buffer.  What is your application that requires more immediate access to the data on your device?  For the fastest transfer of data from your device to your PC buffer, you should use a PCI board.  DAQmx Read will read data from your PC buffer, not the device buffer.

 

I'll post back with more information about why we are experiencing this behavior as soon as I have time to figure out what exactly is going on--I am experiencing very similar results with my USB DAQ device as well.  I will also let you know if I find any workaround to speed up the rate that data is transferred from your DAQ card to your PC buffer.  Any information about your specific application would also help us to understand the reason you need more immediate access to the on-board data buffer.

 

-John 

John Passiak
0 Kudos
Message 6 of 11
(6,056 Views)

Hi dear John!!! Smiley Happy Smiley Happy Smiley Happy

 

Thank you heaps for following up on this issue! I'm very thankful for all the time you have spent on it. As I said, I'm starting to fear that there is no way around the way the USB works and that we are both striving for probably an impossible task, even if it seems odd that we cannot find a way of issuing the interrupt command to trigger a bulk transfer of data before reading the PC buffer.  

 

Yes, I agree that there is no loss of data but just a time delay in gathering the latest samples acquired by the card. But this is less than satisfactory when some external devices or mechanisms have to be controlled using an analog output (ie. a driving voltage proportional to some control variable) and monitored using an analog input (ie. a voltage proportional to some process variable). Outputting a voltage, we want to control the displacement of an hydraulic ram. At the same time we want to monitor two sensors embedded into the hydraulic ram, one measuring the displacement of the ram and one measuring the load applied by the ram to some specimen. While the ram is moving in a predetermined fashion (ie. a sinusoidal movement), the specimen could suddenly break. A breakage can be detected using the information on the load: suddenly the load measured by the load cell on the ram plummets. After breakage some actions have to occur in order to stop the ram. Time is important in that case, even if a small time delay wouldn't be catastrophic in our application. We had a PCI card and we bought a new one with more channels. As it seemed more practical, we opted for a USB model.

 

On a more fundamental level, I prefer to know the limit of the equipment and have an understanding of its way of operating. I also think that, even if there must be very good reasons behind the way things are, the behavior of the USB protocol to transfer data is a bit weird.

 

I have attached a subVI which demonstrated the de-synchronization between analog output and analog input caused by the delay in getting the latest data. I hope the subVi and the screenshot of the front panel are self explanatory.

 

Have a wonderful morning, day or evening!!!

 

Thank you 1000 times!!!

 

LucaQ   

 

 

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

If you need that precise of timing and control of something as serious as a hydraulic ram, there is no way I would trust it to Windows or a USB daq card.

 

You should be looking as a PXI computer running a realtime operating system with a PXI Daq card.

Message 8 of 11
(6,023 Views)
Solution
Accepted by topic author LucaQ

I am inclined to agree with Ravens Fan.  However, assuming you absolutely must use the USB DAQ for your application, a better way to set up your code would be as follows:

 

 

 

 

Instead of using software timing, actually specify the number of samples that you wish to acquire from the buffer per read.  So if reading at 1000 Hz, you can read 2 k samples outside the loop (for a 2 second delay) and 250 samples inside the loop (for a 250 ms delay).

 

The issue is that when you specify -1 for your number of samples to read, you are essentially stating that you don't care how many samples are acquired per read.  Since USB data is transferred in packets, DAQmx tries to maximize throughput by only requesting data from the USB device when necessary (the exact method is beyond me, but it will be based off of your loop rate).  If you actually give the driver a number of samples to acquire, it will send the request for data as soon as that amount has been acquired in the on board buffer.  You don't need a delay function in your loop since the DAQmx read limits the loop rate based off of the number of samples.

 

Note that this is not an issue on PCI devices since data is not transferred in packets--the DMA transfer will occur constantly in the background while your program is running.  I hope this clarifies everything, but we are still left with the question of whether or not this will be sufficient for your application.  As Ravens Fan suggested, a Real-Time OS (without using USB, which is non-deterministic) would be the ideal way to go.

 

-John 

Message Edited by John P on 02-18-2009 05:50 PM
John Passiak
Message 9 of 11
(6,012 Views)

Dear John!!! Smiley HappySmiley SurprisedSmiley Very HappySmiley Wink

 

Yuppie!!! Problem solved!!! You have had the genial insight: all the issues were caused by setting the "number of samples per channel" in the DAQmx Read to -1 and doing a software timing.

 

I have set the "number of samples per channel" to 250 and got rid of the 250ms time delay inside the loop. I also got rid of the arbitrary 2 seconds delay before the for loop (which was there just to better highlight the problem). The subVI now works like magic!!! Every loop promptly brings in all the latest data. I have even put a time delay of 100 ms before the loop, just to see what happened. Well, nothing!!! During the first loop, the card had already acquired roughly 100 samples when it receives the command to send 250 samples back, so it had only to wait for another 150 ms to reach the quota of 250 and to send through the data ready to be read to the PC buffer.

 

I agree with Raven Fans and you that hydraulic rams are dangerous things. A self contained programmable control box (with all the safety features) is usually used to drive the ram, without having to use any external PC or software. That is what routinely drives the ram. But in a few cases, it is useful to be able to send an external signal (controlled by a PC and an acquisition card) to the control box, which in turns reacts driving the ram, in order to execute test regimes that wouldn't be programmable just using the control box. In these cases, a few ms of latency or delay due to the non deterministic behavior of Windows or USB are not too important. For example, if a sinusoidal displacement at a frequency of 2 or 3 Hertz is delayed of 2 or 3 ms, that is not a big problem. On the contrary, I agree that these considerations (operative system and acquisition card) would be of the uttermost importance if a software had to be written to do the closed loop control of the ram. In our case, the external signal driven by PC is just telling the ram "move x mm", instead of having to dial on the screen of the control box "move x mm". By driving the external signal, we can build test regimes that we cannot program just using the control box. So what we do isn't too much affected by random delays at the millisecond level.

 

Thank you heaps again for the very elegant and witty solution!!! And for all the time you have spent looking for a solution!!! That has been deeply appreciated.

 

LucaQ  

0 Kudos
Message 10 of 11
(5,998 Views)