Understanding pulseIn() timeout

I'm having trouble figuring out what the meaning of pulseIn()'s timeout parameter.

From the reference Description I read that pulseIn():

Returns the length of the pulse in microseconds or gives up and returns 0 if no complete pulse was received within the timeout.

This implies that the function could time out any time before the final edge occurs between the pulse "ON" state and pulse "OFF" state. So if you call pulseIn(pin, HIGH, timeout) with pin in initial state LOW, the timeout may occur while the pin is in the HIGH state after the initial transition from LOW to HIGH.

...but on the same reference page, the timeout parameter is described as:

timeout (optional): the number of microseconds to wait for the pulse to start; default is one second. Allowed data types: unsigned long.

and, similarly the return value is described as:

The length of the pulse (in microseconds) or 0 if no pulse started before the timeout. Data type: unsigned long.

which contradicts what's in the Description section, by implying that the timeout cannot occur once the pin is put in the pulse "ON" state; in the example I gave above, pulseIn() could time out if the pin never transitions from LOW to HIGH, but once in HIGH state, there's no chance of timing out before the pin goes back to LOW.

So... which is it?

Thanks,
Zach

I think it's just a writing error. Aka, the person writing didn't realize the difference. The code to do the pulseIn is written is assembly so not that easy to read. But the orignal C code seems to be includes (but I don't know for sure if someone changed the assembly code

From wireing_pulse.S

 * {
 *     unsigned long width = 0;
 *     // wait for any previous pulse to end
 *     while ((*port & bit) == stateMask)
 *         if (--maxloops == 0)
 *             return 0;
 *
 *     // wait for the pulse to start
 *     while ((*port & bit) != stateMask)
 *         if (--maxloops == 0)
 *             return 0;
 *
 *     // wait for the pulse to stop
 *     while ((*port & bit) == stateMask) {
 *         if (++width == maxloops)
 *             return 0;
 *     }
 *     return width;
 * }

Aka, it will return 0 if the timeout is reached and a pulse did not start yet or didn't end yet. Last including if pulseIn() is called after the actual pulse is started because it will ignore an ongoing pulse.

So this item can go on the list of improvements of the Arduino references :slight_smile:

Thanks. I'm working on a project implementing the Arduino API on our own hardware from scratch. So I'm trying to hunt down the correct semantics. I'd just like to verify that this implementation is taking the correct interpretation.

To compound confusion, I found an older reference which states that pulseIn():

Gives up and returns 0 if no pulse starts within a specified time out.

which completely agrees with Interpretation #2 (timeout only before pulse starts)...

So this means that either (1) Arduino changed its specification to Interpretation #1 (timeout can happen any time) after this previous incarnation was written but missed some doc changes, or (2) it's always been Interpretation #2, "complete pulse" is an error, and it's been coded with this erroneous interpretation in mind. I find situation (1) more reasonable, but you never know.

Is there anyone who knows what the spec should be that can verify which interpretation is correct??

Thanks again,
Zach

If anyone wants to submit a proposal to improve this documentation, or any of the other content in the Arduino Language Reference, you can do that by following this tutorial:
https://create.arduino.cc/projecthub/Arduino_Genuino/contribute-to-the-arduino-reference-af7c37

Thank you. I would create a Pull Request if I knew the proper semantics! I've submitted Issue #706...

Thanks!

ahazybellcord's issue report: