06-06-2014 05:27 PM
I am trying to build a LabVIEW DAQ system (using a NI USB-6218 BNC and LV 2013) which performs continuous single-channel AI and periodic two-channel AO. My woes are currently with getting the implementation of the AO tasks to work as desired. My implementation scheme is as follows:
A representative example of this implementation is attached. (There are specific reasons why I wish to separate the control of the pacing interval from the pacing waveform output itself.)
According to my review of the LabVIEW KB and examples archive, AO generation should be “retriggered” by stopping and restarting the task (eg, see http://www.ni.com/example/30008/en/). (I know that there is another suggested method for generating retriggerable AO using onboard counters [http://www.ni.com/example/29787/en/], but I don’t have enough counters for this implementation in the context of the larger scope of my actual program.) However, when I run my program, it appears that my AO output task only respects the trigger on the first iteration thru the stop/start loop; on all subsequent iterations, the loop appears to free-run (the DAQmx Start doesn't seem to wait for the next CO trigger).
Can someone please help me identify what I’m doing wrong here?
Thanks,
==Matthew
Solved! Go to Solution.
06-08-2014 05:26 PM - edited 06-08-2014 05:33 PM
Hi Matthew,
When I run you code, I get an AO waveform every 500ms as expected. I suspect your problem is that for each run of the AO task, you output~10 copies of your waveform.
Your AO code is set up for a finite output, and it's using the default "number of samples per channel" of 1000. Since your waveform is 101 points long, DAQmx generates coppies until it gets to 1000 samples. If you do only want to output 101 samples for ever trigger you get, set the DAQmx Timing vi to 101 samples per channel.
When I set that, I get a single high then low cycle every 500ms.
-Luke
06-09-2014 10:16 AM
Hi Luke,
Thanks for pointing out the "number of samples per channel" error. That definitely fixes one issue.
However, there still seem to be a couple of issues remaining:
(1) There is still the behavior of the while loop that doesn't seem right: It still appears to 'free-run' with ~50 ms duration per iteration, instead of (per my expectation, at least) cycling at the same rate as the trigger edges (500 ms, or whatever I put for that value). Isn't the 'DAQmx Wait Until Done' function a blocking function that should wait each iteration until the finite AO pulses are triggered and completed? And thus shouldn't the while loop iterate at that same (slower) interval?
(2) Perhaps related to #1 above, when I watch the AO outputs for a while, it appears that they eventually become "corrupt" --- either they stop triggering, or only part of the pulse gets output (thereby holding the channel at the incorrect voltage), etc. The CO output on Ctr0 remains consistent, so it's not because of the loss of the trigger itself.
Thus, I'm still not convinced that the AO task is properly re-engaging its trigger upon each stop/start iteration of the while loop, or that the 'DAQmx Wait Until Done' function is not waiting as anticipated. Where is the breakdown here? Is it in my logic, my implementation, or somewhere else?
Thanks for any further insights & suggestions you can provide,
==Matthew
06-09-2014 12:32 PM - edited 06-09-2014 12:33 PM
Hi Matthew,
I had been using an X series card, I was getting a nice consistent 500ms loop time. I switched to a USB 6218 and I started seeing loops of ~30ms.
The USB 621x devices are sensitive to timing on the interrupt used for Wait Until Done/Is Task Done. Because we are starting the task again and the hardware hasn't reset that interrupt, Is Task Done is returning immediately.
The easiest workaround is to manually un-reserve the task between stopping and writing using the DAQmx Control Task vi. This will add as much as 30 or 40 ms of extra overhead but as it is now, you are only writing for 10.1 out of 500ms, so an additional 40ms of overhead won't cause missed triggers. Un-reserving the task effectively clears the hardware, resetting that interrupt.
Once I add the unreserve, I get nice consistent 500ms loop times.
-Luke
06-09-2014 01:23 PM
Perfect! That was it! Thanks so much for your assistance & solution.
==Matthew