LoginSignup
20
24

More than 5 years have passed since last update.

ESP8266 (ESP-WROOM-02) で距離センサー(HC-SR04)を使う (温度センサーを併用して)

Last updated at Posted at 2016-01-17

概要

ESP8266 (以下、WROOM02) で距離センサーを使う。(音速は気温に影響を受けるので、温度センサーも併用して。)

はじめに

Arduino で距離センサーを使う場合、以下の素晴らしい記事が、大変参考になりました。
Arduino編 その8 距離センサーを使ってみる

これを WROOM02 でやろう、という内容です。

元記事と違う部分は

  • 距離センサーそのものは 5V 駆動なので、WROOM02 の 3.3V でも動作するように回路を修正。
  • 温度センサーを併用して、音速を補正し、距離を正確に求める。

です。

部品調達

距離センサー

Amazon で 1個 200円 ( Amazon HC-SR04 ) で売ってたので、4個 800円 で大人買いしたら、5個 買えば 780円だったことに後から気づき Orz..
(中国からの輸送なので、変更手続きとかできないと言われた。)

それでも、10日くらいで、無事に 4個 届きました。
IMG_2396.JPG

抵抗アレイ

プルアップ(プルダウン)を何箇所もやるのかったるいなぁとおもっていたら、千石の地下1階の突き当りで、「抵抗アレイ」なるものを見つけました。
これは便利!ブレボーに最適!とおもって 10K をまとめ買いしようと思ったら、10K だけ売り切れ Orz.. それに近しいやつを購入してお茶を濁しました。(1個 (8抵抗) 10円)
IMG_2397.JPG

回路図

さて、部品もそろったところで。

今回の回路ですが、

  • WROOM02 でセンサーを使う場合は、ESP8266 (ESP-WROOM-02) でセンサーを扱う を参照してください。
  • 今回は A/D 変換の必要なセンサーは 1個 ですが、使い慣れた 8ch 10bit の A/Dコンバータを使っています。
    • A/Dが必要なセンサーが1個なら、TOUT 端子を使うのがもっとも部品数が少ないと思いますが、評判が怪しいのでやめてます。
    • 余談ですが、A/Dコンバータの ch1〜ch7 は使わないので、GNDに落としますが、ここで先程の抵抗アレイを使うと気持ちいいです。
  • 距離センサーからの出力 (ECHO 端子) は 5V です。これを直接 WROOM02 に入力すると大変なこと (実は、リセットがかかるだけ)になるので、気をつけて下さい。 5V を 3.3V にするには、同じ大きさの抵抗 3個を直列に繋いで、1/3 降圧したところで信号を取り出せばいいです。
    • 3.3 は、よく考えられた数字だということを発見!。
    • もし 上限 1V の端子 (例えば TOUT 端子) に入力したい場合は、3.3V をさらに、同じ大きさの抵抗 3個を直列に繋いで、分圧 (2/3 降圧) すればよい。
  • TRIG 端子は「負論理端子(その端子を0Vにするとアクティブになる)」なので、電圧の考慮は特に要りませんでした。

今回の回路図は以下になります。
distance.png

Eagleプロジェクトの一式は Githubにアップロードしておきます。

スケッチ

スケッチは以下になります。

  • 温度センサーによって特性が異なるので、実際の部屋の気温をもとに、Tref の値をずらして、値を校正してください。
  • 一般的な温度センサーは 1℃ で 10mv 変動するみたいですね。(詳しくはデータシートを参照して下さい。)
  • 音速は 331.5 + 気温(℃) * 0.61 (m) です。

  • mapという便利関数が Arduino に用意されているようですが、float 版が無いので真似しました。

  • IO16ピンを RST につないでいるので、Deep-Sleepモード ( ESP8266 (ESP-WROOM-02) で消費電力を抑えるには (スリープモードまとめ) ) を使って消費電力を抑えるのも良いと思います。

extern "C"{
#include <spi.h>
#include <spi_register.h>
}

#include <Ticker.h>

Ticker ticker;


const int TRIG = 5;
const int ECHO = 4;

void setup() {
  Serial.begin(115200);
  Serial.println("");

  spi_init(HSPI);

  pinMode(TRIG, OUTPUT);
  pinMode(ECHO, INPUT);

  ticker.attach_ms(1000, timer);
}

void loop() {
}

void timer() {

  float mv0 = check(0);

  // 手持ちの温度センサーに応じて、適当にずらして値を校正する
  float Tref = -35.97; // MCP9700
//float Tref = -114.68; // LM335Z

  // 一般的な温度センサは、10mv/1'C
  float tr = mv0 / 10 + Tref;

  // パルス発射
  digitalWrite(TRIG, HIGH);
  delayMicroseconds(100);
  digitalWrite(TRIG, LOW);

  // 計測
  int interval = pulseIn(ECHO, HIGH);

  // 温度 tr のときの音速 (m)
  float v = 331.5 + tr * 0.61;

  // 2 で割るのは往復の時間が計測されているため
  // 10,000 で割るのは、cm に換算するため
  double distance = interval * v / 2 / 10000; // cm 


  Serial.print(" Temp.:");
  Serial.print(tr);

  Serial.print(interval, DEC);
  Serial.print("\t");
  Serial.print(distance, 2);
  Serial.print("\n");
}

// @see: http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=2719
float fmap(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

float check(int channel) {
  // start bit (1 bit) : 1
  // SGL/DIFF bit (1 bit) : SGL:1
  //  select the input channel (3 bit) : CH0:0, CH1:1
  uint8 cmd = (0b11 << 3) | channel;

  const uint32 COMMAND_LENGTH = 5;
  const uint32 RESPONSE_LENGTH = 12;

  uint32 retval = spi_transaction(HSPI, 0, 0, 0, 0, COMMAND_LENGTH, cmd, RESPONSE_LENGTH, 0);
  retval = retval & 0x3FF; // mask to 10-bit value

  // センサー(A/D変換後)の値をmvに変換
  // ( 0-1023 を 0-3300 (mV) にマッピングする )
  return fmap(retval, 0, 1023, 0, 3300);
}

結果

まず、3cm くらいで小手調べ。
IMG_2394.JPG

適当に連続した10個をサンプリング。

  • Temp. は室内温度。その隣が距離(cm) になります。
 Temp.:24.03177 3.06
 Temp.:24.03153 2.65
 Temp.:24.03177 3.06
 Temp.:24.03177 3.06
 Temp.:24.03151 2.61
 Temp.:24.03178 3.08
 Temp.:24.03178 3.08
 Temp.:24.03176 3.05
 Temp.:24.03178 3.08
 Temp.:24.03177 3.06

次は、50cm。これも適当に抽出した、連続した10回(10秒) です。
± 0.4 % 程度に収まっています。

 Temp.:24.032902    50.23
 Temp.:24.032880    49.85
 Temp.:24.032878    49.81
 Temp.:24.032880    49.85
 Temp.:24.032904    50.26
 Temp.:24.032883    49.90
 Temp.:24.032883    49.90
 Temp.:24.032882    49.88
 Temp.:24.032883    49.90
 Temp.:24.352883    49.93

次は、ずっと伸ばして、1m 30cm。

IMG_2391 2.JPG

かなり、いい線いっています!

 Temp.:24.037469    129.27
 Temp.:24.037469    129.27
 Temp.:24.357491    129.73
 Temp.:24.037466    129.22
 Temp.:24.037540    130.50
 Temp.:24.037467    129.24
 Temp.:24.037541    130.52
 Temp.:24.037466    129.22
 Temp.:24.037467    129.24
 Temp.:24.037494    129.71

HC-SR04 は、データシート上は、2cm から 180cm となっています。
HC-SR04 データシート

限界まで調査したいですが、これ以上は、部屋の片付けが追いつかないので、写真なしで、結果だけお送りします。

上限の200cm (180cm と間違えて 200cm で計測してしまいました。)
しかし、これも問題無いようです。
(気温センサのミスを除くと、200cm で ± 5mm)

 Temp.:23.3811566   199.96
 Temp.:23.3811569   200.01
 Temp.:23.3811567   199.97
 Temp.:23.3811566   199.96
 Temp.:23.0611568   199.88
 Temp.:23.0611591   200.27
 Temp.:23.3811541   199.52
 Temp.:23.3811540   199.51
 Temp.:23.3811596   200.47
 Temp.:23.3811570   200.02
 Temp.:33.0611573   203.49    ← 気温がダメ
 Temp.:23.3811596   200.47
 Temp.:23.3811569   200.01
 Temp.:23.7111620   201.00    ← 気温がダメ
 Temp.:23.3811540   199.51

205cm 。あぁ、そろそろ、だめっぽいです。

 Temp.:22.7411828   204.25
 Temp.:23.0611827   204.35
 Temp.:23.0611854   204.82
 Temp.:23.0611852   204.78
 Temp.:23.0611827   204.35
 Temp.:33.7111831   208.26    ← 気温がダメ
 Temp.:22.7411827   204.24
 Temp.:23.0611878   205.23
 Temp.:23.0611829   204.39
 Temp.:22.7411852   204.67

210cm 。これはもう、ダメですね。力尽きました。

 Temp.:22.7411948   206.32
 Temp.:22.7411899   205.48
 Temp.:22.7411951   206.38
 Temp.:22.7411926   205.94
 Temp.:23.0611953   206.53
 Temp.:22.7411927   205.96
 Temp.:23.0611952   206.51
 Temp.:22.7411925   205.93
 Temp.:23.0611977   206.94
 Temp.:23.0611953   206.53

データシート上は 2cm 〜 180cm ですが、200cm までは精度よくいけるようです。

まとめ

  • 主観ですが、予想してたより随分と精度がいいのでビックリです。
  • 気温の変動は少ないだろうから、直近いくつかの最大と最小(異常値の可能性)を除いた平均を使えば、もっと安定すると思います。
  • 距離センサーを使う場面は、乗り物等での自動ブレーキですかね。
    それなら、200cm でちょうど良い気がします。
  • 個人では、使う場面が思いつきません。。(しかも、4 個も。)
  • Arduino の道を切り開いてくれている先輩方に感謝します。
    自分は後をトレースしているだけで、申し訳ないです。
20
24
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
24