Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Device Synchronization

I am using 3 devices; an NI 9213 in a NI cDAQ9171 USB single Chassis, BNC 2120, and NI 9205 in a NI cDAQ-9174 USB Chassis. From what I have read I can't find a way to synchronize them (wired or in LabVIEW). Is there a way to synchronize them? Thanks.

0 Kudos
Message 1 of 12
(2,077 Views)

Well the 9213 is considered a "Slow Sampling" device, the 9205 is a scanned device, and the BNC-2120 is a terminal block -- not a device at all.   But I assume the BNC-2120 is probably cabled to a desktop DAQ device, most of which are the "scanned" type.

 

Each cDAQ chassis and the desktop board will have distinct and independent clocks that will *NOT* match exactly.  Perfect hardware-level sync, if achievable at all (I'm using weasel words because I really don't know much about "Slow Sampling" devices) will definitely require physical wires to share appropriate timing signals among the 3 distinct platforms.  And along with the physical wires, you'll probably need to do some fairly involved configuration in your software.

 

But tell us more about your app, and what degree of sync *you* need.  There may be simpler approaches that'll be good enough.

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 2 of 12
(2,028 Views)

Thanks Kevin,

 

Ideally, I would like to send out a trigger from the BNC-2120 terminal block (PCI 6221) to trigger the 9213 and the 9205 to begin reading samples. It would be triggering a camera at the same time. If I didn't have any constraints, I'd like to trigger at 10 hz and have the NI 9213 read at 75 hz and the 9205 read at 10hz and know that sample 1 occurs 'at the same time'.

Right now all of them work but none are synchronized. Worst case scenario is I drop the trigger voltage and read the trigger on 9213 and forget about trying to trigger 9205. I don't know how good I want it to be but I'd like it better than my worst case idea.

 

I have attached a stripped down version of where I'm at right now. On PCI 6221: ao0  is wired to PFI 0 and ctr0 triggers the camera.

0 Kudos
Message 3 of 12
(2,008 Views)

I don't think synchronizing was possible beyond what I had already explained. I found a device that can receive a trigger. So I have simplified.

 

I want to have NI 9213 (plugged into cDAQ 9188) read beginning every time BNC-2120 terminal block (PCI 6221) sends out a trigger. I also want it to read faster; trigger at 10 hz and read at 70 hz. I have my VI attached. I can send the trigger and have NI 9213 read starting from the trigger.

 

The problem is if I don't send a trigger within the the read timeout time the read loop stops and won't restart. I will have large periods of time without a trigger. If I make the timeout infinite then I can't stop the read loop. Do you have a recommendation for stopping the loop while still accomplishing my goal? Thanks!

0 Kudos
Message 4 of 12
(1,955 Views)

I'm sure there is a more eloquent solution but it works to just ignore wait time errors following the read. If there is a better solution I'd love to implement it. Thanks!

0 Kudos
Message 5 of 12
(1,935 Views)

It's fine to ignore a specific error that's *expected* during normal runs, like your timeout error.

 

I spent a minimal amount of time to do minimal in-place mods to your posted code.  Many improvements are possible, but the end goal for all the timing relationships isn't clear to me.  Honestly, I suspect it might not be entirely clear to you either.  Here are just a few comments and questions that come to mind:

 

1. You seem to be using an AO task to generate a 5V pause trigger signal.  While it's likely to work, it'd be better to do this with a DO task.  

 

2. You have a CO task that generates pulses at a rate that's *slightly* slower than what you call your (nominal) AI sample rate.  1% slower to be precise.  Why?

 

3. You seem to be trying to iterate the upper loop at this same slightly slower rate, though I see no code for a second task worth of AI from another chassis.  And if you make such a task, I would think you'd be driving the task from the hardware trigger signal, much like you do for the TC task.  I don't understand the apparent plan to manage the other AI task with software-based loop timing.  I also don't understand why you'd specifically try to run 1% slower than the requested rate.

 

4. You mention wanting a 10 Hz trigger rate and a 75 Hz sample rate of the TC's.  Meanwhile, you're also reading 7 samples per triggering event.  You probably need a little more breathing room in the timing specs to let you stop and restart the AI task after one acquisition and before the next trigger.  That's why I changed the requested # samples to read to 5 instead of 7. 

   A nice alternative is to configure your task to be re-triggerable, but I don't know if your device and/or chassis will support that.

 

5. It seems like your triggered AI task should be Finite rather than Continuous.  You always start, perform 1 read, then stop.   Finite Sampling is a more natural fit.

 

6. You aren't preserving any of your AI data.  Every triggering event will capture a new set which will replace your previous data in the GUI.  It goes no other place (such as a data file) for later inspection or analysis.

 

7. You mention triggering a camera with your trigger signal.  I suspect this means that the camera will take a snapshot just as you trigger your AI data acq tasks to start, so your TC data will represent things going on *after* the snapshot.  Is this what you're expecting?  Is it what you want?

 

8. You'll need a scheme for how you're going to correlate camera snapshots with acquisition data.  Once you start actually *saving* the data, that is.

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 6 of 12
(1,923 Views)

1. You seem to be using an AO task to generate a 5V pause trigger signal.  While it's likely to work, it'd be better to do this with a DO task.  Got it thanks

 

2. You have a CO task that generates pulses at a rate that's *slightly* slower than what you call your (nominal) AI sample rate.  1% slower to be precise.  Why? My actual code does many more things, this allows for the error in timing since the triggering loop doesn't operate at exactly 10hz.

 

3. You seem to be trying to iterate the upper loop at this same slightly slower rate, though I see no code for a second task worth of AI from another chassis.  And if you make such a task, I would think you'd be driving the task from the hardware trigger signal, much like you do for the TC task.  I don't understand the apparent plan to manage the other AI task with software-based loop timing.  I also don't understand why you'd specifically try to run 1% slower than the requested rate. I got rid of the other task to simplify the code for the forum. The hope is that if I can get one triggered read right, I'd be able to figure out the other.

 

4. You mention wanting a 10 Hz trigger rate and a 75 Hz sample rate of the TC's.  Meanwhile, you're also reading 7 samples per triggering event.  You probably need a little more breathing room in the timing specs to let you stop and restart the AI task after one acquisition and before the next trigger.  That's why I changed the requested # samples to read to 5 instead of 7. Thanks, I see the trigger out on an oscilloscope and all the triggers are there but I can't read them all

   A nice alternative is to configure your task to be re-triggerable, but I don't know if your device and/or chassis will support that. Right now the trigger loop is sending all the triggers. At 5 hz trigger, the read loop reads at each trigger. At 10 hz triggering, the read loop reads just over half the triggers even at 2 finite samples 20 hz sample rate. I think from the manual the NI 9188 chassis can exceed the 10 hz so my guess is either stopping/starting each loop or the NI 9213 Module is limiting. I'll start by trying to retrigger. 

 

5. It seems like your triggered AI task should be Finite rather than Continuous.  You always start, perform 1 read, then stop.   Finite Sampling is a more natural fit. I thought it seemed more natural too, through the iterations continuous is where I found success first. Your updated VI with finite works. Good change.

 

6. You aren't preserving any of your AI data.  Every triggering event will capture a new set which will replace your previous data in the GUI.  It goes no other place (such as a data file) for later inspection or analysis. This was for the sake of simplicity of the code, I will be writing data to file.

 

7. You mention triggering a camera with your trigger signal.  I suspect this means that the camera will take a snapshot just as you trigger your AI data acq tasks to start, so your TC data will represent things going on *after* the snapshot.  Is this what you're expecting?  Is it what you want? Yes the idea is to get a camera shot with a measurement at the same time, then some measurements between each image. Both the camera and measurement are triggered on the rising edge.

 

8. You'll need a scheme for how you're going to correlate camera snapshots with acquisition data.  Once you start actually *saving* the data, that is. Thanks. This will be handled automatically through file naming which set of measurements corresponds to image sets.

0 Kudos
Message 7 of 12
(1,897 Views)

Thanks for all the clarifying answers and comments.  The whys are pretty well covered, so we can focus on the how-to's.  I'll pick up numbering from where I left off.

 

9. I'd run the counter pulse train at the actual desired frequency, such as 10 Hz.  Forget about that little 1% fudge factor, there are other (better) ways to handle the issue you were trying to work around.

 

10. As I come to understand your app a bit better, I see no need for your software-generated trigger signal (where you used AO and I recommended DO).  Just use the counter pulse train output signal.  It's better to sync off a single shared signal anyway.

 

11. NI's DAQ devices make a clear distinction between *trigger* signals and *clock* signals.   Your TC task needs to receive a 10 Hz *trigger* signal so it can then capture multiple samples with a sample *clock* rate of ~75 Hz.  Your other AI task should just use the 10 Hz signal directly as its sample clock.  No triggering necessary.

 

12. The best option is if your TC device (& chassis?) support hardware-based retriggering for analog inputs.  Try setting the DAQmx Trigger property "retriggerable?" to True -- you'll get an error if it isn't supported.

 

13. Otherwise, you'll need to support retriggering in software, much as you're already doing.  You have to stop and restart the task after each set of samples.

   Unfortunately, cDAQ systems over USB or Ethernet connections will respond slower to this stop and restart process.  Your call to explicitly commit the task before starting it for the first time is already the best thing you can do to speed up stop & restart.  (Though I'm not sure exactly how much difference it makes in the specific case of cDAQ.  It's fairly dramatic on desktop boards.)

 

14. So now you're set up in a situation where the TC task might be prone to missing some 10 Hz pulse train triggering signals while it's stopping and restarting.  Meanwhile the camera and the other AI task will sample on all of them and not miss any.  So you need to deal with this somehow.

 

15.  Here's my suggestion.  Put the other AI task into the same loop with the TC task.  *After* a successful TC read, read all available samples from the other AI task.  Only keep the very last sample because the earlier ones would correspond to missed triggers for the TC task.

    But that's not all.  This much helps make sure that if and when the TC task misses a trigger, you also ignore the corresponding sample taken by the other AI task.  But you still need to correlate your AI data with occasional misses to your camera data without misses.

 

16.  So you're gonna also make a counter edge-counting task that counts the 10 Hz signals.  After a successful TC read, read the count value.  Use this count value to drive your file naming convention, so that missed triggers result in skipped file numbers.

    Note that this scheme is still not perfect.  It relies on the software being able to query the count value between the end of one TC capture and the moment the next 10 Hz triggering signal happens.

    A better method doesn't come immediately to mind, but maybe I'll think of something later.

 

17.   Note that in this whole scheme, it'll be important that the 10 Hz pulse train is started *last*.  Your camera and the other DAQ tasks should already be started and waiting for the 10 Hz pulse train before you begin generating it.

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
Message 8 of 12
(1,880 Views)

9. I'd run the counter pulse train at the actual desired frequency, such as 10 Hz.  Forget about that little 1% fudge factor, there are other (better) ways to handle the issue you were trying to work around. OK thanks

 

10. As I come to understand your app a bit better, I see no need for your software-generated trigger signal (where you used AO and I recommended DO).  Just use the counter pulse train output signal.  It's better to sync off a single shared signal anyway. Counter pulse train output signal from which device? Sorry I don't understand can you elaborate?

 

11. NI's DAQ devices make a clear distinction between *trigger* signals and *clock* signals.   Your TC task needs to receive a 10 Hz *trigger* signal so it can then capture multiple samples with a sample *clock* rate of ~75 Hz.  Your other AI task should just use the 10 Hz signal directly as its sample clock.  No triggering necessary. Right

 

12. The best option is if your TC device (& chassis?) support hardware-based retriggering for analog inputs.  Try setting the DAQmx Trigger property "retriggerable?" to True -- you'll get an error if it isn't supported. That was an easy way to find out, its not supported. Thanks

 

13. Otherwise, you'll need to support retriggering in software, much as you're already doing.  You have to stop and restart the task after each set of samples.

   Unfortunately, cDAQ systems over USB or Ethernet connections will respond slower to this stop and restart process.  Your call to explicitly commit the task before starting it for the first time is already the best thing you can do to speed up stop & restart.  (Though I'm not sure exactly how much difference it makes in the specific case of cDAQ.  It's fairly dramatic on desktop boards.) 👍

 

14. So now you're set up in a situation where the TC task might be prone to missing some 10 Hz pulse train triggering signals while it's stopping and restarting.  Meanwhile the camera and the other AI task will sample on all of them and not miss any.  So you need to deal with this somehow. What I did is used the same ctr0 to generate two signals from the same PFI. One at 10 Hz and one at 5 Hz. This way the leading edge is at the 'same' time. The camera trigger has to be at 10 Hz. I'll just ask for more sample reads from the read loop. The small time error from missing one sample is something I can live with

 

15.  Here's my suggestion.  Put the other AI task into the same loop with the TC task.  *After* a successful TC read, read all available samples from the other AI task.  Only keep the very last sample because the earlier ones would correspond to missed triggers for the TC task.

    But that's not all.  This much helps make sure that if and when the TC task misses a trigger, you also ignore the corresponding sample taken by the other AI task.  But you still need to correlate your AI data with occasional misses to your camera data without misses. This will be plan B if I need to read on every trigger.

 

16.  So you're gonna also make a counter edge-counting task that counts the 10 Hz signals.  After a successful TC read, read the count value.  Use this count value to drive your file naming convention, so that missed triggers result in skipped file numbers.

    Note that this scheme is still not perfect.  It relies on the software being able to query the count value between the end of one TC capture and the moment the next 10 Hz triggering signal happens.

    A better method doesn't come immediately to mind, but maybe I'll think of something later.

 

17.   Note that in this whole scheme, it'll be important that the 10 Hz pulse train is started *last*.  Your camera and the other DAQ tasks should already be started and waiting for the 10 Hz pulse train before you begin generating it. Right, I found that out. I dropped the loop wait times in my stripped down example to fix that problem

0 Kudos
Message 9 of 12
(1,871 Views)
10. As I come to understand your app a bit better, I see no need for your software-generated trigger signal (where you used AO and I recommended DO).  Just use the counter pulse train output signal.  It's better to sync off a single shared signal anyway. Counter pulse train output signal from which device? Sorry I don't understand can you elaborate?

I'm talking about the pulse train you generate on the PCI-6221 and wire to your camera.  I'm counting on you being able to bring that signal into your cDAQ systems for use as a common & shared timing signal for sync purposes  There may be a place to bring it straight into the chassis or you may need to use a simple digital module to pass it through to the chassis.

 

I remembered that the TC task you posted showed trigger configuration for a PFI pin, so I figured you must have a way to put your 10 Hz counter pulse train signal there.  A closer look shows that it seems to reference a different chassis model (9188) than what you identified in your original post (9174 and 9171).  So now I'm a little confused again.

 

It also seems to me that you probably ought to put both cDAQ modules together in the same multi-module chassis to simplify the sharing of timing signals.

 


14. So now you're set up in a situation where the TC task might be prone to missing some 10 Hz pulse train triggering signals while it's stopping and restarting.  Meanwhile the camera and the other AI task will sample on all of them and not miss any.  So you need to deal with this somehow. What I did is used the same ctr0 to generate two signals from the same PFI. One at 10 Hz and one at 5 Hz. This way the leading edge is at the 'same' time. The camera trigger has to be at 10 Hz. I'll just ask for more sample reads from the read loop. The small time error from missing one sample is something I can live with

This can't be right.  What you stated is impossible.  A single counter channel (ctr0) cannot generate 2 output signals at 2 different frequencies at the same time.  Nor can 2 distinct counter outputs be mapped to the same PFI pin at the same time.

 

Can you re-state this part of the plan in a little more detail?  

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 10 of 12
(1,861 Views)