はじめに
この記事は、以前、「flutter_blue_plus を使った Flutterアプリ」や「Web Bluetooth API を使ったブラウザで動く Webアプリ」では気にすることなく実装できていた、「mico:bit からの BLE UART の受信処理」に関する話です。
上記の受信処理を「M5Stack(NimBLE-Arduino)」で実装しようとした時に、当初はまったポイントがあったので、それに関するメモを残すために記事を書きました。それと合わせて、自分が詳細を把握できてなかった技術的な部分のメモも書いておきます。
過去にやっていた内容とその記事
ちなみに、過去に flutter_blue_plus・Web Bluetooth API を使ってやっていたことは、以下のように Qiita の記事に書いていたりします。
- Web Bluetooth API の事例
- flutter_blue_plus の事例
上記のいずれも、micro:bit が送信側となって BLE でデータを送り、それを Flutterアプリや、ブラウザ上の Webアプリで受ける、ということをやっています。
今回の結論
今回の話の結論を先に書きます。
M5Stack(NimBLE-Arduino)での実装で、うまくデータを受信できていなかった話は、「CCCD(Client Characteristic Configuration Descriptor)」や、「Notify(通知)」「Indicate(確認付き通知)」というものに関わる内容のようでした。
ここで出てくる Notify・Indicate は、BLE の GATT に関連するもののようです。データ受信の処理に種類があって、それらを区別する必要があるようなのですが、自分はこれを認識できていませんでした。M5Stack での NimBLE-Arduino を使った BLE UART の受信処理において、「Notify を使うか Indicate を使うか」を設定してやる必要があるようです。
micro:bit の BLE UART での Tx の仕様
micro:bit の BLE UART での Tx の仕様をあらためて見てみると、以下のようになっていました。上で出てきた内容に関するところを見ると、受信側の処理で扱うべきなのは Notify ではなく Indicate のほうになるようです。
●Bluetooth Developer Studio - Profile Report
https://lancaster-university.github.io/microbit-docs/resources/bluetooth/bluetooth_profile.html
当初、自分がこれを受信する処理を書いた時に、M5Stack側で Notify での受信処理を実装しようとしていたため、micro:bit が送っているデータを M5Stack で受信できない状態になっていました。
NimBLE-Arduino での実装
NimBLE-Arduino での実装について、関連する仕様の情報などを見てます。
●NimBLE-Arduino: NimBLERemoteCharacteristic Class Reference
https://h2zero.github.io/NimBLE-Arduino/class_nim_b_l_e_remote_characteristic.html
上記を見ると、CCCD の値を直接扱うことなく Notify・Indicate の処理を扱えるようです。もう少し書くと、赤い下線の部分の処理で Notify・Indicate を扱えるかを判定でき、緑の下線の部分の処理で Notify・Indicate のどちらを使うかなどの指定ができるようです。
今回の micro:bit の BLE UART を受信する処理を書く際には、Indicate のほうになるよう subscribe(false, 。。。, 。。。);
を使った内容にする必要があるようでした。
CCCD の直接の指定と機能の有効化
ちなみに、CCCD を直接指定するような場合での、CCCD と機能の有効化の関係は以下になるようです。
- 0x0001: Notification
- 0x0002: Indication
- 0x0003: Notification・Indication の両方が有効
今回の NimBLE-Arduino を使った処理では、上記の内容は、NimBLE-Arduino での内部処理に隠蔽された状態になっているようです。
過去のお試しの話
今回、自分がはまったポイントになっている Notify・Indicate の話は、過去の Flutterアプリ(flutter_blue_plus)・Webアプリ(Web Bluetooth API)のお試しの時には気にすることなく進められていました。
これをあらためて調べてみたところ、flutter_blue_plus や Web Bluetooth API での標準の API を使っていれば、Notify・Indicate を自分で指定してなくても、API側でそれらをうまく使い分けてくれる挙動になるようでした。
【追記】 その後の試作
その後、mico:bit で BLE UART を使って送った文字列を、M5Stack で受信できました。