pulseIn() の解説と実装リファレンス

記事内には広告が含まれています。

【概要】

pulseIn() は、指定したピンの信号が特定のレベル(HIGHまたはLOW)に達した瞬間から、次の状態変化(エッジ)が発生するまでの時間をマイクロ秒(μs)単位で測定する関数です。主に超音波距離センサのパルス幅計測や、RC受信機からのPWM信号解析など、パルス幅の取得が必要な用途で使用されます。

【仕様】

関数シグネチャ

unsigned long pulseIn(int pin, int level, unsigned long timeout);

引数

  • pin: 監視対象のデジタルピン番号。
  • level: 測定を開始するレベル。HIGH または LOW を指定。
  • timeout: タイムアウト時間(マイクロ秒)。指定した時間内にエッジが検出されない場合、関数は 0 を返します。指定しない場合、Arduinoのデフォルトタイムアウト(通常は1秒)が適用されます。

戻り値

  • unsigned long: 測定されたパルスの持続時間(マイクロ秒)。タイムアウトした場合は 0 を返します。

【技術的特徴】

動作原理

pulseIn() はブロッキング処理として動作します。関数を呼び出すと、指定したピンが level に達するまで待機し、その後、次のエッジが発生するまでCPUを占有したまま待機を続けます。この間、他のコードの実行は停止します。

内部実装と精度の差異

pulseIn() はハードウェアタイマーを直接駆動するものではなく、ソフトウェア的にマイクロ秒単位のカウントを監視します。そのため、高優先度の割り込み処理が実行されている最中には、測定精度にわずかな誤差が生じる可能性があります。

他の関数との比較

  • attachInterrupt() との比較:
    pulseIn() は簡易的な実装には適していますが、ブロッキングが発生するため、リアルタイム性が求められるシステムでは不向きです。一方で、attachInterrupt() を使用して割り込みフラグを立て、タイマーや micros() を利用して計算する方法は非ブロッキングであり、より高度なマルチタスク処理に適しています。

【注意点】

  • ブロッキングによる影響:
    pulseIn() は呼び出し中にプログラムの実行を停止させます。例えば、timeout を長く設定すると、その間他のセンサーの読み取りやLEDの点滅処理が中断されるため、設計には注意が必要です。
  • タイムアウト設定の重要性:
    タイムアウトを指定しない、あるいは極端に長い値を設定すると、信号が途切れた際にプログラムが長時間停止し、システム全体の応答性が著しく低下するリスクがあります。
  • パルスの最大値:
    unsigned long を使用しているため、理論上は非常に長いパルスも測定可能ですが、物理的な環境やArduinoの処理速度により、極端に長いパルスの精度は保証されません。

【サンプルコード】

以下は、HC-SR04超音波距離センサを用いて距離を計測する標準的な実装例です。

const int trigPin = 9;
const int echoPin = 10;
const int timeoutLimit = 30000; // 30ms timeout

void setup() {
  Serial.begin(9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  // Trig信号の送信
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Echoパルスの幅を取得
  unsigned long duration = pulseIn(echoPin, HIGH, timeoutLimit);

  if (duration > 0) {
    // 音速 340m/s を使用した距離計算 (往復分を2で割る)
    float distance = duration * 0.034 / 2;
    Serial.print("Distance: ");
    Serial.print(distance);
    Serial.println(" cm");
  } else {
    Serial.println("Out of range or sensor error");
  }

  delay(500);
}

【活用例】

  1. 超音波距離センサの統合:
    HC-SR04やParallax Ping等のセンサを用いて、障害物検知や距離測定を行うロボットの制御。
  2. RC受信機のPWM解析:
    RCカー等のステアリング信号(パルス幅で角度を決定する信号)を読み取り、アナログ的な操作量をデジタル値に変換する。
  3. 簡易的なパルス幅変調(PWM)のデコード:
    外部機器から送られてくる低速なPWM信号のデューティ比を算出する処理。

コメント

タイトルとURLをコピーしました