Hello, I am struggling to write a VI that would acquire one analog voltage sample every time an aperiodic TTL trigger is detected.
Trigger events are aperiodic; their rate can change from 0.2 Hz to 1 kHz unpredictably from sample to sample. The experimental setup is complex (hence the aperiodicity), but the important part is that there is a hardware voltage averager that provides two outputs: analog Data Out and digital Busy. When Busy signal goes down, Data Out is valid and must be read within 1 ms. Then the rest of experimental setup may or may not reconfigure itself for the next measurement, and the averager presents the next data point.
I am using NI USB-6009 with Labview 2013. USB-6009 samples up to 48K samples per second; it has a single PFI0 input that can be used as digital trigger input and 8 analog inputs.
A simple-minded solution I had involved setting up an AI Voltage task with PFI0 as source to Start Trigger, performing one read, shutting down the task and repeating everything right away. This sounds very inefficient to me, especially at 1kHz frequencies.
Another idea was to set up continuous AI voltage acquisition, where PFI0 was wired as the source to the Sample Clock. However, this throws an error -89136: Specified route cannot be satisfied because hardware doesn't support it. I can't tell whether I coded something stupid or I am using inadequate hardware.
I am out of ideas, and I am a DAQmx noob, so any help is greatly appreciated.
One method which should work without needing to restart a task would be to continuously sample 2 channels of AI voltage (no trigger). One channel will have your signal. The other channel will have the trigger signal. Then process the data in software. Whenever you find a falling edge on the trigger signal channel, extract the corresponding sample from the data channel. You can then discard all other samples prior to those and start searching for the next trigger.
The sample rate may depend on the minimum duty cycle of the trigger signal. It must be fast enough to capture the minimum width Busy down pulse and the minimum width Busy up pulse. If the device can sample that fast then you can guarantee that you will capture every trigger. For example if the minimum pulse widths are both 500 us (which would give a 1 kHz trigger rate), then sampling at 2 kHz would theoretically get you at least one sample on each up and down level of Busy. If the minimum Busy down width is 100 us, then you would need to sample at > 10 kHz. As a practical matter, I would sample faster to allow for frequency tolerances and drift. If the minimum Busy down width is 100 us, then you would need to sample at > 10 kHz.
Please look at these forum where this matter is addressed:
The important comment says the following:
The behavior you are talking about is using an external sample clock. Nearly all of our other multifunction products are capable of this configuration, and setting this should give you a single sample on the edge of your external TTL signal (can usually be set to rising or falling). The USB 6009 does not support using an external sample clock, so this is the cause of the error you are seeing.
The USB 6009 actually does support using an external digital trigger on PFI0. So, in theory you could re-trigger multiple single sample acquisitions off of this external signal. However, to rearm the 6009 you actually have to stop and restart the task in software*. During this software-defined rearm time you might miss external trigger signals, so this solution is less than ideal.
So, the best solution is going to be to use another board that supports using an external sample clock. If you must use the 6009, the one recommendation I could give would be to explicitly commit the task by calling the DAQmxTaskControl function outside your loop before starting the task.
Here's a few boards that you might look into that allow for external sample clocks for the AI channels:
My favorite of the above options is the X Series, but this is assuming that PCIe is an acceptable form factor. The 6210 would be my recommended USB solution, and if you prefer PCI I would go with the PCI 6220.
*Note: In the external trigger case, all subsystems (AI, AO, DI, DO, Counters) are retriggerable on our new X Series devices without having to restart the task in software. Before X Series was released, the workaround was to use a counter output (which are retriggerable) to generate a sample clock for the AI task to use. Unfortunately, the 6009 does not have the capability to generate a counter output or to use an external clock for AI, so you have no choice but to rearm the acquisition in software if you do not purchase new hardware.
Thank you to those who replied!
Here is my current solution to my own problem, in case someone else is struggling with the same task.
This VI uses NI USB-6009 DAQmx that doesn't have a change detection functionality. (If you are lucky to have change detection, consider this approach instead) The trigger is connected to the PFI0 input counter. The counter is polled at 1kHz,
and every time it changes, AI2 DAQ channel is sampled. The timing is software-controlled, so it's non-
deterministic. There may be a varible delay between a trigger is detected and an analog port is sampled,
but it didn't matter in my application. When running, this polling VI consumes less than 1% of my CPU cycles,
and I don't have a fancy processor. As written, it actually runs slightly faster than 1KHz (closer to 1.2 kHz),
and I am curious why.