Arduinoで遊ぶページ

Arduinoで遊んだ結果を残すページです。
garretlab
pulseIn()

pulseIn()

概要

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

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

ソースコード

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

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です。

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

digitalPinToPort()digitalPinToBitMask()を使って、pinに対応するポートとビットマスクを求めます。digitalRead()の説明も参考にしてください。

	// 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を設定します。

	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で割ることで、最大何回ループするかを設定しています。

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

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

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

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

バージョン

Arduino 1.8.2



メニューを表示するためにJavaScriptを有効にしてください。

Arduinoで遊ぶページ
Copyright © 2017 garretlab all rights reserved.
inserted by FC2 system