Measuring Pulse Width


#1

Slowly learning XOD, but need some assistance. Here is the situation.

A series of pulses, from an external pulse source, are applied to an input pin. The ‘on’ time, of each pulse in the series of pulses, will not vary in pulse width or amplitude, during the series of pulses.

I want to measure and display on the LCD the ‘on’ time of one of the pulses. The ‘on’ time of the pulses can be very short. Maybe 2 or 3 usec.

Thanks in advance.

Wayne


#2

Unless something has been added recently, there are no existing XOD nodes to help you, but you might be able to create your own in C++ using the pulsein function.


#3

Thanks gweimer…

My expertise with C++ is below zero. My ‘expertise’ with Arduino IDE is copy/paste sketches.


#4

The node for hc-sr04-ultrasonic-time cycles the pin to force a new ping, then times how long it takes for the pin to switch back low so it knows how long it took for sound to make round trip. This should be close to what you need.


#5

Great idea. I will give it a try. Thanks!


#6

I think measuring the pulse width of very short duty cycle pulses that you’re working with, directly from a digital input, on a platform like the 8 bit AVR at say 16MHz is going to be difficult since the width of the pulses is within an order of magnitude of the 1/f system clock period. It’s a problem of timestep resolution for example the Arduino Uno environment has a maximum time resolution of 4 microseconds on a call to “micros()” , trying to timestamp two external events with a period shorter than that, and take a difference e.g. dt = (now - previousNow) will be indeterminate. I believe writing the code by hand for “regular Arduino” would bump into the same issue I don’t think it’s XOD-specific.

Possible solutions other than using some other faster device would be to either use an analog pulse stretcher circuit that stretches out the pulse by some known fixed amount prior to hitting the input, and then rescale the result in software, or use undersampling/averaging to indirectly infer the on time of a single pulse from a sequence of pulses of the same width.

My intuition is that the time averaging/undersampling approach is the way to go here, rather than mucking with the digital inputs. Get the sampled pulse train into digital domain ASAP via an analog/ADC channel input and at that point there are probably a number of copy-n-paste averaging DSP algorithms that can extract a pulse width from it. The 8 bit Arduino is fine at doing basic DSP tasks so long as the results aren’t expected to be “real time” :wink:


#7

The “Git-R-Done” approach I’m thinking of could likely be tried entirely with XOD patch nodes, no writing code required. Imagine the problem in the analog domain. You have a sequence of pulses. What you want is a DC voltage encoding its average pulse width, say the pulse train has a constant positive-going amplitude of 1 volt, in the analog domain you could average a pulse sequence to a DC voltage using an RCR filter followed by a buffer, so by appropriately picking components the filter spits out say 0.02 volts DC if the average pulse width of the train is 2%, 0.03 if it’s 3%, etc. over some (probably limited) range of input widths.

You could grunge a bunch of math to find out what the resistor and capacitor values would be to do that or adjust component values in analog simulation software or on a breadboard to find them empirically.

Basically the idea is to do exactly that but digitally in XOD, just send the pulse train to the ADC, it spits out a train of numbers whatever they are, send it to the digital equivalent of that analog filter, then send that output to LCD or serial port or whatever, and empirically tweak the coefficients of the digital filter while looking at the actual pulse width on a scope until it gives you the response you want for the range of pulse widths you expect. Could probably connect a couple pots to some of the other analog inputs to tweak the digital filter parameters in real time until the readout looks good compared to what the scope shows.

I don’t know for sure this will work out but seems plausible at least…


#8

Thanks bitrex…

I like the way you explained your thinking process in detail… I’m an old ‘hardware’ guy and definitely not a ‘coder’. Sure glad that XOD uses the ‘hardware’ approach to software.

How about this…

All the pulses in the pulse string will have essentially the same ‘on’ time. Actually, all we need to do is read the ‘on’ time of one of the pulses. The others can be ignored. For example, read the ‘on’ time of pulse #10 and display on LCD. (probably need a ‘latch’ and I haven’t found this in XOD)

My thoughts, for whatever they are worth, use the incoming pulse train to control one input of a gate. The other gate input is from the Arduino clock or 16mhz oscillator, if that signal is available. These would have to be extremely rapid pulses. Then count these pulses and feed them to LCD display. Not sure Arduino can generate extremely rapid pulses.

Thanks and God Bless,

Wayne


#9

Hi, sorry for the delay in my reply! I think the problem with that scheme is that as I understand it, the way XOD is currently set up, it would be difficult to generate a fast enough signal pulse to feed the gate. At those speeds I think you’d have to at least use some kind of hardware interrupt to “catch” the pulse which the XOD execution model doesn’t seem to support yet. It may be possible to do strictly with the straight-Arduino environment but I’m skeptical.

If you prefer to take a more hardware-centric approach instead of doing it all-DSP like my previous suggestion then I think the task could be simplified a lot by adding a small amount of external hardware to stretch out the first pulse in the sequence. If you know precisely the factor you stretch it by and it’s stretched out by say a factor of a hundred then measuring that width from the ADC input and then scaling in software becomes a pretty straightforward task. One-shot lockout/pulse stretchers are pretty easy circuits to build with modern fast CMOS logic I think I have a schematic around here somewhere…