Duty Cycle of Clock pulse measurement T7


Recommended Posts

Hello Forum...

We wish to be able to measure the time a current is flowing over each of 4 channels. It may be for a fraction of a second or several seconds (maybe up to a minute).

We have two Labjack T7's and each currently monitors 4 experimental reactors

Our logging frequency for our experimental workbench is currently by the second and is something we want to maintain.

What we need to know is what is the duration of current "ON" for each second.

The frequency of current pulse is random. A channel may pulse a fraction of a second or indeed may remain "ON" for a number of seconds, therefore no rising or falling edges, just a constant high for the duration of several logging cycles (see attached graph).

I understand that if there are no rising (or falling edges) then the data will read as "0" which will be totally wrong for our purpose... or am I reading this wrong?

Is "Duty Cycle" using a rising edge the thing I should be looking for or should I be looking to count the number of pulses a signal is "HIGH". The "HIGH" being provided by our Hall Effect current sensor?

The current is a regulated 7.5 Amps... it does not vary except in terms of the time that is is on. I made up a simple Excel chart to illustrate what we are looking at.

Any guidance would be appreciated.




Link to comment
Share on other sites

Sounds like once per second you want to read a value that is the total duty cycle of a waveform over that last second.  So if the signal was high 50 ms, low 450 ms, high 150 ms and low 350 ms, you would get a reading of 20% for that 1 second.

The duty-cycle measurement timer mode measures every cycle, not the overall duty cycle of some time period, so that will not do what you describe.  The only way I can think of to do it in hardware, so DF can read the value once per second as you describe, would be to write a Lua script that measures the percent on of each second and puts that value in user-ram.  Sounds like a fairly easy script.


Link to comment
Share on other sites

34 minutes ago, LabJackSupport said:

Sounds like once per second you want to read a value that is the total duty cycle of a waveform over that last second.  So if the signal was high 50 ms, low 450 ms, high 150 ms and low 350 ms, you would get a reading of 20% for that 1 second.

Now why couldn't I express my needs as clear and as concise as that!

You have it in a nutshell.

I was hoping that DaqFactory would be able to handle this without the need to delve into scripting. I'm no programmer (by a long way). 

Can anyone point me in the right direction?

Link to comment
Share on other sites

You can do this in a sequence, but the precision of the result is going to be based on your acquisition speed due to quantization in time.  For example, if you have a Timing of 100ms, and pulses as described (50, 450, 150, 350), then DAQFactory is going to probably miss the 50ms pulse, or register it as 100ms, and round the others in one way or another.  To improve this, you simply need to sample faster.  Sampling at 0.01 is probably the fastest you can go without streaming, so streaming the input might be the best as then you can get data at much higher intervals.  But this is independent of how the calculation would be done in DAQFactory. 

So, let's say you have a channel called "current" that is either being acquired quickly through Timing or just streamed at high speed.  Next create a channel called "Duty" that is Device Type "Test", "D to A".  Then create a sequence to calc the duty and have it running whenever you want the duty calculated:

   private data = current[systime(), systime()-1]   // retrieve 1 second worth of data from history
   private pointsOn = sum(data > 0.5)
   private totalPoints = numrows(data)
   duty = pointsOn / totalPoints * 100


"while(1)" means loop forever
"private data =" gets all the data points recorded in the current channel for the last second.  It doesn't matter how many there are, as long as the data points are evenly spaced
"private pointsOn =" calculates the number of data points in current that read more than 0.5.  "(data > 0.5)" returns an array the same size as data containing either 1 when data is > 0.5, or 0.  Summing this array gets the number of points.
"private totalPoints =" simply gets the number of data points in the last second. 
"duty = " calculates the duty from those last two measurements
"delay(1)" waits a second before "endwhile" loops us back around

A few notes:
1) I could of course combine a lot of this into a single line, but left it split up so you can understand the flow
2) the way this is written it will miss data points during the few millisecond that the loop is calculating.  This is probably not a problem, but if it is there are ways to tighten it up, it just makes the script a little more involved.
3) remember, the precision of the result of this is dependent on your acquisition speed, and that the data points are equally spaced.  For this reason I suggest you stream the "current" channel as fast as you can.  Make sure the History of "current" is long enough to hold at least the last 2 seconds worth of data.  So if you are streaming at 10kHz, the history should probably be 20,000 or more.


Link to comment
Share on other sites


Thanks very much for that. 

My main problem is not knowing DaqFactory well enough to quickly implement your advice but I'm learning with each step. 

That was quite an elegant solution with the minimal of scripting involved... thanks very much yet again.



Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.