機材
機材は下記を使用します。
・ESP32-DevKitC ESP-WROOM-32開発ボード(秋月電子) 1,480円(税込み)
・超音波センサHC-SR04(AliExpressで95円程度。送料無料)
・ブレッドボード
・ジャンプワイヤケーブル
回路は簡単で、Vcc、GND、Trig、Echoの4線のみの結線です。
超音波センサ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の仕様は公式ページのSpecificationのページで確認することができます。
Service ID
ちょっと無理がありますがService IDは0x181AのEnvironmental Sensingにします。
Characteristics ID
Characteristics IDはDistanceがなかったのでElevationとHeightが近かったので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を使用します。
先ほど設定したService IDのEnvironmental Sensing, Characteristics IDのHeightでValue(ここでは130cm)が取れていることがわかります。
ソースコード
サンプルコードにちょっと手を加えたものだけど、githubにあげておきます。
(2019/3/18追記)