🐝

ESP32と超音波センサ(HC-SR04)で距離測定

2023/06/05に公開


はじめに

この記事では超音波距離センサ(HC-SR04)をESP32開発ボードに接続し、Micropythonプログラムにより物体までの距離を測定する方法について記述しています。

In English

This article describes how to measure distance using ultrasonic sensor HC-SR04 and ESP32 development kits in Japanese.

基礎知識

超音波の反射時間を利用して非接触で測距するモジュール。外部からトリガパルスを入力すると超音波パルス(8波)が送信され、出力された反射時間信号を計算することで距離が測定できます。

altHC-SR04

HC-SR04の仕様

HC -SR04の仕様書(英語)

電源電圧 5V(Vcc - Gnd間)
測定可能距離 2cm~400cm
測定精度 3mm

距離測定の仕組

altHC-SR04

  1. センサのTrig入力に10μ秒のパルスを加える
  2. 40kHzの超音波を8サイクル分連射
  3. 物体までの往復距離に応じたパルス幅の信号がEcho端子に出力される
  4. Echo端子のHighの時間を計測すれば計算式より距離が計算できる
  5. 距離=(Highの時間*340ms)/2 (音速は温度により変化するが、ここでは簡単のため一定としている。)

端子

  • Vcc 電源電圧(5V: 3.3Vでは動作不能)を与える
  • Trig 測定開始信号を与える
  • Echo 反射があるとONになる
  • Gnd グランドライン(GND)

準備

誤結線による事故からESP32開発ボードやPCを守るために、ESP32開発ボードからUSBケーブルを引き抜く。

用意するもの

  • HC -SR04超音波距離センサ
  • リード線(赤、黒、黄、白それぞれ1本)

結線

  • Vcc 5Vに接続
  • Trig GPIO5に接続
  • Echo GPIO18に接続
  • Gnd GNDに接続

サンプルプログラム1

1秒毎に距離を測定し表示する。

8行目:Trig端子はGPIO5を使用。
9行目:Echo端子はGPIO18を使用。
11行目:インスタンス作成。trigはGPIOを出力として使用。
12行目:インスタンス作成。echoはGPIOを入力として使用。
15行目~16行目:一旦trigを5μ秒OFF(Low)にする。
19行目~21行目:10μ秒のトリガパルスをTrig端子に送出。
24行目~25行目:反射が来るまで無限ループ。
27行目:nowに現在のナノ秒をセット(正確には、電源投入もしくはハードウェアリセットからのナノ秒)
30行目~31行目:Echo端子がHighの間、無限ループ。
33行目:refに現在のナノ秒をセット。
36行目:反射に要したナノ秒をマイクロ秒に変換。
39行目:tは往復に要した時間となっているので、その半分の値を29.4μ秒で割って距離をcmで表すようにしている。
ここでは、音速を340m/秒とし、1μ秒ではその

10^{-6}
となるので、0.034cm/μsec、1cm進むのにその逆数の29.4μsec/cmとしている。
40行目:距離を少数2位まで表示。

altultrasonic1.py
ultrasonic1.py

コピペ用 ultrasonic1.py
ultrasonic1.py
# Ultra Sonic Sensor(HC-SR04)
# Apr.14th 2023
# Vcc should be connected to 5V instead of 3.3V.

from machine import Pin
import time

TRIG = 5
ECHO = 18

trig = Pin(TRIG, Pin.OUT)
echo = Pin(ECHO, Pin.IN)

while True:
    trig.off()
    time.sleep_us(5)
    
    # Making 10μsec trigger
    trig.on()
    time.sleep_us(10)
    trig.off()
  
    # Waiting for echo
    while echo.value() == 0:
        pass
    # Got echo back
    now = time.time_ns()
    
    # Measuring echo duration
    while echo.value() == 1:
        pass
    # Echo turns off
    ref = time.time_ns()
    
    # Convert nano sec. to micro sec.
    t = (ref - now) / 1000
    
    # sound travels about 340m/sec, it means 0.034cm/μsec, it is 29.4μsec/cm
    d = (t /2) / 29.4
    print('{:.2f} cm'.format(d))
   
    time.sleep(1)


サンプルプログラム2

サンプルプログラム1と同様に1秒毎に距離を測定しますが、この例ではMicropythonのtime_pulse_us() を使用したものです。

https://micropython-docs-ja.readthedocs.io/ja/latest/library/machine.html#machine.time_pulse_us より引用

machine.time_pulse_us(pin, pulse_level, timeout_us=1000000, /)

指定の pin のパルスを計時し、パルスの持続時間をマイクロ秒単位で返します。 pulse_level 引数には、低パルスを計時する場合に 0、高パルスを計時する場合に 1 を指定します。

ピンの現在の入力値が pulse_level と異なる場合、関数は最初にピン入力が pulse_level に等しくなるまで待機し、次にそのピンが pulse_level に等しい時間を測ります。ピンが既に pulse_level に等しい場合、計測はすぐに開始されます。

タイムアウトが発生した場合、上記の状態を待っていた場合は -2 を返し、上記の場合は -1 を返します。タイムアウト時間は両方のケースで同じで、 timeout_us (マイクロ秒単位)で指定します。

altultrasonic2.py
ultrasonic2.py

コピペ用 ultrasonic2.py
ultrasonic2.py
# Ultra Sonic Sensor(HC-SR04)
# Apr.14th 2023
# Vcc should be connected to 5V instead of 3.3V.

from machine import Pin, time_pulse_us
import time

TRIG = 5
ECHO = 18

trig = Pin(TRIG, Pin.OUT)
echo = Pin(ECHO, Pin.IN)

while True:
    trig.off()
    time.sleep_us(5)
    
    # Making 10μsec trigger
    trig.on()
    time.sleep_us(10)
    trig.off()
  
    # time_pulse_us() returns μsec. 
    t = time_pulse_us(echo, 1)
   
    # sound travels about 340m/sec, it means 0.034cm/μsec, it is 29.4μsec/cm
    d = (t /2) / 29.4
    print('{:.2f} cm'.format(d))
   
    time.sleep(1)


演習問題

  1. 呼び出すと距離を返す関数 measure() を作成し、ultrasonic1.py を同じ機能を提供するようなプログラムを作成して下さい。(ファイル名:ultrasonic-ex1.py)

  2. 作成した関数 measure() を使用して、人が近づいてくると圧電スピーカから「ドミソ」、遠ざかって行くと「ソドミ」と音が出るプログラムを作成してください。(ファイル名:ultrasonic-ex2.py)

Discussion