Arduinoの基礎 - 測距センサ
概要
ここでは、超音波距離センサ(HC-SR04)を使用して、距離を計測する方法を記載する。
超音波は、人の耳に聞こえない周波数の音波(空気の振動)で、超音波距離センサとは、超音波を出してその反射が返ってくる時間を測ることで距離を測定するセンサのことである。
音波を使う距離センサの他に、光を使う光学式の距離センサもある。
光学式の場合は、基本的に高い精度での計測が可能であるが、光が反射する面の色の影響を受けやすいなどの問題もある。
音波は精度が低いものの、反射面の色や材質の影響を受けにくい、 測定距離が長い、障害物の影響を受けにくい、などの特徴がある。
超音波距離センサ(HC-SR04)の使用
Arduinoにおいて、HC-SR04を使用するには、NewPingライブラリを使用する。
ArduinoのライブラリのWebサイトに、NewPingのダウンロードのリンクがあるので、zipファイルをダウンロードする。
Arduino Playground - NewPingライブラリ
zipファイルをダウンロード後、Arduino IDEを起動して、[Sketch]メニューバー - [Include Library] - [Add .ZIP Library...]を選択して、zipファイルを追加する。
次に、HC-SR04とSC1602A(I2Cアダプタ)を使用して、測定した距離をLCDに表示する仕組みを作成する。
HC-SR04は電源電圧5[V]、動作周波数40[kHz]、測定角度15[度]で動作する。
- 測定可能距離 : 2[cm]~450[cm]
- 分解能 : 0.3[cm]
- 最小範囲 : 2[cm]
- 動作方法
- トリガー(TRIG)に印加する電圧を10[μs]以上Highにすると、距離の測定を開始する。
- 測定後、距離に応じた長さの信号がECHOに返される。
- 測定結果から距離への換算は、以下のように計算する。(単位は[mm])
距離 = (ECHOがHighの時間 * 340) / 2
HC-SR04のピン配置は、以下の通りである。
また、測定結果をLCDに表示するため、以下のように配線している。
以下に、サンプルコードを記述する。
ping_median
メソッドを使用して、Pingの応答時間を取得している。
pingを5回試行して中央値を取得することにより、安定した値を取得することを試みている。
#include <NewPing.h>
#include <LiquidCrystal_I2C.h>
const int PIN_SONAR_TRIGGER = 12;
const int PIN_SONAR_ECHO = 11;
const int MAX_DISTANCE = 200;
NewPing sonar(PIN_SONAR_TRIGGER, PIN_SONAR_ECHO, MAX_DISTANCE);
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup()
{
lcd.init();
lcd.backlight();
lcd.clear();
}
void loop()
{
delay(50);
unsigned long microSec = sonar.ping_median();
unsigned long dist = sonar.convert_cm(microSec);
lcd.clear();
lcd.setCursor(0, 0);
if( !dist )
{
lcd.print("-");
return;
}
else
{
String s = String(dist);
s += "[cm]";
lcd.print(s);
}
}
または、NewPingライブラリを使用しない場合は、以下のようなソースコードとなる。
#include <LiquidCrystal_I2C.h>
// address : 0x27, 1602LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
void wait_microsec(long wait)
{
long start = micros();
while (( micros() - start) < wait);
}
void setup()
{
pinMode(11, INPUT);
pinMode(12, OUTPUT);
lcd.init();
lcd.backlight();
}
void loop()
{
digitalWrite(2, HIGH);
wait_microsec(11);
digitalWrite(2, LOW);
unsigned long range = pulseIn(3, HIGH ,1000000);
if(range)
{
range = ((range * 340) / 2) / 1000;
lcd.setCursor(0, 0);
lcd.print(range / 10, DEC);
lcd.print(".");
lcd.print(range - ((range / 10) * 10), DEC);
lcd.print(" cm ");
}
delay(200);
}