MicroPython版BLEライブラリでPeripheralを書いてみた。スマフォから接続すると瞬間に切れる。。なぜだろう。。
(ソース抜粋)
#//Service 03B80E5A-EDE8-4B33-A751-6CE34EC4C700 #//Characteristic 7772E5DB-3868-4112-A1A9-F2669D106BF3 MIDI_SRV_UUID = bluetooth.UUID('03B80E5A-EDE8-4B33-A751-6CE34EC4C700') MIDI_CHR_UUID = bluetooth.UUID('7772E5DB-3868-4112-A1A9-F2669D106BF3') payload = advertising_payload( #name="BLE MIDI 0.01", #services=[bluetooth.UUID(0x181A)], services=[MIDI_SRV_UUID], ) BLE_MIDI_CHR = (MIDI_CHR_UUID, bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY) BLE_MIDI_SERVICE = (MIDI_SRV_UUID, (BLE_MIDI_CHR,)) SERVICES = (BLE_MIDI_SERVICE, ) bt = bluetooth.BLE() bt.irq(bt_irq) bt.active(1) ((midi,),) = bt.gatts_register_services(SERVICES) bt.gap_advertise(100,adv_data=payload) print(payload) print(decode_name(payload)) print(decode_services(payload))
実行結果
GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=7 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0 bytearray(b'\x02\x01\x06\x11\x07\x00\xc7\xc4N\xe3lQ\xa73K\xe8\xedZ\x0e\xb8\x03') [UUID128('03b80e5a-ede8-4b33-a751-6ce34ec4c700')] >>> --- BT IRQ --- 1 _IRQ_CENTRAL_CONNECT (0, 1, b'K\xea)\x95Fg') stop advertise --- BT IRQ --- 2 _IRQ_CENTRAL_DISCONNECT (0, 1, b'K\xea)\x95Fg') GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=7 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0 --- BT IRQ ---
一度接続できるが、すぐに切れる。多分、Client側で異常と判断して切りに来ている。。先人の動くサンプルをベースに修正しないと、手探りで作っても動かないと思われる。。
サンプルの ble_temperature.pyを動かしてみたけど、やはり、接続>切断となる。だから、、Pythonプログラムの問題ではなく、BLEライブラリ側がおかしいのでは?と無責任に推測*1*2。
GAP procedure initiated: stop advertising. GAP procedure initiated: stop advertising. GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=7 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=800 adv_itvl_max=800 IRQ Central Connect IRQ Central Disconnect GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=7 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=800 adv_itvl_max=800
使ったのは以下の通り、2020/9/02ビルドのVer1.13 ( esp32-idf4-20200902-v1.13.bin)
>>> uos.uname() (sysname='esp32', nodename='esp32', release='1.13.0', version='v1.13 on 2020-09-02', machine='ESP32 module with ESP32')
問題切り分けのため、ファームバージョンをV1.12にさげてみる。
esp32-idf4-20191220-v1.12.binを使って再度テスト実施
ble_temperature.pyを動かすと、V1.12でもやはり接続後すぐに切れる。なぜか?? 昔動かした時はすんなり動いた記憶があるのだが。
■追記
別のiPhoneだと正常に接続できた。よって異常動作はiPhone依存のようであった。どうもOS側で過去に接続したBLE Peripheralを記憶していて、いろいろ設定を変えるとその設定との不一致が起きるのか、iPhoneが想定する設定と違うせいか、その辺りで、OS側でNGと判断しているようである(推測)。そのように考える根拠として、、Peripheralの名称を変えたのに、BLEスキャナでは、ずっと古い名称が表示されていて、どこかにキャッシュした情報で補完していると推測できる。回避策として、iOSの設定画面から、古いBLE設定を消して再度試すと、BLEの動作が多少安定した。
■追記
iOS上で動くフリーのBLEスキャナは複数使っていて、それぞれ動作が違っていた。一度動き出すと、他のツールも段々と調子が良くなって、最終的にはどのスキャナでも通信が確立してNotifyで送られてくる温度を取れるようになった。推測だけどiPhoneのOS側で過去に通信して得られたPeripheral情報をcacheして補完してそうなのと、直接通信パケットを見れてないので、動作が安定しない根本原因が分からない。
■追記
ふろに入っていて気づいたのだが、、iPhoneのOS側でBLEペリフェラルを覚えていたというのは、BLEのペアリング設定が残ったままで、EPS32側の設定を変えてしまったからでは?と思う。だったら、iOS側は古い情報を期待して接続に来るのに、ESP32側ではサービスUUIDもアトリビュートのUUIDも変わっていたらエラーにするだろうと想像できる。教訓として、、BLEスキャナで古いペリフェラル名が出てきたらiOSでペアリング設定が残っていないかを再確認すべし
■追記
iPhone上で動作するBLEスキャナでは見えるようになったが、iOSの設定>Bluetoothでデバイスが表示されない。なぜだろうか?? アドバタイズのオプションがまずいのか?
GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=7 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=800 adv_itvl_max=800
■ご参考記事
キャッシュしているという記事(ただしデバイス名だけ)
BLE機器のデバイス名を変更してもiOSから見えるデバイス名が変わらない - Qiita
ble-midi/Apple-Bluetooth-Low-Energy-MIDI-Specification.pdf at master · skratchdot/ble-midi · GitHub