pulseIn()

概要

pulseIn()は、ピンに入力されるパルスの時間を計測します。

pulseIn()のリファレンスはこちらをご覧ください。

ソースコード

pulseIn()は、hardware/arduino/avr/cores/arduino/wiring_pulse.c に定義されています。以下に全ソースコードを示します。

 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;
}

入力はpin、state、timeoutで、それぞれ、uint8_t、uint8_t、unsigned longです。戻り値はunsigned longです。

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

digitalPinToPort()digitalPinToBitMask()を使って、pinに対応するポートとビットマスクを求めます。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);

stateMaskと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;

stateMaskは、入力で指定したデジタルピン(pin)に対応するビットが0か1かを調べるための変数です。stateが0の場合はpinがLOWの時間を測定するので0を設定し、stateが0以外の場合はpinがHIGHの時間を測定するので、ピンに対応するビットマスクを設定します。

maxloopsは、入力パラメータで指定したtimeout(マイクロ秒単位)をmicrosecondsToClockCycles()でクロック数に変換し、1回のループでのクロック数の16で割ることで、最大何回ループするかを設定しています。

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

countPulseASM()を呼び出して、指定したピンが指定した状態であるかを判定するためのループを何回実行したか(何回回ったか)を取得します。

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;
}

最後に、widthが0でない場合は、widthをclockCyclesToMicroseconds()で、マイクロ秒に変換した値を、widthが0の場合は0を返します。

バージョン

Arduino AVR Boards 1.8.6

最終更新日

March 21, 2023

inserted by FC2 system