Showing results for 
Search instead for 
Did you mean: 

Count Pulses per second in Digital Waveform

Go to solution

Need to count number of pulses each second acquiring digital waveform data from a Thermo-Fisher Neutron Flux Unit.

VI is based on the Continuous Measurement Template.

Not using Counter Example because we need timestamps for each pulse.

Currently using waveform generator on the bench to simulate the pulses.

Labview 2021,cDAQ chassis + 9402 module, see attached zip file

I am displaying the data in a digital graph, but need to also display pulses per second, a digital indicator is fine.

0 Kudos
Message 1 of 6
Accepted by topic author GretchenSkellyZimmer

I'm a little confused about the nature of the task you are trying to accomplish.  As I understand it, you want to acquire the time that individual Pulses occur, and that onset time is the only measure of interest (all the pulses are the same height, and pulse duration isn't an issue).  I'm also assuming that pulses occur "relatively infrequently", say, at least a few milliseconds apart.


Oops -- I just went back and looked again at your Trial1, where you clearly are taking a digital waveform sampled at 10 kHz and taking 10K samples at a time (or one DAQmx Read/second).  You are "doing the right thing" to save the data as a Waveform, as you get a TimeStamp as the t0 component of every Waveform (one every 10 seconds).  You absolutely do not need to (and should not) save a separate Waveform in the DAQ loop, as you can always calculate it from the Waveform data, itself.


Suppose you look at the first Waveform.  I'm assuming you are looking for the Rising Edge (start of the Pulse), but might also be interested in the Falling Edge (to measure Pulse Width).  Here's what you do:

  1. Get t0 from the Waveform cluster.
  2. You need a Shift Register to hold the previous Pulse value, which you can initialize to False.
  3. Decide if you want to process all 10000 points inside the DAQ loop (you probably can do this with time to spare, but if not, simply make the DAQ loop a Producer and send the Waveform to a Consumer loop for the processing.
  4. We're going to build an Array of "Rising Edges" that consist of the TimeStamp of the Rising Edges.  [If you want to save the "time between rising edges", you certainly can do that, instead, but it seems simpler and more flexible, to me, to save Time of Rising Edges).
    1. In your inner loop, you are looking for a "Rising Edge",   This will be when the Previous Edge (in Shift Register) is Low and the current Digital level is High.  When this happens, you need to calculate the TimeStamp appropriate for that time.  This is simply t0 (from the Waveform component) + i/(sampling rate), where "i" is the index of the For loop.  Do you know about Conditional Tunnels?  You want to bring this computed value to the edge of the inner For Loop (where it will turn into an indexing Tunel), right-click the tunnel, and turn on "Conditional" (I think it's the bottom choice) and wire the "True" from the "Rising Edge" Case structure) to it.  Notice that when it is not the Rising Edge, the "other case" is False, so those TimeStamps will not be saved, just what you want.
    2. Finally, bring the current Y value (High or Low) to the right Shift Register to be ready for the next loop.
  5. When you've done all of this, you will have a (much smaller) array consisting of the TimeStamps (in "absolute time", so remember to save the very first TimeStamp if you want to change to "relative time", or "time since I started recording", which you get by simply subtracting "Start time" from "Rising Edge times" (you don't even need a For loop for this -- you can subtract a single constant from an Array to get an Array of Differences).

I hope this gets you started on the right path.


Bob Schor

0 Kudos
Message 2 of 6

Bob, thank you so much for your reply.  I read through it all; you had some good suggestions.

I came up with a solution by writing a small Labview VI and worked through a solution that way.

I am able to determine the 'counts per second', which is what I needed.

They key is to divide the counts per read of Digital Waveform, and then divide by the duration,

i.e. the time of the last read minus the time of the first read.

See attached images of small VI, front & back panels.

I only wanted to count the rising edge, i.e. one '1' - not the entire flat top.

So that is why I call the subVI 'DeleteExtraOnes'.


Download All
0 Kudos
Message 3 of 6



     I'm glad you got something working.  But let me make a few suggestions, starting with the choice of variable for your "signal".  Your "Data In" is an array of U8, or a "byte", which LabVIEW (and many other Programming Languages) considers to be numeric value from 0 to 255.  By convention, many of these Programming Languages represent Boolean (2-value, True or False) data as a Byte, with 0 usually meaning "False" and 1 usually meaning "True".  I , wasn't sure if LabVIEW also did this, but I just tested it, and it does, but you were "lucky".


But let me play "Professor" for just a moment, and change your input, an Array of U8 representing a Boolean signal with 1 = True and 0 = False, and show you a "cleaner" way to detect rising edges using a true Boolean signal, i.e. an Array of Boolean.


Right away, a question arises -- if the first entry is True, do you want to count this as a Rising Edge or not?  I'm going to assume that whatever the first point is, I'm not going to count it as a "rising edge", which means that I'll (arbitrarily?) say that the point before it (which I use to initialize the Shift Register) is also True.


Here I generate an array of 200 Booleans, with 10% True and 90% False (more-or-less), and this will be my "TTL Signal".  Then I'll count rising edges quickly and "neatly" -- if the present sample is False (= Low), then it is not a Rising Edge; if it is True, it is a Rising Edge if the previous signal was False (i.e. Not Previous), and in both cases, the present sample goes into the Shift Register for the next time through the For Loop.  Finally, when the Loop exits, I simply change the Array of Booleans to an Array of 0, 1 in order to add them up and see how many "randomly chosen" TTL High values I generated (10% of 200 = 20, more or less).

Rising Edges.png

With the probability of a logic High (true) at 10% (uniform Random (0, 1) < 0.1), one might expect about 105 of the samples would be (single) Rising Edges.  Try running this with the probability set to 0.5, or 0.8 -- does the answer "make sense" to you? 


Bob Schor


P.S. -- oops, I just realized that I forgot to clear the Graph before plotting it, so it gets ugly fast.  It's late, so I'm going to leave this as "an exercise for the reader" ...


0 Kudos
Message 4 of 6

Bob, thanks so much for your reply, I appreciate your effort even though it is late!

I will try out your example, and surely implement it.  I want my waveform processing to be efficient / fast, and I think these ideas will help.  In general, I have found working with Digital Waveforms much trickier than with Analog waveforms, starting with the fact that some of the Dig routines do not work as advertized.

Thanks again,


0 Kudos
Message 5 of 6

Most of my work has been with analog waveforms (such as nerve spikes) -- I haven't (yet) had the pleasure of trying to create digital graphs.  A colleague lent me a digital oscilloscope, with a "digital probe", and I can barely understand how to turn it on!


Bob Schor

0 Kudos
Message 6 of 6