I'm writing this simple tutorial mostly for myself, as I am tackling generally the same problem third time in my life, and third time I had to (re)invent the exact method how to do that. The problem is very basic: How to synchronize two (or more) outputs in inputs in a NI data acquisition setup, using DAQmx in LabVIEW? By synchronizing I mean e.g. a situation where we are sampling two outputs simultanosly or measuring some data in sync with a control output.
There are multiple applications of such setup. It is really nice in e.g scanning microscopy - one can output the control signal for one axis in a form of e.g. uniform voltage ramp and simultanously measure what there is to be measured (voltage from a photodetector, counts from an APD, Z height from AFM, tunneling current etc). I've set up some systems like that some time ago, and then firstly tackled the problem of I/O syncing under DAQmx.
Of course such measurements can be realized without synchronizing two DAQ tasks - you can output a single sample from the ramp, then measure the input etc. This will also work totally perfect, but this approach is ~an order of magnitude slower than using two synchronized I/Os. So just... no.
Of course such measurements can be realized without synchronizing two DAQ tasks - you can output a single sample from the ramp, then measure the input etc. This will also work totally perfect, but this approach is ~an order of magnitude slower than using two synchronized I/Os. So just... no.
In my current application I'm using an comparator to perform analog to digital conversion - a bit how an SAR ADC works, but with a ramp, not with (duh...) succesive approximation. This is beacause of the architecture of the device beeing tested here (actually it's not an ADC per se it's a kind of robust, programmable light sensor). The circuit looks like so:
What we want to do exactly is to generate a ramping voltage (0 V - 5 V) on the analog output, while monitoring the digital input of the circuit. This kind of measurement can be carried out on most of National Instruments hardware. I'm doing this on a bigger USB DAQ, although earlier did such things on PCI M-series cards. With PCI cards it is even funnier, as one can synchronize several cards using an internal connection (see here), exactly as in an PXI system.
First we generate the voltage ramp from 0 V up to - in our case - 5 V. The ramp is configured to consist of N samples and will be outputed on the analog output as a reference voltage followed by a 0 V, as the N+1 sample in order to put the output to ground level. This is important, as due to the parasitic capacities and the propagation delays in the system, when we apply 0 V to the reference voltage input after it beeing at 5 V potential and read the digital output of U1 it will be probably at high level, as if the 5 V was still applied to the reference. Actually this kind of behavior is part of a broader topic of e.g. race conditions etc. It is crucial to think about this kind of behaviors whenever we interface our DAQ system to a real, physical system.
In order to make such measurement we must set up two DAQmx tasks: one for the analog output (master) and second one for digital input(s) (slave). After we setup the physical channels to both tasks we configure sample clocks for both tasks. First we configure the master sample clock (for the AO) in a regular way (finite samples, N+1 samples etc). Then, we configure the sample clock od the DI task in a similar fashion, except that that we route the source of the sample clock to the analog output clock (or any other clock, that we use for clocking the AO task). The sample clock rate/frequency has to be the same for the DI as for AO, but the sample number doesn't have to be - we can read less or equal number of samples from the slave task that output through the master task.
After setting up the task we can load the ramp to the output task (with auto start set to false) and proceed to run the tasks. Unless we want to change the ramp, we do not have to reload it at every iteration of the data acquisition. First we need to arm the DI - in this we this task starts to listen and wait for the sample clock to start sampling. After the slave task is armed we can start the master task, that will do its job and by generating the AO sample clock also clock the DI sampling. We have to wait untill this tasks finishes and stop it. in this time N samples will be read from the digital inputs. These samples will be later read from the slave task, and the slave task can be stopped. At this point finish the loop and clean the master and slave tasks od re-run the loop again - arm the slave task, run the master task, stop it and read the data from the slave task, just before reading it.
And it's ready! You can use such synchronization method to sync all kind of I/Os - digital, analog, counters (this is a bit more tricky, but still possible) etc. Feel free to ask, if you have any questions. Stay tuned for more LabVIEW adventures 😉.
First we generate the voltage ramp from 0 V up to - in our case - 5 V. The ramp is configured to consist of N samples and will be outputed on the analog output as a reference voltage followed by a 0 V, as the N+1 sample in order to put the output to ground level. This is important, as due to the parasitic capacities and the propagation delays in the system, when we apply 0 V to the reference voltage input after it beeing at 5 V potential and read the digital output of U1 it will be probably at high level, as if the 5 V was still applied to the reference. Actually this kind of behavior is part of a broader topic of e.g. race conditions etc. It is crucial to think about this kind of behaviors whenever we interface our DAQ system to a real, physical system.
In order to make such measurement we must set up two DAQmx tasks: one for the analog output (master) and second one for digital input(s) (slave). After we setup the physical channels to both tasks we configure sample clocks for both tasks. First we configure the master sample clock (for the AO) in a regular way (finite samples, N+1 samples etc). Then, we configure the sample clock od the DI task in a similar fashion, except that that we route the source of the sample clock to the analog output clock (or any other clock, that we use for clocking the AO task). The sample clock rate/frequency has to be the same for the DI as for AO, but the sample number doesn't have to be - we can read less or equal number of samples from the slave task that output through the master task.
After setting up the task we can load the ramp to the output task (with auto start set to false) and proceed to run the tasks. Unless we want to change the ramp, we do not have to reload it at every iteration of the data acquisition. First we need to arm the DI - in this we this task starts to listen and wait for the sample clock to start sampling. After the slave task is armed we can start the master task, that will do its job and by generating the AO sample clock also clock the DI sampling. We have to wait untill this tasks finishes and stop it. in this time N samples will be read from the digital inputs. These samples will be later read from the slave task, and the slave task can be stopped. At this point finish the loop and clean the master and slave tasks od re-run the loop again - arm the slave task, run the master task, stop it and read the data from the slave task, just before reading it.
And it's ready! You can use such synchronization method to sync all kind of I/Os - digital, analog, counters (this is a bit more tricky, but still possible) etc. Feel free to ask, if you have any questions. Stay tuned for more LabVIEW adventures 😉.
Brak komentarzy:
Prześlij komentarz