超音波距離センサ HC-SR04を使って、Arduinoで距離測定を行う方法を説明します。
また、HC-SR04のデータシートの内容を確認しながら、測定原理についても確認します。
HC-SR04 とは
超音波で物体までの距離を測定することができる測距センサです。
実際に使ってみて、想像以上の高精度で驚きました。
実物は単三電池と同じくらいの大きさです。

上記の写真の左の発信器から超音波を出力し、測定対象の物体に反射して右の受信器で超音波を受信します。
超音波を発信してから受信するまでの時間を測定することで距離を測定することができます。
主な仕様については以下です。
その他の詳細な仕様については、データシートを確認してください。
- 動作電圧:5 V
- 動作電流:15 mA
- 動作周波数 : 40Hz
- 測定距離:2 -400 cm
- 測定角度:15°
HC-SR04 + Arduino の使い方
HC-SR04をArduinoで使う方法を説明します。
下記ではArduino UNOを使用しています。
配線
HC-SR04のピンの内容は以下です。

ピン番号 | Pin | 内容 |
---|---|---|
1 | Vcc | 5V電源 |
2 | Trig | 超音波発信 |
3 | Echo | 超音波受信 |
4 | GND | グランド |
Arduinoとの接続は以下のようにしました。
HC-SR04 | Arduino UNO |
---|---|
Vcc | 5V |
Trig | D7 |
Echo | D8 |
GND | GND |


スケッチ(プログラム)
スケッチはGitHubで公開されています。
上記の配線は、GitHubのスケッチに合わせています。
公開されているコードを下記に載せておきます。
/**
HC-SR04 Demo
Demonstration of the HC-SR04 Ultrasonic Sensor
Date: August 3, 2016
Description:
Connect the ultrasonic sensor to the Arduino as per the
hardware connections below. Run the sketch and open a serial
monitor. The distance read from the sensor will be displayed
in centimeters and inches.
Hardware Connections:
Arduino | HC-SR04
-------------------
5V | VCC
7 | Trig
8 | Echo
GND | GND
License:
Public Domain
*/
// Pins
const int TRIG_PIN = 7;
const int ECHO_PIN = 8;
// Anything over 400 cm (23200 us pulse) is "out of range"
const unsigned int MAX_DIST = 23200;
void setup() {
// The Trigger pin will tell the sensor to range find
pinMode(TRIG_PIN, OUTPUT);
digitalWrite(TRIG_PIN, LOW);
//Set Echo pin as input to measure the duration of
//pulses coming back from the distance sensor
pinMode(ECHO_PIN, INPUT);
// We'll use the serial monitor to view the sensor output
Serial.begin(9600);
}
void loop() {
unsigned long t1;
unsigned long t2;
unsigned long pulse_width;
float cm;
float inches;
// Hold the trigger pin high for at least 10 us
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// Wait for pulse on echo pin
while ( digitalRead(ECHO_PIN) == 0 );
// Measure how long the echo pin was held high (pulse width)
// Note: the micros() counter will overflow after ~70 min
t1 = micros();
while ( digitalRead(ECHO_PIN) == 1);
t2 = micros();
pulse_width = t2 - t1;
// Calculate distance in centimeters and inches. The constants
// are found in the datasheet, and calculated from the assumed speed
//of sound in air at sea level (~340 m/s).
cm = pulse_width / 58.0;
inches = pulse_width / 148.0;
// Print out results
if ( pulse_width > MAX_DIST ) {
Serial.println("Out of range");
} else {
Serial.print(cm);
Serial.print(" cm \t");
Serial.print(inches);
Serial.println(" in");
}
// Wait at least 60ms before next measurement
delay(60);
}
動作結果
実際に物体との距離を測定しました。
測定結果はシリアルモニタで確認することができます。
対象物体との距離が約10cmの場合です。
十分な精度です。


対象物体との距離が約30cmの場合です。
十分な精度です。


測定原理
超音波距離センサ HC-SR04 は、Trigピンを10μs High にすると、40KHzのパルスを8個発信します。
発信されたパルスは、物体に反射し、HC-SR04の受信器で受信します。

発信した40KHzのパルスの最後のパルスがLowになってから、受信機でパルスを受信するまでの時間を測定することで、距離を算出することができます。
以下はデートシートから引用したものに説明を追加したものです。

距離の算出
上記のように、超音波を発信してから受信するまでの時間を測定することで距離が算出できるのは、超音波の速度(音速)が分かっているからです。
空気中の音速は、私たちが生活するような気温では1次式で近似することができます。

近似した式は以下です。
音速(m/s) = 331.5 + 0.61 t (m/s) (※ t は摂氏温度)
多くの分野で音速について言う時、常温として15℃を採用することが一般的であり、その場合 340.5(m/s)となる。それで一般に、音速を15℃で秒速340mとしている。
wikipediaより引用
HC-SR04のデータシートや上記のGitHubのコードでは、音速を 340m/s として、距離を算出しています。
Distance = (ECHO high level time X ultrasonic velocity (Speed of Sound in air 340m/sec) / 2, you can calculate the distance to the obstacle.
HC-SR04 データシートより抜粋
上記の内容を式にしたのは以下です。
$$ 距離[m] = 340[m/s] × \frac{ECHO high level time}{2}\ $$ECHO high level time(μsec)は、上記で説明したパルスを出力してから受信するまでの時間のことです。
時間は往復の時間なので、物体にパルスが到達する片道の時間は半分です。
測定距離は cm で表したい、Arduinoで扱う時間はμsec なので上記の式の単位を変換します。
$$ 距離[cm] = \frac{340[m/s] * 100}{1000000}\ × \frac{ECHO high level time[μsec]}{2}\ $$つまり、
$$ 距離[cm] = 0.017[cm / μsec] × ECHO high level time[μsec] $$データシートには、以下のように距離の算出方法が記載されています。
Distance in cm = echo pulse width in uS/58
1/58 = 0.017 なので、上記の算出内容はデータシートと同じ距離算出方法です。
GitHubのスケッチの距離算出式も上記となっています。
ラップタイマを自作したい
実家の畑に父親がラジコンのサーキットを作りました。

ラップを測定するために、上記のセンサでラップタイマーを作ってみようと思います。
上記センサとは別に赤外線センサでも試してみましたが、超音波センサの方が扱いやすそうなので赤外線センサで試してみようと思います。
