Arduinoで超音波センサHC-SR04を使う

##超音波センサとは
超音波を発射し、何らかの物体にぶつかって跳ね返って来た反射波を受信する。そして発射してから受信するまでの時間を計測することでセンサと物体の距離を測ることができる。
（海底の地図を作成したり、漁の時の魚群探知にも使われるそう）


##材料

--[超音波距離センサー　ＨＣ－ＳＲ０４](https://akizukidenshi.com/catalog/g/gM-11009/)
基本の距離測定の処理をするためのモジュール。必要なものが全て詰まっているので、ブレッドボードに直接挿して使えるという優れもの。

--[ArduinoUno](https://akizukidenshi.com/catalog/g/gM-07385/)
マイコンボード。　

--[ジャンパーワイヤー](https://akizukidenshi.com/catalog/g/gC-05159/)

--[ブレッドボード](https://akizukidenshi.com/catalog/g/gP-00313/)


##接続

・VCC　　5Vの電力を供給する電源
・Trig　　トリガーの入力ピン(2)
・Echo　　レシーバー出力ピン(3)
・GND　　グランド。マイナス

![sonic_ブレッドボード2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617418/c2972ada-0052-8d5d-de3a-a9c3f3be0b4d.jpeg)


##プログラム

###まずピンを定義・初期設定

```c
const int trigPin = 2;
const int echoPin = 3;

double duration = 0;
double distance = 0;

void setup() {
Serial.begin( 9600 );
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {

}
```
往復して音波が帰ってくるまでの時間をtime,そこから計算する物体との距離をdurationとおく。
シリアルモニタに距離を表示させたいのでSerial.begin

trigPinは超音波を発射させる引き金のような役割  => output
echoPinは超音波を受信する役割  => input



###モジュールを動かす

ここで使うのが**pulseIn()**関数
パルス（電流の流れた間隔)を返す。
たとえば　
pulseIn(2, HIGH);であれば2のピンがHIGHになった瞬間からLOWになるまでの時間を返す。
(公式リファレンス　[pulseIn関数](https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/))


この関数を使ってechoPinが音波をうけとるまでの時間を計測できる。

```c
void loop() {
  digitalWrite(trigPin, LOW); #両方のピンをLOWに指定して初期化
  digitalWrite(echoPin, LOW);
  delayMicroseconds(1);
  digitalWrite(trigPin, HIGH); #超音波パルスを発射
  delayMicroseconds(10); #10us続ける(最低でも10usだそう)
  digitalWrite(trigPin, LOW); #発射停止
  duration = pulseIn(echoPin, HIGH); #超音波が跳ね返ってくるまでの時間
}
```

###距離を計算する
このままだと音波が返ってくるまでの時間しかわからないので、わかりやすい単位、長さ(cm)に変換したい。

>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データシート](https://akizukidenshi.com/download/ds/sainsmar/hc-sr04_ultrasonic_module_user_guidejohn_b.pdf)から引用

**echoPinがHIGHになっている時間(duration) × 音波の速度(音速の 340m/秒) ÷ 2**
この式で距離が測れる。なぜ2で割るのかというと、音波を発射して返ってきた時、音波は物体間の距離の2倍動いているから。

####!単位を揃えよう
durationの値はμs（μは10の-6乗, 0.000001)
1μs = 0.000001s
また、単位はcmにしたいので 340m = 34000cm

式は　duration × 0.000001 × 34000 ÷ 2

```c
void loop() {
///省略
  duration = duration * 0.000001 * 3400 / 2
  Serial.println(duration);
  Serial.println(" cmです");
}
```
###コード全部
```c
const int trigPin = 2;
const int echoPin = 3;

double duration = 0;
double distance = 0;

void setup() {
  Serial.begin( 9600 );
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}
void loop() {
  digitalWrite(trigPin, LOW);
  digitalWrite(echoPin, LOW);
  delayMicroseconds(1);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);   
  duration = duration * 0.000001 * 34000 / 2;
  Serial.print("距離は");
  Serial.print(duration);
  Serial.println(" cmです");
}
```
###動作確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617418/bd3bbb9a-cd3c-f2a1-84ed-284f3372b2c1.png)

 

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">物体間の距離10cmの時<br>シリアルモニタの表示　⇩ <a href="https://t.co/cA6cs26sOy">pic.twitter.com/cA6cs26sOy</a></p>&mdash; choco#JCプログラマー (@choco_JC_prog) <a href="https://twitter.com/choco_JC_prog/status/1344564362799849473?ref_src=twsrc%5Etfw">December 31, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

誤差は2mmほど、障害物探知には問題なさそう。
正確な計測のために、温度センサ・赤外線センサも今後使っていきたい。