Reading pulse lengths accurately

Hi! I wanted to use my two boards (Arduino Unos) to: -Generate a pulse from one of the outputs -Read the pulse on a second board

I'm not concerned with how to hook the boards up, but more about the accuracy. -I was just wondering what the most accurate methods for generating a pulse were (and the shortest length of time I can accurately program the board to make a pulse for) -And the most accurate method for reading a pulse was (and the shortest pulse length it can accurately read)

I originally used PulseIn and digitalWrite with the micros() delay, but I found when I printed out the length of the pulse, my answers were very variable. Can anyone recommend me the best methods to use?

Have you got either pull up or pull down resistors on your input or outputs? If not it may be possible that they are floating.

Post a picture of your circuit wiring.

I don't have a good answer for you, but it depends on the 16Mhz processor clock (obviously, the Arduino can't generate a pulse shorter than its clock).

Then, it depends on how long it takes the processor to "run" the particular operations that generate the pulse as well as whatever else you programming is doing before it get's around the loop.

If you set an output pin high and then set it low in the next program step, that's going to take some amount of time and you'll get a short pulse. (I don't know how wide the pulse will be.) If you delay 1uS between those two program steps, you pulse will be longer than 1uS because it takes some time for the processor to perform an operation. Different operations take different amounts of time (which you can look-up in the datasheet). (But remember, the processor isn't running C++, it's running machine language compiled from C++ and there can be many machine instructions to complete one C++ statement/expression.)

If you are "printing-out" the results every time through the loop, the serial communication is going to slow-up your loop a LOT. If you can "capture" the reading to a variable, and then print it when you are no longer generating/reading pulses, you can work with shorter pulses and you should get more consistent results.

There should be a way to generate (or measure) pulses in the "background" because various libraries such as PWM, stepper motor, and servo drivers seem to work that way, but I'm not expert enough to know you how that's done. (It might involve interrupts and/or assembly language.)

Will you be outputting a single pulse every now and then OR a series of pulses like a square wave, and varry its on time? Have you tried an interrupt to aid in the reading? Port manipulation?

As far as I know you can program the onboard timers to generate a pulse on a pin when the count expires. If I'm right, this does not need any intervention by your code once you have it set up. You would need to read the Atmega 328 datasheet to get the details.

Measuring received pulses may not be so convenient. Basically you can set up an interrupt to save the value of micros() at each interrupt and then your code can subtract reading A from reading B to get the difference. However micros() increments in 4 usec jumps so it can't be very accurate at short intervals.

You could possibly set up a timer to give a shorter version of micros() but if you try to measure very short intervals you quickly run into the problem that you are using up all the CPU cycles and have none left for anything useful.


Interesting reading or the replies on this but one simple question in....

Why are you trying to do this? Just interested.

With a hardware timer/counter you should be able to get pulses with a precision of one clock cycle (1/16th of a microsecond). If you use pulseIn() on the receiving side you get a precision of 21 instruction cycles (1-5/16th microseconds). Probably best to use pulse width increments of 2 or 3 microseconds and a minimum pulse width of 10 microseconds.