ESP-IDF で iBeacon

はじめに

  • Bluetooth は 2.4 GHz 帯の電波を使用したデジタル機器用の近距離無線通信技術である.
  • BLE (Bluetooth Low Energy) は Bluetooth の一部で,バージョン 4.0 から追加された省電力に特化するために作られた通信形式である.
    • それ以前の規格は Bluetooth Classic と言う・
    • Bluetooth の規格の変遷は例えば wikipedia に詳しい.
  • iBeacon は BLE のサブセット.
    • iBeacon では後述するアドバタイズ機能だけに特化して低コスト (低消費電力など) を追求している.

BLE の基礎

  • BLE では,機器は「親機 (セントラル (Central),マスター(master))」と「子機 (ペリフェラル(Peripheral),スレーブ(slave)」に大別される.
  • BLE では,ペリフェラルが間欠的電波を発信する (ブロードキャスト).その電波をセントラルが発見し,目的のペリフェラルからの信号であれば通信を開始する.
  • 用語:
    • アドバタイズ:ペリフェラルからのブロードキャスト通信.
      • ペリフェラル機器が定期的に情報を送信
    • スキャン:セントラルによるアドバタイズの受信
      • BLE では受信後に,プロファイルを用いた 1 対 1 接続通信が行われる.
    • RSSI:受信電波強度
      • セントラル機器はアドバタイズ信号を受信したとき,受信した電波の強さに関する情報を得ることが出来る.
    • プロファイル:機器の種類ごとに策定されたプロトコル
      • Bluetooth は様々なデバイスでの通信に使用されるため,機器の種類ごとに策定されたプロトコルがあり,それらの使用方法をプロファイル (Profile) と呼び標準化されている.
        • 例) HID (Human Interface Device Profile):マウスやキーボードなどの入力機器を無線化するためのプロファイル。
        • 例) 汎用プロトコル
          • GAP (Generic Access Profile)
          • GATT (Generic ATTribute profile)

iBeacon のアドバタイズデータ

iBeacon のアドバタイズデータには,以下の情報が含まれる.

  • UUID, major, minor:ビーコンの識別
    • UUID (128-bit),Major,Minor で構成された ID 情報を保持.
    • UUID は必須.Major と Minor は任意.
    • 通常の使い方としては,UUID で「サービスやアプリの切り分け」, major で「建物」,minor で「フロア」などと使い分ける.
  • TxPower:ビーコンが発する信号の強さ.単位は dBm.
    • iBeacon の場合は 1m 離れた地点での受信信号強度を利用
  • RSSI (Received Signal Strength Indication):セントラルが順した電波の強度.単位は dBm.

iBeacon で RSSI と TxPower から距離を推定する.

自由空間では受信信号強度は距離の二乗に反比例して減衰していく(フリスの伝達公式)ので, RSSI と TxPower と距離 distance の関係は次のようになる. 但し,実際には障害物の有無などで電波の受信強度は変化する.

RSSI = TxPower - 20 * log( distance )

これを距離の式に直すと (C 言語的に書くと),以下のようになる.

distance = pow(10.0, (TxPower - RSSI) / 20.0)

得られた距離から以下の 3 段階に分けることが普通である.

  • Immediate (非常に近い)
  • Near (近い)
  • Far (遠い)

参考

ESP32 マイコンで iBeacon

2 台のマイコンボードを用意し,ESP-IDF のサンプルを利用する.

$ cd ~/esp

$ cp -r esp-idf/examples/bluetooth/bluedroid/ble/ble_ibeacon ./ble_ibeacon_XXX    
  (ディレクトリ名は送信側・受信側が区別できるように適宜決める)   

サンプルの ESP-IDF iBeacon demo README を読む.idf.py は make で読み替えると,make menuconfig で SENDER か RECEIVER を選ぶ必要があることが分かる.また,1 つの PC に複数台のマイコンボードを接続する場合には,SENDER と RECIEVER でデバイスを切り分ける必要がある (デバイスを /dev/ttyUSB0 と /dev/ttyUSB1 に分ける).この作業を送信側と受信側の両方で行うこと.

$ cd ble_ibeacon_XXX

$ make menuconfig

   > Serial flasher config でデバイス名を選択 (/dev/ttyUSB0 など)
   > iBeacon Example Configuration で SENDER か RECEIVER を選択.

$ make

$ make flash monitor

送信側・受信側の両方で準備が出来れば, サンプルの ESP-IDF iBeacon demo README に書かれているように, 動作確認できるはずである.

サンプルの構造

<URL:https://www.lucadentella.it/site/2018/02/09/esp32-31-ble-gap/> に載っている 模式図 が分かり易いが, メイン関数から esp_ble_gap_set_scan_params で Bluetooth ドライバが呼ばれた後は, Bluetooth のドライバとコールバック関数の間でやり取りが繰り返し行われる.

例えば,スキャンした結果は ESP_GAP_BLE_SCAN_RESULT_EVT として返ってくるので, スキャンした結果を操作したい場合には,main/ibeacon_demo.c の 96 行目からの case 文に命令を追加すれば良い.

96     case ESP_GAP_BLE_SCAN_RESULT_EVT: {
97         esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param;
...
...    (以下略)

アドバタイズデータの調整

main/esp_ibeacon_api.h の 44-45 行目に uuid, major, minor が設定されている.

44 #define ESP_UUID    {0xFD, 0xA5, 0x06, 0x93, 0xA4, 0xE2, 0x4F, 0xB1, 0xAF, 0xCF, 0xC6, 0xEB, 0x07, 0x64, 0x78, 0x25}
45 #define ESP_MAJOR   10167
46 #define ESP_MINOR   61958

設置された uuid, major, minor は main/esp_ibeacon_api.c の 41-47 行目で構造体 vendor_config に保管され使われている.

41 /* Vendor part of iBeacon data*/
42 esp_ble_ibeacon_vendor_t vendor_config = {
43     .proximity_uuid = ESP_UUID,
44     .major = ENDIAN_CHANGE_U16(ESP_MAJOR), //Major=ESP_MAJOR
45     .minor = ENDIAN_CHANGE_U16(ESP_MINOR), //Minor=ESP_MINOR
46     .measured_power = 0xC5
47 };

これらを設定しなおすことでアドバタイズデータを調整することができる.

スキャンの調整

デモ (main/ibeacon_demo.c) では無限にスキャンを続けるが,そのスキャンを有限の時間で収めるためには 79 行目の uint32_t duration の値を調整すれば良い.

76     case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: {
77 #if (IBEACON_MODE == IBEACON_RECEIVER)
78         //the unit of the duration is second, 0 means scan permanently
79         uint32_t duration = 0;
80         esp_ble_gap_start_scanning(duration);
81 #endif
82         break;
83     }

デモ (main/ibeacon_demo.c) ではスキャンした全ての iBeacon の情報が表示されるが, これを調整するためには 96-119 行目の ESP_GAP_BLE_SCAN_RESULT_EVT の部分を調整すれば良い. 送信側の UUID, major, minor に対する if 文を書けば良い.

96      case ESP_GAP_BLE_SCAN_RESULT_EVT: {
97          esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param;
98          switch (scan_result->scan_rst.search_evt) {
99          case ESP_GAP_SEARCH_INQ_RES_EVT:
100             /* Search for BLE iBeacon Packet */
101             if (esp_ble_is_ibeacon_packet(scan_result->scan_rst.ble_adv, scan_result->scan_rst.adv_data_len)){
102                 esp_ble_ibeacon_t *ibeacon_data = (esp_ble_ibeacon_t*)(scan_result->scan_rst.ble_adv);
103                 ESP_LOGI(DEMO_TAG, "----------iBeacon Found----------");
104                 esp_log_buffer_hex("IBEACON_DEMO: Device address:", scan_result->scan_rst.bda, ESP_BD_ADDR_LEN );
105                 esp_log_buffer_hex("IBEACON_DEMO: Proximity UUID:", ibeacon_data->ibeacon_vendor.proximity_uuid, ESP_UUID_LEN_128);
106
107                 uint16_t major = ENDIAN_CHANGE_U16(ibeacon_data->ibeacon_vendor.major);
108                 uint16_t minor = ENDIAN_CHANGE_U16(ibeacon_data->ibeacon_vendor.minor);
109                 ESP_LOGI(DEMO_TAG, "Major: 0x%04x (%d)", major, major);
110                 ESP_LOGI(DEMO_TAG, "Minor: 0x%04x (%d)", minor, minor);
111                 ESP_LOGI(DEMO_TAG, "Measured power (RSSI at a 1m distance):%d dbm", ibeacon_data->ibeacon_vendor.measured_power);
112                 ESP_LOGI(DEMO_TAG, "RSSI of packet:%d dbm", scan_result->scan_rst.rssi);
113             }
114             break;
115         default:
116             break;
117         }
118         break;
119     }

より深く理解するために

ESP-IDF のマニュアルを読むのが早道.

課題

  • [1] iBeacon を用いた距離測定を行いなさい.
    • 特定のマイコンボード同士の距離を測ること.uuid, major, minor などのアドバタイズデータから適切な相手を特定せねばならない.
    • 測定した距離を標準出力にリアルタイムに出力できるようにすること.
      • 適切な相手との距離を測定したことを示すため,uuid, major, minor, TxPower, rssi, 距離,の全てを出力すること.
    • 提出物 : プログラムファイル (ibeacon_demo.c) と出力結果のコピペ.但し,教員に結果を見せること.
    • PC の USB ポートが足りない場合は,SENDER のマイコンボードを電池駆動すること.
  • [2] 実際の距離と,iBeacon を用いた距離測定から得られた値を比較検討せよ.その結果を提出せよ.
    • 2 つのマイコンボードを 0.5 m, 1 m,2 m, 3 m と順に離して置き,それぞれの状況において iBeacon を用いた RSSI 計測および距離測定をしてみよ.
    • 得られた結果は Excel などでまとめ,各種統計量の算出や,そのグラフを作成してみよ.→ iBeacon の距離測定精度について議論すること.
    • 提出物 : word などの電子ファイル (Excel などで作成した統計量の図や考察を含むこと).
    • この実験は 2-3 名のグループで行って構わないが,課題の提出は各自が行うこと (同一グループの学生の提出内容は同じになってよい).