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 AVR Boards 1.8.6

License

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
  Copyright (c) 2019 garretlab.
  Added source code explanation by garretlab.
*/

/*
  wiring_pulse.c - pulseIn() function
  Part of Arduino - http://www.arduino.cc/

  Copyright (c) 2005-2006 David A. Mellis

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General
  Public License along with this library; if not, write to the
  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  Boston, MA  02111-1307  USA
*/

Last Update

July 31, 2025

inserted by FC2 system