2016-07-10 距離計の校正 (v0.2 - v0.4) > HC-SR04 + GP2Y0A710K > ブレッドボード実装 / 同時測定用コード > HC-SR04で精度を確保するのは難しそう

```txt:動作環境
ESP-WROOM-02 (以下ESP8266)
昇圧回路 (3V -> 5V) (http://akizukidenshi.com/catalog/g/gM-03451/)
距離センサー: HC-SR04 (http://akizukidenshi.com/catalog/g/gM-08762/)
距離センサー: GP2Y0A710K (http://akizukidenshi.com/catalog/g/gI-03157/)
Arduino IDE v1.6.6
```

http://qiita.com/7of9/items/193181bb1a8c7b873aaf
の続き。

ブレッドボード実装をした。


## 回路図
GP2Y0A710Kも接続する時の回路図は以下となる。
FTDIアダプタの接続は省略した。
https://upverter.com/7of9/0440e7247433a89e/160710_ESP8266_HC-SR04_GP2Y0A710K/

## ブレッドボード実装

### 左側面から

右下は電池CR-123A。縦に接続できるように、CR-123AケースとL型ピンヘッダを使って「抜き差しできる」ようにした。
左手前がGP2Y0A710K、左奥がHC-SR04 (FTDIアダプタに隠れている）。

![DSC_0185.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/6e10e831-2984-20e0-2ba8-fe618b6bf558.jpeg)

### 背面から

左手前、電池のL型ピンヘッダが見えている。ピンヘッダのGNDピンをCR-123Aケースに直接半田付けして、プラスピンはケースに赤のリードで接続。

![DSC_0186.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/a816766c-309a-c9ec-8c49-d74a208c6877.jpeg)

### 右側面から

左手前のスイッチはIO0のH/L切替用。ソフトダウンロード時は手前にスイッチさせる。

![DSC_0187.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/7a40138a-e26e-0629-f88d-bd5957b99574.jpeg)

### 上面から

左真ん中にある緑色のものは昇圧回路(3V->5V)。

![DSC_0188.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/647c2dd9-7f23-ddd4-7fdf-23e5e6007177.jpeg)


## 同時測定用コード > 間違ったコード

<font color=red>
(追記 2016/07/11)
以下のコードではkTrigPinをHレベルにした後100msec待機している。待機時間の単位が間違っていて、正しくは10usec以上であった。
</font>

### code

- HC-SR04 : TriggerをHIGH,LOWして、~~Echoが返る時間から距離を計測~~ (2016/07/12訂正: ECHOピンがHレベルになっている幅から距離を計測)
- GP2Y0A710K : AD取込み。1/3抵抗分圧した値を取る。最大1.0V程度になる。

[v0.2 @ github](https://github.com/yasokada/esp8266_160710_HC-SR04_GP2Y0A710K/releases/tag/v0.2)

```c:esp8266_160710_HC-SR04_GP2Y0A710K.ino
#include <ESP8266WiFi.h>

extern "C" {
#include "user_interface.h"
}

/*
 * v0.2 2016 Jul. 10
 *   - add ADC for GP2Y0A710K
 * v0.1 2016 Jul. 09
 *   - calculate distance in [cm]
 *   - receive echo in loop() 
 *   - send trigger in loop()
 *   - set pinMode() at setup()
 */

static const int kTrigPin = 12;
static const int kEchoPin = 13;

void setup() {
  WiFi.disconnect(); // avoid watchdog reset by WiFi thread

  Serial.begin(115200);
  Serial.println("");

  pinMode(kTrigPin, OUTPUT);
  pinMode(kEchoPin, INPUT);
}

void loop() {
  // trigger
  digitalWrite(kTrigPin, HIGH);
  delay(100); // msec
  digitalWrite(kTrigPin, LOW);

  // echo
  int interval_us;
  interval_us = pulseIn(kEchoPin, HIGH) / 2; // 2: round-trip
  
//  Serial.print(interval_us);
//  Serial.print(", ");
  
  float dst_m = (float)interval_us * 340.0 / 1000.0 / 1000.0;
  float dst_cm = dst_m * 100.0;

  uint ADvalue;
  ADvalue = system_adc_read();
  float voltage = ADvalue * 1.0 / 1024;

  Serial.print(dst_cm);
  Serial.print("\t");
  Serial.print(voltage);
  Serial.println();
    
  delay(300); // msec

//  delay(1000); // msec
}
```

### 結果

左がHC-SR04の測定値(距離[cm])、右がGP2Y0A710Kの測定値(1/3分圧した電圧[V])。

```txt:結果
14.62	0.72
17.58	0.70
0.88	0.70
17.58	0.71
17.14	0.70
12.17	0.72
13.87	0.70
18.02	0.72
17.58	0.71
16.35	0.72
13.84	0.70
4.45	0.70
13.84	0.70
1.70	0.71
13.80	0.72
14.65	0.70
2.48	0.70
14.25	0.70
16.69	0.71
14.69	0.70
3.23	0.71
17.58	0.71
12.58	0.72
14.25	0.70
3.33	0.70
13.80	0.72
17.58	0.71
14.69	0.71
14.28	0.69
3.33	0.72
17.58	0.70
12.17	0.72
```

## TODO

上記のブレッドボード実装では前後に移動した時にFTDIアダプタの取り扱いが障害になる。
udpLoggerに測定データを送信することでFTDIアダプタを外す予定。

あとは、HC-SR04とGP2Y0A710K が反射物にきちんと正対するように物理的なテストベンチを作ることだが、狭い日本家屋では簡易的なものしか用意できないだろう。

ブレッドボード実装とユニバーサル基板実装ではノイズの観点から正確さが変わるかもしれない。精度を上げる方法は今後検討するかもしれない。

## code v0.3

udpLoggerへデータ送信するようにした。
これでFTDIアダプタは外すことができる。

[v0.3 @ github](https://github.com/yasokada/esp8266_160710_HC-SR04_GP2Y0A710K/releases/tag/v0.3)

試し測定で以下のグラフが得られた。
左上におかしな点が見られる。
数を増やせば影響は少ないと期待する。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/12a48776-8133-17c5-a197-969d984a31a4.png)

380測定の結果。距離を160cmまで測定した。
結構ノイズが多い。
また、電圧が飽和している。1/3分圧では足りないようだ。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/88db540b-b131-7930-9881-81f4911e60c1.png)

距離を縮めながら測定した場合のそれぞれの測定値が以下。
HC-SR04側の測定値がばらついているため、きれいな関係図が取得できていない。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/3d7f5d91-3986-b733-19f8-ed195a62859b.png)

## code v0.4

### 抵抗分圧の変更

GP2Y0A710K の測定時に飽和する問題に対して、10k + 10k + 10kによる1/3分圧でなく、10k + 10k + 4.7kでの0.19の分圧とした。

### 異常値の除去

[v0.4 @ github](https://github.com/yasokada/esp8266_160710_HC-SR04_GP2Y0A710K/releases/tag/v0.4)

HC-SR04の測定のノイズを減らすようにしてみた。主な処理は以下。

- 25回の測定を行い、上位1/5の位置のデータを使う

25回の測定値を見た時に距離が130cmはありそうなところで、6割り近くに12cmなどの明らかに小さい異常値が見られた。そのため上記の処理とした。

この症状がHC-SR04一般的なことかは分からない。

### 測定結果 > 距離を変えながら測定

測定データは以下となった。
HC-SR04測定に改善が見られた。

ただし、距離が100cm以遠の部分でやはり値の変化が大きい。

GP2Y0710Kの測定値は安定している。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/ab764167-7d23-9f7c-8b8e-b07e311ac53f.png)

HC-SR04のデータとGP2Y0A710Kのデータから作った散布図。
HC-SR04は上記の理由から100cm未満のデータとしている。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/526478dc-8b7e-02bb-eae0-9ede4be57c23.png)

この散布図から「距離-電圧」関係式を作ろうと思ったが、後述の理由からペンディングしている。

### 実測との比較

HC-SR04の測定データに対して、実測と比較してみた。
100cm以遠は測定のばらつきが大きいため100cm未満で確認。

| A:HC-SR04 (cm) | B:実測 (cm) | A/B |
|:-:|:-:|:-:|
| 85.97 | 90 | 0.955 |
| 66.92 | 70 | 0.956 |
| 46.61 | 50 | 0.932 |
| 28.06 | 30 | 0.935 |

実測と比べてHC-SR04の値が小さくでた。
音速を340m/s固定にしている影響もあるかもしれないが、その係数A/Bの値が距離によって異なる。

### 結論

結果としてHC-SR04の測定値を使う場合、以下を実施しないといけないと思う。

- 絶対値校正 (校正係数自体が距離の関数かもしれない)
- 100cm未満のデータに制限する

上記のような処理を行いGP2Y0A710K の関係式に使うよりは、実測しながらGP2Y0A710K 単体測定したデータで関係式を使う方が正確であるように思われる。


## code v0.5

### 同時測定コード > kTrigPin待機時間訂正

kTrigPinをHレベルにした後の待機時間を間違ってmsec単位としていた。usec単位に変更した。

[v0.5 @ github](https://github.com/yasokada/esp8266_160710_HC-SR04_GP2Y0A710K/releases/tag/v0.5)

訂正したコードで25回の測定データを見ると、やはり小さい値がたくさん測定されてしまう。

```
109.65,
10.13,
7.38,
9.18,
5.75,
24.79,
9.32,
5.78,
100.47,
34.82,
8.57,
7.38,
7.41,
7.41,
9.35,
5.75,
7.45,
102.10,
33.22,
9.35,
6.56,
23.97,
10.06,
5.75,
90.54,
```