I have two signals: Signal A serves as a gate. Signal B is a harmonic TTL signal (e.g. 12 Hz). Both signals are derived from external sources (and are not generated by the counters on the card). I’d like to generate an output pulse on a user specified terminal whenever a rising edge of signal B occurs within the gate window (Signal A high, 1-10 ms). To this end, I am employing a piece of code for pulse counting: https://decibel.ni.com/content/docs/DOC-4516 (please find attached a source code image): Signal B is supplied to CTR SRC 0, which is configured to count edges. CTR1 is configured to output a pulse (the gate window) upon receiving a start trigger signal from an external source. CTR1 OUT is configured to provide the desired gate window, which is supplied to CTR0 GATE. Thus, CTR0 will ignore all rising edges at its input but for those which fall into the gate window. The idea is to set the counter to 4294967295 (32 bit counter) such that it generates a pulse when the counter rolls over to zero (please find attached oscilloscope traces of the relevant signals). This works well, however, I cannot resolve the following issues:
A. Once a rising edge of B has been counted, the counter rolls over and does not generate another output pulse. I tried to use the DAQmx Channel “CounterReset” command as described here: https://decibel.ni.com/content/docs/DOC-26249. However, I do get an error message indicating that the reset does not work with the “Pause Trigger” command used in the code. So this does not seem to be a viable option. Is there another way to reset the counter or use the counting itself to generate a pulse.
B. The output pulse on CTR 0 is not generated when going from 4294967295 to 0, but occurs when the counter goes from 4294967294 to 4294967295. Based on the manual, it should occur for the former case. What could be the reason for this behavior?
C. The output pulse on CTR 0 does not occur concurrently with the rising edge of B within the gate window, but with the following rising edge of B (the edge that it is not supposed to be counted as it is outside the gate window.) What could cause this delay?
Please let me know if you have any suggestions how to troubleshoot items A-C. Additionally, I would welcome any suhhestions reagrding alternative approaches for achieving the desired functionality. I am using Labview 2015, the PCIe-6321 card and the BNC-2110 connector block. Thank you very much for your help.
You've got a very intriguing problem. Seems like a TTL AND circuit could help a lot but barring that, there may be some DAQmx tricks that'll help solve it. Let me first address your specific points:
A. Agreed, this is not directly viable. There's not really a better way to reset the counter. Counting can be used to generate a pulse, but will require a minimum of 2 same-polarity edges per pulse. Even then, the pulse width is not configurable, it's based on the board's internal timebase. I recall that M-series boards set the width at 50 ns, not sure for your X-series.
B. Interesting. That doesn't seem quite right to me either. I've made cascaded 64-bit counts by using the "low bits" rollover pulse to increment the "high bits" counter, and don't recall seeing it happen one count too soon. Not sure I was inspecting closely enough to vouch for that though.
C. I can't fully reconcile your code, your scope pic, and your description. CTR 0 shouldn't be incrementing its count on the rising edge of Sig B due to its pause trigger PFI13 being low at the time. And if its count doesn't increment to "terminal count", I don't know why the output would toggle state. I'm also kinda surprised the output toggles at all when you didn't explicitly configure to do so.
The important thing that isn't surprising is that CTR 0 doesn't (and can't) change its output until receiving a 2nd source edge. There are a number of places that this "minimum of 2" shows up for counter operations, most notably that it's the minimum # of "Ticks" (i.e., source edges) allowed for pulse generation.
I've re-read your post a couple times to absorb it, let me just make sure by restating what I *think* you're up to and you can correct me where wrong.
1. The essential goal seems to be that a rising edge on Signal B should result in an immediate programmable pulse (choice of timing specs and output terminal), but *only* if the rising edge on Signal B occurs "soon enough" (1-10 msec?) after an external trigger edge (PFI0).
2. The CTR 1 gate pulse is being generated only to try to help accomplish the stuff above. It's not inherently necessary, just a means to an end.
3. Question: what do you know about the possible pulse widths and frequencies of the external signals, trigger and Signal B? Particularly, will the external trigger always be >= the 10msec max you have in mind for your CTR 1 gate pulse?
I'm suspecting the best path forward will not be based on incrementing count and toggling a terminal count condition. I suspect it'll be based more on pulse generation. If so, there'll likely need to be a minimal delay from the external trigger until your pulse, something in the order of 0.1 to 0.2 microsec. I don't have a complete solution mapped out in my head, but that's where I'm leaning pending answers to #3 above.
Thank you very much for your comments. Regarding your questions:
(1) Yes, you correctly summarized the essence of what I’d like to accomplish. I think the functionality I am trying to design is similar to a D flip-flop (https://en.wikipedia.org/wiki/Flip-flop_(electronics)#D_flip-flop)
(2) Yes, CTR 1 simply provides some additional control over the gate pulse length and timing. It is not inherently necessary.
(3) The signal I am trying to gate has a nominal frequency of 12 Hz and a 50% duty cycle. My start trigger/gate signal is 9 Hz. I do have a signal delay generator that provides full control over the start trigger pulse width. So I could set the pulse width to any desired value.
A small delay between the trigger and the output pulse is perfectly fine for my application. The precision I am looking for is on the order of a few milliseconds.
I tried to use the DAQmx “two-edge separation measurement” to accomplish the task. While it does measure the time difference between the edges of the two signals, I could not find a way to make use of the generated time data. Thank you for your help.
>> I’d like to generate an output pulse on a user specified terminal whenever a rising edge of signal B occurs within the gate window (Signal A high, 1-10 ms).
If you set start trigger for your "gate" pulse - channel B, set low delay to 20 ns (2 ticks of 100 MHz timebase, mimimum delay), and pause trigger for this task - channel A? It seems it will do the request. I would also add timing Vi, 1 pulse finite acquisition, sometimes it makes the difference.
What can you advise to read about counters, configured for counting pulses, but when you are using their output?
Here's an outline for an idea, point by point. There are potential flaws, but there's a chance they won't matter for your needs. Here goes:
1. CTR1 OUT continues to behave as it does now. External trigger edge causes immediate pulse from CTR1 with controlled duration 1-10 msec.
2. A new CTR2 is used to generate the fastest possible pulsetrain (Probably 25 MHz). It will be pause triggered by CTR1 OUT so it only generates high speed pulses during the controlled 1-10 msec of interest.
3. CTR0 continues to be a retriggerable single pulse, triggered by SIGNAL B. The new thing is that it uses CTR2 OUT as its timebase rather than using an internal continuous clock signal. The pulse will have a minimal low time (and may also need the same minimal "initial delay" for consistency) of 2 Ticks of the intermittent timebase coming from CTR2 OUT. I don't know how wide the high time will need to be for you. The wider you need, the more likely you are to bump into this method's flaws.
A. Once CTR0 gets triggered, it will ignore subsequent triggers until it finishes generating its pulse. You won't be able to usefully create a pulse wider than CTR1 OUT's high time. If you try, you'll see CTR0 quickly toggle to high state and stay stuck there until there are enough CTR1 pulses that their cumulative high times add up to CTR0's high time. During CTR1 OUT's low time, it's as though time stands still for CTR0 because its timebase is not cycling. During CTR1 OUT's low time, CTR0 OUT will simply maintain state and see pulses to count time with again after the next time CTR1 OUT goes high.
B. Assuming you can live with a CTR0 OUT high time < CTR1 OUT high time, you should wire in the relationship that makes sure that whatever CTR1 OUT's high time may be, it's used to calculate the max CTR0 OUT high time. Note that CTR0 high time need to be a smidge shorter than CTR1's, 1 microsec should be more than sufficient.
Well, none, kinda by definition. That doesn't mean you won't discover some. Just that I didn't anticipate them.
Thank you for your detailed suggestions. I tried to implement what you had suggested but ran into some issues, so I went back to the original idea of using the terminal count pulse. Essentially, the solution is to feed the counter output into the count direction input of the same counter. So it outputs a pulse every time it detects an edge.
I'm trying to think through your solution and I'm not quite following how it works to produce a CTR0 pulse for every eligible rising edge on Signal B. Here's where my thought experiment goes:
1. Configure CTR0 for edge counting, count direction controlled externally & configured to use its own output to determine count direction.
2. Further configure CTR0 for pause triggering by CTR1 OUT, and set its terminal count behavior to either pulse or toggle state (see below)
3. Even further configure CTR0 with an initial count that is 1 away from the terminal count taking into account the count direction dictated by CTR0's idle state
4. First eligible rising edge shows up on Signal B within time period that CTR1 OUT is in high state.
5. CTR0 count changes by 1 and activates terminal count behavior. (I'm mildly surprised here that this seems to be an exception to the many instances in counter programming that require a minimum of 2 source edges.)
6. Output either pulses briefly or toggles state.
6A. A brief pulse leaves CTR0 back at idle state. So you get the CTR0 pulse output, but the next eligible edge of Signal B keeps counting in the same direction and won't activate the terminal count behavior for a long, long time
6B. Toggling state means the counter is now ready to count in the opposite direction on the next eligible edge of Signal B. Apparently, returning back to the same value as the initial count will again activate terminal count behavior on the very next eligible Sig B edge. However, it takes 2 such edges to toggle state twice and create a pulse on CTR0 OUT.
The other surprising thing here is that your original post described an issue in item B that would seem to require you to go back and forth more than 1 count to keep reactivating terminal count behavior.
So which part(s) of that thought train do I have wrong?