11-23-2020 04:25 PM
I really just need some help to know where to start. This is my first time using cDAQ hardware.
My application requires 4 counter pulse outputs. Lets call them W, X, Y, Z. These will map to the 9401 W=PFI3, X=PFI7, Y=PFI1, Z=PFI5 CTR OUT pins.
These outputs will serve as triggers for 4 independent light sources. The sources require precision sync. They will have a period of 100ms. The pulses that trigger the source must be 50ns wide for the test case.
I create 4 DAQmx vchans, Led_W, Led_X, Led_Y, and Led_Z.
I create 4 Tasks, T_Led_W, T_Led_X, T_Led_Y, and T_Led_Z.
I want the application to be able to produce a pulse train on any one or 2 of the trigger lines.
For one line it is easy, just configure T_Led_W, and let it go.
The Problem is that I need to generate pulses synchronized to the nanosecond on 2 triggers at the same time, for example, W and X.
I cant use Channel Expansion, because when I do that, the two tasks start a few microseconds apart.
I only have 4 counters on this chassis, so I cant use another counter to start the tasks on an edge.
I might be able to do something with Time based triggering, that actually worked. I was able to create a task with outputs W and X, and setup a time trigger, and I can get W and X to output 50ns wide pulses every 100ms syncd exactly.
This kind of stuff might work for me, but really what i want to do is produce the following output where every letter in the sequence below happens at an exact 100ms time, producing a 50ns wide pulse:
W, W, W, W, W, W, W, WX, WX, WX, WX, X, X, X, X, XY, XY, XY, XY...
Without the availability of of a 5th counter to keep track of the 100ms tick, I don't see how time triggering will help.
Is this possible with the hardware I have to work with?
11-24-2020 09:53 AM
I've never used a Time-based start trigger and am frankly surprised that you got sub-microsec precision from it. With my lack of knowledge and experience, I remain inclined to trust a hardware signal-based start trigger more.
So, all you have to do is generate a trigger pulse with a DO task. Choose a DO line that also maps to an otherwise unused PFI line. Then configure all the counters to trigger off that PFI line.
After that, the "initial delay" property will let you delay some counter outputs relative to others. If the pattern you listed doesn't repeat, all the pulse trains can be set for Finite Sampling.
If the pattern *does* repeat, a different approach is needed. All the pulse trains would need to be set for Continuous Sampling. Each would configure itself for Pause Triggering using a distinct PFI/DO line as its Pause Trigger. Then you'd need to create a continuous DO task that toggled those 4 DO lines with the right timing to pause and unpause the respective pulsetrains according to the pattern you want.
In this scenario, you probably just set the same initial delay for all pulse trains, letting your controlled pause triggers take care of when they're on and off.
-Kevin P
11-24-2020 04:51 PM
Thanks for the answer!
I tried your suggestion: "So, all you have to do is generate a trigger pulse with a DO task. Choose a DO line that also maps to an otherwise unused PFI line. Then configure all the counters to trigger off that PFI line."
It does not work, as the start task vi errors with "Specified route cannot be satisfied because the hardware does not support it.
The Trigger DAQmx vi wants a hardware pin (/SS_RLY1/PFI0) as the trigger source, and I am trying to set the bit on my NI 9482 SolidState Relay card with a DO task on that same DO
So, for the examples I added, Dig_in_trig does NOT work, and HelloWorld.vi which is time based does. I am still looking for a better idea.
11-24-2020 07:03 PM
I tried configuring a simulated cDAQ config like yours. Based on a little tinkering around, it *appeared* that PFI terminals 0-7 must get configured for either input or output in 4-bit nybbles. So if any of PFI 0-3 need to act as inputs, they all will. If any need to act as outputs, they all will. Same thing for the PFI 4-7 group.
MAX also shows the DIO / PFI equivalency when you select the 9401 module, right-click and show pinouts. PFI 0-7 map to digital "port0/line0-7".
So if you start with a shipping example for counter pulse output, you can see how to forcibly direct the output signal to a chosen PFI pin destination. Your 4 counter outputs should all be directed to the same half-port. I'd recommend routing counters 0-3 to output pins PFI 0-3 respectively just for simplicity.
That frees up PFI 4-7 to act as an inputs. So you can configure one to be the counters' common triggering signal that you then control via a DO task configured for port0/line4 (or 5,6,7).
On the other front, how exactly did you confirm the sub-microsec precision of the time-based trigger? Did you confirm it for multiple simultaneous counter outputs set to trigger off the same timestamp? How?
It seems too good to be true b/c if it DOES work that perfectly, there ought to be an awful lot of people advocating the method. But I haven't seen that. Which makes me suspect that it doesn't work quite so perfectly after all. But maybe you can teach me something here. After all, if it does work, there's no need to worry about the signal-based trigger I've been trying to advocate.
-Kevin P
11-25-2020 10:52 AM
Thank you very much for your post! I will try to do some work with changing the counter output pins. I may be able to do something like this:
Use one counter (ctr0)for the 100ms heartbeat, direct that output to an unused PFI pin, say PFI5-22
Configure another counter (ctr1) and ship it to PFI3-19 (connected to trig W) and config ns scale pulse width
Configure another counter (ctr2) and ship it to PFI7-25 (connected to trig X) and config ns scale pulse width
Trigger W and X off of PFI5
And just keep doing the redirection and enabling / disabling of the tasks that actually output to the hardware triggers to get it done.
The actual full sequence for the test would be:
W, W, W, W, W, W, W, WX, WX, WX, WX, X, X, X, X, XY, XY, XY, XY, Y, Y, Y, Y, YZ, YZ, YZ, YZ, Z, Z, Z, Z
The bold outputs are where I would have an analog input task measure the state of my DUT. That is gonna be fun to write, but if I can do all that output redirection and keep the timekeeper task running, it should work.
To answer your question on how well the Time based triggering works, I can show you. I have all the hardware and a scope. Here are some screenshots:
40 ns time base, W and X counter outputs from the "helloworld" vi. Counter pulse width is set to 50ns.
Here you can see that I am indeed getting 2 pulses every 100ms on the dot.
my scope only does to 4ns/div, but we can see that the 2 pulses are lined up within 2.4ns or so. Good enough for my application, i can probably tolerate about 10 times that degree of sync and not violate my spec.
11-25-2020 11:45 AM
Wow, that's really impressive!
<time passes for some online research>. Ah hah! Now I get it! The 9189 chassis is one of the special breed that supports Time-Sensitive Networking (TSN) ! Few devices do and I haven't used any, so it didn't occur to me to check before.
Anyway, no doubt now that you *CAN* count on time-based triggering after all, so never mind all the stuff I was saying about signal-based triggering.
I'm not sure how you plan to redirect 2 output signals to 4 possible destinations while properly coordinating the timing of that redirection. Maybe you've got a straightforward method. From here, I'd think the pause-triggering idea with a hw-timed DO task would also be a pretty good option.
As to the AI part, I'm supposing you essentially want to trigger a multi-sample acquisition at each of the bolded points in the pattern? I think what I'd try is to configure a retriggerable finite AI task (assuming you have hw to support that) that triggers at *every* 100 msec pulse point. And then I'd just throw away the captures I wasn't interested in.
The trick I think is how to generate a triggering signal at each of those 100 msec points now that all the PFI / DO lines have been used up.
On a desktop device, I think I could make a change detection based DI task that observes the lines used for the counter pulse trains. That didn't seem possible with the 9401 though. Output and Input behaviors seemed exclusive.
But on a device that supports such observation, the AI task would retrigger off the DI task's internal signal named the "change detection event." And you would pre-know the sequence of pulse patterns to know which captures to save and which to throw out.
I suppose a 2nd 9401 module might enable that approach. If nothing else, the counter outputs could be physically wired to the 2nd module. I'm not sure you could make it work via the internal signal routing I usually prefer.
And after all that, the pause-triggering approach isn't quite so straightforward after all. What's your other alternative?
-Kevin P
12-01-2020 03:42 PM
Thanks for all of your help Kevin!
I was trying to get some redirection going, but as far as i can see, the cDAQ setup does not allow for any rerouting or signal exporting at all. I guess that is the downside of not having a bus structure in a cDAQ?
So it seems that I may never get this thing to do exactly what I want. At least without diving into way more technology than I need to get my test problem.
The original test sequence that I listed was all hardware timed perfectly. The commands were output all exactly on the 100ms edges of one counter used as a clock, and that counter was also used to sync analog input read tasks that happen in between the command outputs.
Tomorrow we will have a design meeting, and I am going to pitch an alternate methodology that does not require the stated levels of syncing.
12-02-2020 06:35 AM
Understood. It's one of those engineering life lessons -- not every interesting technical problem is worth solving.
Good luck with a suitable workaround!
-Kevin P
03-16-2023 08:10 AM
I've spent some time figuring out a solution to a very similar problem and I wanted to post my solution here in case it may help someone else. My goal was to output two continuous "CO Pulse Freq" outputs, one at 1 kHz and the other at 4 kHz. I needed them both to start at the exact same time so that the rising edge of the 1 kHz pulse corresponded with the rising edge of a 4 kHz pulse and then 3 more pulses from the 4 kHz signal would occur before the next 1 kHz pulse and the cycle would continue from there.
TL;DR: just physically wire the line7 output pin to line3 and using PFI3 as the start trigger. Then make a DO task that toggles line7 high then low. Make sure both counter tasks are started and waiting on the start trigger before toggling the line7 pin. That works perfectly although it does sacrifice a potential output signal. For some more context see below.
NI has a few examples on their website for using a dummy analog input and the freqout methods for serving as an internal start trigger. The issue was that I had other analog inputs and counter outputs in use on this DAQ that meant the freqout and analog inputs couldn't be held hostage by a dummy task just for triggering. I tried to use the method Kevin described by having my two pulses use counter 0 and 1 on the 9401 with output pins set to PFI0 and PFI1, respectively. Then I made a digital output task on line7 and configured the start trigger to PFI7 for both counter tasks. The issue is that it seems either the 9401 or the cDAQ chassis itself (not sure which one) doesn't support doing this. I always got errors that either the PFI7 was already configured as an output and couldn't be used as an input or that the line7 was already configured as an output and couldn't be used as an input. Some of the NI examples clearly show reading the value of a DO pin as a start trigger, so it must work in some cases, just not on the 9401. After some more troubleshooting I ended up just physically wiring the line7 output pin to line3 and using PFI3 as the start trigger. That works perfectly although it does sacrifice a potential output signal.