chakokuのブログ(rev4)

テック・コミック・ごくまれにチャリ

ESP32の ESP-IDFでBLEサンプルをビルドしてみる

Pythonで使えるBLEライブラリでは鍵交換が実装されていないと判断し、ESP32のESP-IDFを使ってBLEのデバイスを試作してみる。いきなり開発は難易度が高すぎるので、正しく動作するはずのサンプル実装をビルドしてみる。
過去の開発事例でいろいろ実装例が紹介されているので、それを使う。Gitで公開されているBLE接続のSP開発事例があり、それを取ってきてビルドしてみる。
ビルドしたBLEサンプル(トランジスタ技術 2017/11月号記事)
GitHub - h-nari/ESP32_bt_speaker: bluetooth speaker using I2S + built in DAC

すると、、ライブラリの仕様が変わったのか、エラーが出ている。
ビルドすると、、

alias get_idf='. ~/tech/uc/esp/esp-idf/export.sh'
get_idf
make

以下のエラーが発生

/home/xxx/lang/c/esp32/test/ESP32_bt_speaker/main/main.c:136:34: error: 'ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE' undeclared (first use in this function); did you mean 'ESP_BT_GENERAL_DISCOVERABLE'?
         esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                  ESP_BT_GENERAL_DISCOVERABLE
/home/xxx/lang/c/esp32/test/ESP32_bt_speaker/main/main.c:136:34: note: each undeclared identifier is reported only once for each function it appears in
/home/xxx/lang/c/esp32/test/ESP32_bt_speaker/main/main.c:136:9: error: too few arguments to function 'esp_bt_gap_set_scan_mode'
         esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);

API仕様書によると、引数は2つで定数が違っているような。。
CLASSIC BLUETOOTH GAP API - ESP32 - — ESP-IDF Programming Guide latest documentation

esp_err_tesp_bt_gap_set_scan_mode(esp_bt_connection_mode_tc_mode, esp_bt_discovery_mode_td_mode)

esp_bt_connection_mode_t.... ESP_BT_CONNECTABLE
esp_bt_discovery_mode_t....ESP_BT_GENERAL_DISCOVERABLE

手パッチして修正

test/ESP32_bt_speaker/main$ diff main_org.c main.c
136c136
<         esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
---
>         esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE,ESP_BT_GENERAL_DISCOVERABLE);

再度ビルドでエラー(型不一致)

/home/xxx/lang/c/esp32/test/ESP32_bt_speaker/main/bt_app_av.c:204:73: error: incompatible type for argument 2 of 'bt_av_notify_evt_handler'
     bt_av_notify_evt_handler(rc->change_ntf.event_id, rc->change_ntf.event_parameter);

ソースが公開された時期と現在のライブラリのバージョンとの不整合が発生しており、修正が大変と判断して、この実装例を用いてビルドするのをあきらめる。

次に、ESP-IDFに同梱されているBLEサンプルをビルドしてみる。
使ったサンプル:esp_hid_device
これはHIDサンプル。GIT上のURLは以下
esp-idf/examples/bluetooth/esp_hid_device at master · espressif/esp-idf · GitHub

同梱サンプルだからビルドは一発で通って、ESP32に焼いてみた。BLE接続できるHIDとして動作して、アドバタイズを始める。Windows10からデバイスを探し出して接続すると、ペアリングが動作して、正しく接続された。以下はWindowsのデバイス管理画面

下の画面はESP32のデバッグ出力

さすがESP-IDFのライブラリだけあって、問題なく一発で接続できる。問題としては、、使いこなすには各種設定パラメータを理解して正しく設定する必要がある。

ESP32のIDF API資料
Bluetooth API - ESP32 - — ESP-IDF Programming Guide latest documentation
説明書もあるので、、この資料とBLEの解説本を読みながら、、GAPとGATTを実装するとWindowsから正しく接続できる俺MIDI Keyboardができるはずなのだが。。

ESP32のESP-IDFでBLEプログラミングのWalkThroughが書かれており、これを読みながら順番に実装していけばできるはず。。多分。
esp-idf/Gatt_Server_Example_Walkthrough.md at c77c4ccf6c43ab09fd89e7c907bf5cf2a3499e3b · espressif/esp-idf · GitHub
https://www.espressif.com/sites/default/files/documentation/esp32_bluetooth_architecture_en.pdf


上記Walkthroughに倣って最小限のソースを書いてみたが、ヘッダの配置とかすでに変わっているようでエラーがでた。ゆえに、、同梱のBLEサンプルをベースにして、必要な機能に書き換える方法でないと無理そうだ。

ClassicBLEは通信せず、BLEだけでよければシンプルなNimBLEを使えと書かれていた。
BLE User Guide — Apache Mynewt latest documentation
BLE Peripheral Project — Apache Mynewt latest documentation