Playing with Arduino
A page to record my playing with Arduino
pulseIn()

Abstract

The pulseIn() measures the time of input pulse.

Source Code

The pulseIn()is defined in hardware/arduino/avr/cores/arduino/wiring_pulse.c as below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
    // cache the port and bit of the pin in order to speed up the
    // pulse width measuring loop and achieve finer resolution.  calling
    // digitalRead() instead yields much coarser resolution.
    uint8_t bit = digitalPinToBitMask(pin);
    uint8_t port = digitalPinToPort(pin);
    uint8_t stateMask = (state ? bit : 0);
 
    // convert the timeout from microseconds to a number of times through
    // the initial loop; it takes approximately 16 clock cycles per iteration
    unsigned long maxloops = microsecondsToClockCycles(timeout)/16;
 
    unsigned long width = countPulseASM(portInputRegister(port), bit, stateMask, maxloops);
 
    // prevent clockCyclesToMicroseconds to return bogus values if countPulseASM timed out
    if (width)
        return clockCyclesToMicroseconds(width * 16 + 16);
    else
        return 0;
}

The inputs are pin, state and timeout. The types are uint8_t, uint8_t and unsigned long respectively. The return is unsigned long.

1
2
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{

First it gets the port and bitmask coresponds to the specified pin using digitalPinToPort() and digitalPinToBitMask(). Also see the explanation in digitalRead().

3
4
5
6
7
    // cache the port and bit of the pin in order to speed up the
    // pulse width measuring loop and achieve finer resolution.  calling
    // digitalRead() instead yields much coarser resolution.
    uint8_t bit = digitalPinToBitMask(pin);
    uint8_t port = digitalPinToPort(pin);

It sets stateMask and maxloops.

 8
 9
10
11
12
    uint8_t stateMask = (state ? bit : 0);
 
    // convert the timeout from microseconds to a number of times through
    // the initial loop; it takes approximately 16 clock cycles per iteration
    unsigned long maxloops = microsecondsToClockCycles(timeout)/16;

The stateMask is a variable to check if the bit coresponds to the pin is 0 or 1. When the state is 0, it is set to 0 to measure the time of LOW state. If the state i not 0, it is set to bitmask of the pin.

The maxloops is the maximum loop numbers. The timeout(micro seconds) input parameter is converted to clock ticks using microsecondsToClockCycles(). See the comment in the source code.

14
    unsigned long width = countPulseASM(portInputRegister(port), bit, stateMask, maxloops);

The countPulseASM() is called to get how many it looped with the specified state.

16
17
18
19
20
21
    // prevent clockCyclesToMicroseconds to return bogus values if countPulseASM timed out
    if (width)
        return clockCyclesToMicroseconds(width * 16 + 16);
    else
        return 0;
}

If the width is not 0, converts the width to microseconds using clockCyclesToMicroseconds() then retrun the value.

If the width is 0, it returns 0.

Version

Arduino 1.8.13

Last Update

June 19, 2020

inserted by FC2 system