ESP8266に距離センサー(HC-SR04)を繋いで距離を測るコードを書いてみました。
※最終的に、このセンサー&ESP8266は自宅ガレージシャッターの開閉状態をSlackに通知する用途に使う予定
パーツについて
HC-SR04は200~400円ぐらいで買える超音波を利用した距離センサーです。
安い! ⇒ Amazon(HC-SR04)
ESP8266はNodeMcu Lua ESP8266 CH340という開発ボードを使っています。
中国から届くのに時間がかかりますが、¥480と激安です。
回路について
最初にGPIOとセンサーを直結して動かなくて、調べてみたらこのセンサーは電源に5Vが必要なようです。
開発ボードのUSBの5Vを利用することにします。
センサーの出力(Echo)も5Vなので、3.3VのESP8266につなぐには分圧回路というのが必要とのことで、ネットの情報を参考にしつつ、見よう見まねで組んでみました。
写真の左側にある3連抵抗の部分で、5Vを3.3Vに落としている感じです。
※1個目の抵抗と2個めの抵抗の間から信号を取ると 5V * 2/3 ≒ 3.3V
出力を滑らかに
距離のfloat値をシリアルに書き出してArduino IDEのシリアルプロッタで見てみると、出力がバラついた感じになったので、以前にスマホの加速度センサーの値を整えるのに使ったローパスフィルターの式を入れて滑らかにしてみました。
出力値 = a * 前回の出力値 + (1-a) * センサの値
※ aは係数で0.8~0.95とかを指定します。小さいほど反応が良くなり、大きいほど滑らかになります。相反します。
グラフ1枚めがローパスフィルター無し、2枚めがローパスフィルター有りです。滑らかになりましたね。
ソースコード
スケッチは以下です。
int Echo = 14; // Echoピン
int Trig = 15; // Trigピン
float dstCMb = 0; // 一回前の距離値
void setup() {
// シリアル通信を開始
Serial.begin(115200);
Serial.println("Serial start.");
// ピン設定
pinMode(Trig, OUTPUT);
pinMode(Echo, INPUT);
}
void loop() {
// trigger
digitalWrite(Trig, HIGH);
delay(20); // msec
digitalWrite(Trig, LOW);
// echo
int intervalUS = pulseIn(Echo, HIGH) / 2; // 超音波の往復の時間を2で割って片道の時間(単位:μsec)にする
// 時間を距離に変換
float dstM = (float)intervalUS * 340.0 / 1000.0 / 1000.0; // センサー出力の値(単位:m) 音速:340m/s(15℃)
float dstCMs = dstM * 100.0; // センサー出力の値(単位:cm)
float dstCM;
// ローパスフィルターで滑らかにする / 外れ値を除外する
if (dstCMs <= 300.0) { // 3mを超えたら外れ値とする
dstCM = 0.95 * dstCMb + 0.05 * dstCMs; // ローパスフィルター適用
dstCMb = dstCM; // 前回値の保存
Serial.println(dstCM); // 距離を出力(単位:cm)
}else{
Serial.println(dstCMb); // 外れ値の場合は前回値を出力
}
}
参考URL
ESP8266 (ESP-WROOM-02) で距離センサー(HC-SR04)を使う (温度センサーを併用して)
http://qiita.com/exabugs/items/088f3f9229674be9e436
センサの入力などに使うディジタルフィルタ
http://ehbtj.com/electronics/sensor-digital-filter/
※とっても参考になりました。ありがとうございました。