これはmbed Advent Calendar 2015の19日目の記事です。
@tw_hoehoe さんが、BLE何台接続できるのって話題にして頂いたのでそれをネタに書きます。(話題提供ありがとうございます。
ペリフェラルの作製
確認のためのペリフェラルをNanoで作ります。
- 接続確認(Connection)のLEDをP0_4(接続すると点灯、切断すると消灯)
- 制御確認のLEDをP0_5(0x00を送ると消灯、0x01を送ると点灯)
に接続するように考えます。
RedBearLabから提供されているBLENano_SimpleControlsを元に作成します。
今回はBLENano_Peripheralという名前で、最新のライブラリでImportします。
mbed BLEライブラリは、コロコロ変わるので、お決まりの通り、そのままでは、エラーが出ました。
まずは、こいつ
Error: No instance of overloaded function "BLE::onDisconnection" matches the argument list in "main.cpp", Line: 191, Col: 10
この2行が怪しい。。
void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) ble.onDisconnection(disconnectionCallback);
ble.onDisconnectionの定義はBLE.hを見ると
template<typename T>
void onDisconnection(T *tptr, void (T::*mptr)(const Gap::DisconnectionCallbackParams_t*)) {
gap().onDisconnection(tptr, mptr);
}
なので
void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
を
void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *param)
に書き換える。そうするとコンパイルがSucces!!になる。
その次、iPhoneのLightBlueでみると名前がおかしい
これは、
ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t *)"Biscuit", sizeof("Biscuit") - 1);
を
ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME,(const uint8_t *)"Biscuit", sizeof("Biscuit") - 1);
に修正すると、きちんと表示される。
あとは、こっちの思うようにファイルを削除したりコードを変更します。
Servo.cpp、Servo.hは不要なので削除。
上手く動作した。出来たのでたくさん作る。
きちんと見えました。(最初[接続前]は、以前使った名前が表示された<汗>。LightBlueがキャッシュしているのかなあ)。ほぼ同じ位置でも信号強度が違うなあ。。
パブリッシュしておきます。
https://developer.mbed.org/users/yueee_yt/code/BLENano_Peripheral/
Centralの作製
Nanoはすべて使ったので同等のRedBear nRF51822を使ってCentralを作成します。
プログラムはBluetooth Low EnergyのBLE_ButtonSenseから作成します。
まず、インポートします。
コンパイルして、例のごとくエラーを出します。
まず、
Error: Class "DiscoveredCharacteristic" has no member "getShortUUID" in "main.cpp", Line: 61, Col: 73
characteristicP->getShortUUID()
は、characteristicP->getUUID().getShortUUID()
に変更。
次のエラー
Error: No instance of overloaded function "Gap::onDisconnection" matches the argument list in "main.cpp", Line: 100, Col: 16
はペリフェラルと一緒なので
void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
を
void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *param)
に置き換える。
これでサンプルは正常にコンパイル出来た。(プログラムが正常とは言っていない。。)
アバタイズのデータを見る
アバタイズのコールバック関数の上3行と下1行ををコメントにしてみる。
void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) {
//if (params->peerAddr[0] != 0x29) { /* !ALERT! Update this filter to suit your device. */
// return;
//}
printf("adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n",
params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],
params->rssi, params->isScanResponse, params->type);
//ble.gap().connect(params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL);
}
- d4 e2 88 34 72 3b
- e1 ec dd a7 de 5c
- de c0 a5 21 5a f5
- d0 1b 65 dc 15 e0
- dd 66 2f 18 c6 01
以下のようなプログラムを作成し、実行しました。
Mode | 動作内容 |
---|---|
1 | Peripheral 1 に接続中 |
2 | Peripheral 1 に接続済み/サービス接続中 |
3 | Peripheral 1 のWriteサービス接続済み |
4 | Peripheral 1 のCharactristics/サービス検索終了 |
11 | Peripheral 2 に接続中 |
12 | Peripheral 2 に接続済み/サービス接続中 |
13 | Peripheral 2 のサービス接続済み |
14 | Peripheral 2 のCharactristics/サービス検索終了 |
21 | Peripheral 3 に接続中 |
22 | Peripheral 3 に接続済み/サービス接続中 |
23 | Peripheral 3 のサービス接続済み |
24 | Peripheral 3 のCharactristics/サービス検索終了 |
31 | Peripheral 4 に接続中 |
32 | Peripheral 4 に接続済み/サービス接続中 |
33 | Peripheral 4 のサービス接続済み |
34 | Peripheral 4 のCharactristics/サービス検索終了 |
41 | Peripheral 5 に接続中 |
42 | Peripheral 5 に接続済み/サービス接続中 |
43 | Peripheral 5 のサービス接続済み |
44 | Peripheral 5 のCharactristics/サービス検索終了 |
結果は1台だけ接続可能でした。。(無応答で終了)
あれ、前は出来たぞっということで、BLE Nanoで再確認。。
3台つながったところでError 7、、、
7って何?って調べると
BLE_ERROR_NO_MEM = 7, /**< Out of memory */
メモリ不足。。。。
参考までにプログラムはパブリッシュしておきますね。
https://developer.mbed.org/users/yueee_yt/code/BLE_Central/
まとめ
RedBearLab nRF51822 V1.0多分16kB は1台
RedBearLab BLE Nano 32kB は3台
で、理由はなんとなく判りますよね。。
PS.実用的なのは1台です。。。3台接続はあくまでネタです。。
明日は@toyowataさんです。