e-NOXProject#006 超音波で距離を測る

これまでのe-NOX Projectでは、ESP32を使ってLEDを光らせ、ブザーを鳴らし、PIR人感センサーで人の動きを検知してきた。

今回は、新たに超音波距離センサー「HC-SR04」を接続した。

目標は単に距離の数値を表示することではない。

人感センサーが人の動きを検知した時だけ距離を測定し、対象が近づくほどブザーの鳴り方を変える。

つまり、

検知 → 測定 → 判断 → 出力

という一連の処理を、ESP32上で成立させることが今回の目的だった。


今回使用した部品

  • ESP32開発ボード
  • HC-SR04超音波距離センサー
  • PIR人感センサー 2個
  • パッシブブザー
  • 1kΩ抵抗 3本
  • ブレッドボード
  • ジャンパーワイヤー

PIRセンサーは2方向へ向けて設置した。

そのうち、超音波センサーと同じ方向を向いたPIRを「PIR1」、反対方向を向いたものを「PIR2」とした。

PIR1が反応した場合のみ、正面の超音波センサーで距離を測定する。

PIR2は別方向の人の動きを検知するだけで、距離測定は行わない。

超音波センサーが向いていない方向の距離を測定しても、壁や別の物体までの距離を誤って表示するためである。


GPIOの割り当て

今回の接続は次のようにした。

機器ESP32
PIR1 OUTGPIO12
PIR2 OUTGPIO13
HC-SR04 TRIGGPIO25
HC-SR04 ECHOGPIO27
ブザーGPIO26
各センサー VCC5V
各センサー GNDGND共通

ECHO端子には分圧回路が必要

HC-SR04のECHO端子からは、約5Vの信号が出力される。

一方、ESP32のGPIOは3.3V系であるため、ECHO端子をGPIO27へ直接接続するのは避ける必要がある。

今回は1kΩ抵抗を3本使用し、次の分圧回路を作った。

HC-SR04 ECHO

      │

     1kΩ

      │

      ●──── GPIO27

      │

     1kΩ

      │

     1kΩ

      │

     GND

GPIO27へ接続する位置は、上側の1kΩ抵抗と、下側の2kΩ相当の抵抗の接続点である。

テスターで確認すると、

  • ECHO~GPIO27:約1kΩ
  • GPIO27~GND:約2kΩ
  • ECHO~GND:約3kΩ

となり、分圧回路が正しく構成されていることを確認できた。


超音波センサーの仕組み

HC-SR04は、TRIG端子へ短い信号を送ると超音波を発射する。

超音波が物体に当たり、反射して戻るまでの時間がECHO端子から出力される。

音波は対象物まで進み、再びセンサーへ戻ってくるため、測定時間は往復分である。

そのため距離は、次の考え方で求める。

距離 = 音速 × 往復時間 ÷ 2

今回は音速を約0.0343cm/µsとして計算した。


使用したプログラム

const int pir1Pin = 12;

const int pir2Pin = 13;

const int trigPin = 25;

const int echoPin = 27;

const int buzzerPin = 26;

void setup() {

  Serial.begin(115200);

  pinMode(pir1Pin, INPUT);

  pinMode(pir2Pin, INPUT);

  pinMode(trigPin, OUTPUT);

  pinMode(echoPin, INPUT);

  pinMode(buzzerPin, OUTPUT);

  digitalWrite(trigPin, LOW);

  noTone(buzzerPin);

  Serial.println(“PIR+超音波+ブザー統合テスト開始”);

}

float measureDistanceCm() {

  digitalWrite(trigPin, LOW);

  delayMicroseconds(2);

  digitalWrite(trigPin, HIGH);

  delayMicroseconds(10);

  digitalWrite(trigPin, LOW);

  // 約4m相当でタイムアウト

  unsigned long duration =

      pulseIn(echoPin, HIGH, 23500);

  if (duration == 0) {

    return -1.0;

  }

  float distanceCm =

      duration * 0.0343 / 2.0;

  // HC-SR04の有効範囲外を除外

  if (distanceCm < 2.0 ||

      distanceCm > 400.0) {

    return -1.0;

  }

  return distanceCm;

}

void loop() {

  int pir1State = digitalRead(pir1Pin);

  int pir2State = digitalRead(pir2Pin);

  Serial.print(“PIR1: “);

  Serial.print(pir1State);

  Serial.print(”  PIR2: “);

  Serial.println(pir2State);

  // PIR2は別方向の人感検知のみ

  if (pir2State == HIGH) {

    Serial.println(

      “PIR2方向で検知・距離測定なし”

    );

  }

  // 超音波センサーと同じ方向の

  // PIR1が反応した場合だけ距離測定

  if (pir1State == HIGH) {

    Serial.println(

      “PIR1方向で検知・距離測定開始”

    );

    float distanceCm =

        measureDistanceCm();

    if (distanceCm < 0) {

      Serial.println(“距離測定不能”);

      noTone(buzzerPin);

      delay(300);

      return;

    }

    Serial.print(“距離: “);

    Serial.print(distanceCm, 1);

    Serial.println(” cm”);

    if (distanceCm <= 15.0) {

      // 非常に近い:連続音

      tone(buzzerPin, 2000);

      delay(200);

    }

    else if (distanceCm <= 30.0) {

      // 近い:速い断続音

      tone(buzzerPin, 1600);

      delay(100);

      noTone(buzzerPin);

      delay(100);

    }

    else if (distanceCm <= 60.0) {

      // やや近い:遅い断続音

      tone(buzzerPin, 1200);

      delay(100);

      noTone(buzzerPin);

      delay(400);

    }

    else {

      // PIR1は検知したが距離は遠い

      noTone(buzzerPin);

      delay(300);

    }

  }

  else {

    noTone(buzzerPin);

    if (pir2State == LOW) {

      Serial.println(“検知なし”);

    }

    delay(300);

  }

  Serial.println(“—————-“);

}


動作結果

動作は次のようになった。

PIR1が反応しない

→ 超音波測定を行わない

→ ブザー停止

PIR1が反応

→ 正面の距離を測定

距離60cm超

→ 距離表示のみ

距離30~60cm

→ ゆっくりした断続音

距離15~30cm

→ 速い断続音

距離15cm以内

→ 高い連続音

PIR2だけが反応

→ PIR2方向での検知を表示

→ 距離測定とブザー制御は行わない

手や本を超音波センサーの正面へ近づけると、シリアルモニターに表示される距離が小さくなり、それに応じてブザーの鳴り方も変化した。


約453cmと表示された理由

試験中、まれに約453cmという距離が表示された。

HC-SR04の一般的な測定範囲は約2~400cmであるため、453cmは有効な測定値ではない。

対象物が斜めになっていた場合や、反射波を正常に受信できなかった場合、ノイズなどを遅い反射として誤って読み取ることがある。

そこで、プログラム側で400cmを超える値を「測定不能」として除外する処理を追加した。

センサーから得られた数値を、そのまま正しいものとして扱わない。

測定範囲や条件を確認し、異常値を除外することも、センサーを扱ううえで重要な処理だと分かった。


PIRが鳴り続けない理由

今回使用したPIRセンサーは、「人が存在すること」そのものではなく、赤外線分布の変化、つまり人の動きを検知している。

そのため、PIR1がHIGHになっている間だけ超音波測定とブザー制御が行われる。

人が静止したり、PIRの保持時間が終了したりすると、PIR1はLOWへ戻り、ブザーも停止する。

人が動く

→ PIR1 HIGH

→ 距離測定

→ ブザー作動

人が静止する

→ PIR1 LOW

→ ブザー停止

再び動く

→ 再検知

これは故障ではなく、PIRセンサーの性質によるものだった。


今回の成果

これまでは、それぞれの部品を単独で動かしてきた。

今回は初めて、複数のセンサーと出力装置が一つの判断処理としてつながった。

PIRが動きを検知する

        ↓

超音波で距離を測定する

        ↓

ESP32が距離を判断する

        ↓

ブザーの鳴り方を変える

単なるセンサーの動作確認から、機械が状況に応じて反応を変える段階へ進んだ。

まだ単純な条件分岐にすぎない。

しかし、e-NOXが将来、周囲を検知し、距離を判断し、安全な行動を選択するための基本構造は、この中にすでに含まれている。


次の課題

次の段階では、以下を検討する。

  • PIRがLOWに戻っても数秒間は距離測定を継続する
  • 超音波を複数回測定し、中央値を使用する
  • 距離測定値のばらつきを記録する
  • サーボで超音波センサーの方向を変える
  • 左右方向の簡易距離マップを作成する
  • XIAO ESP32S3 Senseのカメラ情報と統合する
  • 将来的にPavo Pico IIへ搭載する

今回の実験で、e-NOXは「何かが動いた」と感じる段階から、「どの方向にいて、どれだけ近いか」を判断し始めた。

小さな進歩ではあるが、検知、測定、判断、出力という構造が成立した意味は大きい。

e-NOX Projectは、少しずつ感覚器官を獲得している。


Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です