FireBeetleを使ってビーコンと通信してみた

今回は省電力のFireBeetleを使用してビーコンとの通信を行っていました。
![IMG20220428164915.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/994c9d6e-2075-cdb6-ac98-69518e7859d0.jpeg)

## ピンアサイン
ピンアサインは以下のサイトを参照
https://www.mouser.jp/new/dfrobot/dfrobot-dfr0654-firebeetle/
#### なおピン番号0を使用するとバグりますので要注意！

## FireBeetleをArduinoにインストールする
1、ファイル＞環境設定　から「追加のボードマネージャのURL」に以下のURLを追加します。
http://download.dfrobot.top/FireBeetle/package_esp32_index.json

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/7c31ca0a-9403-9f4a-ba77-3362718e7722.png)


2、ツール＞ボード＞ボードマネージャ　で「FireBeetle」で検索し「FireBeetle-ESP32」をインストール。
![コメント 2021-10-28 101517.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/66495857-2dcd-0128-f401-a7e507312ef0.png)

これでインストールは完了です。


## ドライバインストール
ボードマネージャでインストールしたので自動認識されるかと思ったのですが、
されなかったのでドライバを手動でインストールしました。

1、https://wiki.dfrobot.com/FireBeetle_Board_ESP32_E_SKU_DFR0654#target_11
　　からドライバをダウンロード
![コメント 2021-10-28 112421.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/cc3d99b5-0a45-6c42-8c2a-3f3ed2d58c8f.png)

2、ダウンロードしたファイルを起動し、インストール開始。
![コメント 2021-10-28 112535.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/bcfcd115-e6a9-4116-47af-1ce6e961c1ab.png)

3、デバイスマネージャーで確認。無事認識されているようです。
![コメント 2021-10-28 113548.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/5427e9b4-92b4-5078-2670-b97ada6975fb.png)

## BLE用のライブラリをインストール
BLE通信をするにあたってはライブラリをインストールする必要があります。
![コメント 2021-10-29 093206.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/b0eb69d0-4029-f977-3c97-9c63d077a4e7.png)

## プログラムをインストール
ソースコードは以下。
今回はビーコンの情報を読み取って、PCにシリアル通信で送信するプログラムを作成しています。

```c
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>

class IBeaconAdvertised: public BLEAdvertisedDeviceCallbacks {
  public:
    // BLE検出時のコールバック
    void onResult(BLEAdvertisedDevice device) {
      if (!isIBeacon(device)) {
        return;
      }
      printIBeacon(device);
    }

  private:
    // iBeaconパケット判定
    bool isIBeacon(BLEAdvertisedDevice device) {
      if (device.getManufacturerData().length() < 25) {
        return false;
      }
      if (getCompanyId(device) != 0x004C) {
        return false;
      }
      if (getIBeaconHeader(device) != 0x1502) {
        return false;
      }
      return true;
    }

    // CompanyId取得
    unsigned short getCompanyId(BLEAdvertisedDevice device) {
      const unsigned short* pCompanyId = (const unsigned short*)&device
                                         .getManufacturerData()
                                         .c_str()[0];
      return *pCompanyId;
    }

    // iBeacon Header取得
    unsigned short getIBeaconHeader(BLEAdvertisedDevice device) {
      const unsigned short* pHeader = (const unsigned short*)&device
                                      .getManufacturerData()
                                      .c_str()[2];
      return *pHeader;
    }

    // UUID取得
    String getUuid(BLEAdvertisedDevice device) {
      const char* pUuid = &device.getManufacturerData().c_str()[4];
      char uuid[64] = {0};
      sprintf(
        uuid,
        "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
        pUuid[0], pUuid[1], pUuid[2], pUuid[3], pUuid[4], pUuid[5], pUuid[6], pUuid[7],
        pUuid[8], pUuid[9], pUuid[10], pUuid[11], pUuid[12], pUuid[13], pUuid[14], pUuid[15]
      );
      return String(uuid);
    }

    // TxPower取得
    signed char getTxPower(BLEAdvertisedDevice device) {
      const signed char* pTxPower = (const signed char*)&device
                                    .getManufacturerData()
                                    .c_str()[24];
      return *pTxPower;
    }

    // iBeaconの情報をシリアル出力
    void printIBeacon(BLEAdvertisedDevice device) {
      Serial.printf("addr:%s rssi:%d uuid:%s power:%d\r\n",
                    device.getAddress().toString().c_str(),
                    device.getRSSI(),
                    getUuid(device).c_str(),
                    *(signed char*)&device.getManufacturerData().c_str()[24]);
    }
};

void setup() {
  Serial.begin(115200);
  BLEDevice::init("");
}

void loop() {
  Serial.println("start.");
  BLEScan* scan = BLEDevice::getScan();
  scan->setAdvertisedDeviceCallbacks(new IBeaconAdvertised(), true);
  scan->setActiveScan(true);
  scan->start(60);
  Serial.println("complete.");
  delay(1000);
}
```


書き込み設定は以下。
![コメント 2021-10-28 114220.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/428593c3-5031-0b90-f417-d0b839e52fb7.png)

これでシリアルモニタを確認すると取得したデータが表示されます。