I have a retriggerable task (AI Voltage, Finite samples) that acquires 50 samples at the maximum sample speed (2 MHz for the USB-6361) whenever it receives a TTL pulse on PFI0. These TTL pulses come in a certain sequence that repeats, like this: ABCDABCDABCD. I would like to synchronize this task so that it begins on a specific TTL pulse, pulse A, which I can specify with a second TTL pulse on PFI1 that lines up with pulse A. Otherwise, the first pulse I get would be random, and I won't know if I have ABCDAB... or BCDABC... etc.
The main issue is that I would like the task to wait for a rising edge on PFI1, but only for the first trigger. After that, PFI1 should be ignored, and the acquisition should occur on rising edges from PFI0.
Is there a way I can do this, without lowering my sample rate from 2 MHz? I was considering making a second "dummy" task that waits for the signal on PRI1 and then stars up the first task via software, but I don't think that's very reliable, since these pulses (A,B,C,D) have spacings of 100-500 microseconds. My other idea was to put the PFI1 signal on an analog input port, but then my sample rate has to drop to 1 MHz, because I'm sampling two channels. Maybe someone knows of a proper way to achieve this.
Thanks for the help!
I think we can make this work by generating the sample clock with a counter. You can configure it to generate a retriggerable finite pulse train that the AI task uses as its sample clock. I'd probably just make the AI task be continuous and split the data into groups of 50 samples after the fact.
Here's the important part. The counter task can *also* be configured for a one-time "Arm Start" trigger. Regular triggers get ignored until the Arm Start trigger (PFI1). That arms the counter for action, after which it can keep retriggering on the regular Start trigger signal (PFI0).
If you have some control over these pulses, it'd be better to line up the PFI1 pulse with pulse D, and configure the "Arm Start" trigger for the *trailing* edge of that pulse. Then it'll get armed and the next *leading* edge it sees will be pulse A.
The Arm Start trigger needs to be configured via DAQmx Trigger property node. Search here and you'll find lots of further info.
I had a few minutes while monitoring some equipment and thought I'd whip up a starting example. Along the way, I realized another method might be a little simpler to deal with.
Instead of getting involved in the whole Arm Start trigger business, you could use a retriggerable finite pulsetrain as your sample clock, but then configure a 1-time trigger for AI from that PFI1 synced pulse. It should all work out pretty much the same way in the end -- the AI task gets triggered just once by that special pulse, after which it will perform sampling as the counter task keeps getting retriggered.
Attached is a basic but (hopefully) working example in LV 2016.
Thank you for your advice! I was able to get it to work using your example. This method fixed the issue with synchronization, but unfortunately it also introduced a new problem. I had been previously using the trigger "start delay" property in order to delay the acquisition trigger (the retriggerable one) with 10ns precision to compensate for signal propagation delays. When I try to do that now, I get "Specified property is not supported by the device or is not applicable to the task." I'm guessing there's a way to do it, but I don't know how to do it using the new method. Here's the VI with the error.
Thanks again for your assistance!
You can do that a different way with the counter pulse train. When setting up the pulse specs, there's an input called 'initial delay' at the bottom of the call to DAQmx Create Virtual Channel. This is used as the time before the very first pulse. All subsequent transitions are based on the freq & duty cycle params wired into the top.
In the case of a re-triggered pulse train, the default behavior is that initial delay is used only for the 1st pulse after the 1st trigger. Fortunately for you, you're using an X-series board which supports an option to use the initial delay parameter for the 1st pulse after *every* trigger. Set the DAQmx Channel property "Counter Output->General Properties->More->EnableInitialDelayOnRetrigger" to True. I think that oughta do the trick.
I have a follow-up question on this topic. I'd like to have, for example, pulses A and B acquire 50 samples each, but have pulses C and D have 100 samples each, yielding a total of 50+50+100+100 = 300 samples per cycle (4 triggers). I can think of 3 potential ways to do this.
Is my thought process on the right track? Is 3 possible, or is that not really an option here? Is there an example I can look at for how to set up 2?
I'm not near any hw to verify, but will try to answer as best I can.
1. I agree you could run into trouble getting "desync'ed" between the external pulse timing and the extreme precision you need to exactly control the # pulses at 2 MHz. I don't think this'll be your best approach.
2. You probably can't really make this work under DAQmx alone. You *could* make 2 counter tasks that each generate finite pulse trains in response to 1/2 the external pulse signals, but you can't make the AI task switch back and forth between them for its sample clock. I guess you could add a simple external logical OR circuit between the 2 counter outputs and the PFI pin the AI task would then use as its sample clock.
It also isn't clear to me how your system would support your need to separate out A&B pulses on one signal and C&D pulses on another. But if you know you can do that somehow, that's good enough, you're the one who needs to understand how, not me.
3. Yeah, not really possible to do under DAQmx.
4. So here's a 4th method which is the one I'd recommend. Just generate 100 counter pulses for each trigger A,B,C,D, and ignore the extra samples you don't particularly want. We've already solved the part where you know that you start your AI after an A pulse. Now you can just ignore the extra 50 samples you get after pulses A & B.
Specifically, each sequence of A,B,C,D will generate 4 pulse trains of 100 pulses each. This will produce 400 AI samples. Read them all, and then only keep the following subsets:
Index 0, Len 50 - samples for A pulse
Index 100, Len 50 - samples for B pulse
Index 200, Len 100 - samples for C pulse
Index 300, Len 100 - samples for D pulse
You'll simply be discarding and ignoring the extra samples at indices 50-99 and 150-199. You won't need to change any of the signal routing involved in the known-working configuration.
4. This is actually what I'm doing right now. The issue is that for some applications of this solution, the A and B triggers need to be within 100 samples (50 microseconds) of each other, so the B trigger is received while the counter channel is still generating samples for A.
1. I'm using a PulseBlaster from Spincore to generate these pulses (2 ns precision!), so I'm not expecting timing to be an issue. If I regularly start and stop the task every so often, that would ensure that a single timing error does not propagate forward indefinitely. Alternatively, I believe that I could identify an "off by one" shift in the acquired data during runtime and restart as needed. If I can't rely on the timing of the pulse being correct, then the data is worthless anyways.
2. This method is out unless I use external hardware to logical OR two channels, correct? I can probably switch to this if 1 is causing me problems.
5. What if I use my pulse generator to generate the sample clocks directly instead of using counter channels? Rather than sending pulses A B C and D, I can have it generate the sample clock for each of these pulses. I'd have to read up on the timing specifications and make sure the generated pulses meet them. I'm not sure if it's a good idea to have the sample clock come from a different source than the timebase though.
It sounds like I'll end up going with 1 for now unless you thing that 5 sounds promising.
Thanks again for your help!
Dunno anything about your "PulseBlaster" device, but I like the sound of option 5 if the timing specs can work out. (Mainly, minimum pulse width and max external sample clock freq.)
In your app, I don't think you'll need to worry about sync with your 6361's internal timebase, because you really won't even be using it any more. If you supply sets of 2 MHz pulses from the PulseBlaster that your AI task uses *directly* as its sample clock, then there's nothing further to sync.
I don't see where "Option 1" would solve the problem of capturing 50 samples for A&B pulses and 100 samples for C&D pulses.