超音波センサHC-SR04で測距した値をESP32のBLEで送信する

#機材
機材は下記を使用します。
・[ESP32-DevKitC ESP-WROOM-32開発ボード(秋月電子)](http://akizukidenshi.com/catalog/g/gM-11819/ "") 1,480円(税込み)
・[超音波センサHC-SR04](https://ja.aliexpress.com/item/HC-SR04P-HC-SR04-Ultrasonic-Ranging-Module-Ranging-Sensor-Module-3-5-5V-Wide-Voltage-Performance/32666978730.html?spm=a2g11.search0104.3.1.7f755248anmAps&ws_ab_test=searchweb0_0,searchweb201602_2_10152_10151_10065_10344_10068_5722815_10342_10325_10343_10546_10340_5722915_10548_10341_10698_5722615_10696_10084_10083_10618_10307_5722715_5711215_10059_308_100031_10103_10624_10623_10622_5711315_5722515_10621_10620,searchweb201603_25,ppcSwitch_5&algo_expid=a053acf1-e9f2-4fdf-9c37-b65c1e26527f-0&algo_pvid=a053acf1-e9f2-4fdf-9c37-b65c1e26527f&priceBeautifyAB=0 "")(AliExpressで95円程度。送料無料)
・ブレッドボード
・ジャンプワイヤケーブル

回路は簡単で、Vcc、GND、Trig、Echoの4線のみの結線です。

![ESP32_HC-SR04_fritzing.png](https://qiita-image-store.s3.amazonaws.com/0/148362/ad6be34d-cfc0-114b-927c-c6c50399ed2d.png)


#超音波センサHC-SR04の測距
サンプルコードがwebに多々あるので参考にさせて頂き実装します。
今回は最終的には小数点以下の値までの精度を求めません。1cm単位の精度で十分です。平均・平滑化などは別途考えます。

#BLEでHC-SR04で測距した値を送信する
ESP32 BLEライブラリをArduino IDEにインポート済みなのでスケッチ例に「ESP32 BLE Arduino」というグループができています。今回はBLE_notifyを使用します。
ソースコードを見るとほぼ無修正で利用できることがわかります。

```
void loop() {
    // notify changed value
    if (deviceConnected) {
        pCharacteristic->setValue(&value, 1);
        pCharacteristic->notify();
        value++;
        delay(10); // bluetooth stack will go into congestion, if too many packets are sent
    }
```
HC-SR04で測距した値をvalueに代入し、setValue()でvalueのアドレスとサイズを設定するようです。valueの型はunit8_tなので、測距した値が255cmを超える場合もあるので2バイト使用することにします。
後述のGATTのCharacteristics IDのheightのフォーマットがunit16なのでこれにも合わせます。

HC-SR04で測距する関数measureDistance()で得られた値distをbuffに格納し、setValue()で設定します。

```
void loop() {

    delay(1000);
    double dist;
    uint8_t buff[2];
    // notify changed value
    if (deviceConnected) {

        dist = measureDistance();
        Serial.print("dist= ");
        Serial.println(dist);

        buff[0] = (int16_t)dist & 0xff;
        buff[1] = (int16_t)dist >> 8;
        
        pCharacteristic->setValue(buff, sizeof(buff));
        pCharacteristic->notify();

        delay(10); // bluetooth stack will go into congestion, if too many packets are sent
    }
```

#BLEのservice IDと characteristics ID
スケッチ例のBLE_notifyではservice IDと characteristics IDは下記のように定義されています。

```
#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
```

これではUnknown serviceとUnknow Characteristicsになってしまいます。HC-SR04で測距するので、これに適したServiceとCharacteristics IDを設定します。
[Bluetooth](https://www.bluetooth.com/ "")の仕様は公式ページの[Specificationのページ](https://www.bluetooth.com/specifications/gatt "")で確認することができます。

##Service ID
ちょっと無理がありますが[Service ID](https://www.bluetooth.com/specifications/gatt/services "")は[0x181AのEnvironmental Sensing](https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.environmental_sensing.xml "")にします。

##Characteristics ID
[Characteristics ID](https://www.bluetooth.com/specifications/gatt/characteristics "")はDistanceがなかったので[Elevation](https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.elevation.xml "")と[Height](https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.height.xml "")が近かったのでHeight(0x2A8E)を使用することにします。ソースを下記のように修正します。

```
　#define SERVICE_UUID        "0000181a-0000-1000-8000-00805f9b34fb" // org.bluetooth.service.environmental_sensing 
　#define CHARACTERISTIC_UUID "00002a8e-0000-1000-8000-00805f9b34fb" // org.bluetooth.characteristic.height
```
この設定でコンパイル・ビルド、ESP32に書き込みます。

#Androidアプリでの確認
セントラル側のアプリがまだ出来ていないのでAndroidアプリで確認します。
今回はNORDICのnRF Connectを使用します。

![nRF BLE scanner.png](https://qiita-image-store.s3.amazonaws.com/0/148362/71515ff0-35fc-d6e3-cd9d-66003d60dcb2.png)

先ほど設定したService IDのEnvironmental Sensing, Characteristics IDのHeightでValue(ここでは130cm)が取れていることがわかります。

#ソースコード
サンプルコードにちょっと手を加えたものだけど、[github](https://github.com/mgr206/esp32_HC-SR04 "")にあげておきます。
(2019/3/18追記)