概要
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