Help us understand the problem. What is going on with this article?

ESP32@arduino ideとmicrobitのBLE通信

More than 1 year has passed since last update.

esp32(arduino ide)とmiciro:BitでBLE通信する

esp32 ble ライブラリの修正

前提

Arduino ideとbleライブラリの導入する。
参考:Arduino IDEでESP32 BLEライブラリを導入 - Qiita

ESP32のBLEライブラリの指定アドレスタイプとMicro:bitのアドレスタイプが一致しないのでこのままでは繋がりません。

手順

{Arduinoホームフォルダ}/hardware/espressif/esp32/libraries/BLE/src/BLEClient.cpp
を開き、114行目の
BLE_ADDR_TYPE_PUBLICBLE_ADDR_TYPE_RANDOMに書き換える。

BLEClient.cpp書き換え後
    errRc = ::esp_ble_gattc_open(
        getGattcIf(),
        *getPeerAddress().getNative(), // address
        BLE_ADDR_TYPE_RANDOM,          // Note: This was added on 2018-04-03 when the latest ESP-IDF was detected to have changed the signature.
        1                              // direct connection
    );

(現時点ではアドレスタイプが直書きになっていて変更できないので、Micro:bitのアドレスタイプに合わせて強制的に書き換えてやります。引数とかで指定できるようになるとこの作業は不要になり、この記事も無意味になります。)

microbit側

特殊なことはないです。Bluetoothパッケージを使ってプログラムを作ります。

手順

https://makecode.microbit.org/
にて、
1. 高度なブロックからパッケージの追加、Bluetoothを追加
2. プロジェクトの設定でBluetoothのペアリング方法を「No Pairing Required」にする(*1)
3. お好きなプログラムを作って、microbitに書き込む

作例

基本サービスを使ったプログラム:https://makecode.microbit.org/_DV07965eR8sV

Aボタンを押してる間だけ加速度の値を送るプログラム:https://makecode.microbit.org/27602-21517-86728-91519

参考

micro:bitとWebBluetoothで通信してみました - Qiita


以上で完了です。あとはお好きなプログラムを作って下さい。繋がるはずです。

サンプルプログラム

BLEライブラリの修正で繋がるようになってますが、サンプルプログラムは以下のような感じです。

Micro:bit側

基本サービスを使ったプログラムを書き込んでおきます
https://makecode.microbit.org/_DV07965eR8sV

ESP32側

下記プログラムをArduinoIDEにコピペし、4行目のMACアドレスを自分のMicor:bitのBLEのMACアドレスに書き換えて書き込んでください。
(MACアドレスはスマホのBluetoothデバッグアプリで確認しましょう。AndroidであればnRF Connect for Mobile - Google Play のアプリなど)

Miro:bit->ESP32の順で起動すると繋がり、シリアルモニタにMicrobitから受信した値が表示されるはずです。*2

#include "BLEDevice.h"
static BLEUUID ubit_serviceUUID("E95D0753-251D-470A-A062-FA1922DFA9A8");
static BLEUUID ubit_accUUID("E95DCA4B-251D-470A-A062-FA1922DFA9A8");
static BLEAddress *pServerAddress = new BLEAddress("e0:73:d3:8f:72:29");
static BLERemoteCharacteristic *pRemoteCharacteristic;

static void Callback(
    BLERemoteCharacteristic *pBLERemoteCharacteristic,
    uint8_t *pData,
    size_t length,
    bool isNotify)
{

    Serial.print("Notify/Indicate Callback for characteristic: ");
    Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
    Serial.print(" data length ");
    Serial.print(length);
    Serial.print(" data: ");
    for(int i = 0;i < length ;i++)
    {
        Serial.print((char)pData[i]);
    }
    Serial.print("\n");
}


void setup()
{
    BLEDevice::init("");

    Serial.print("Forming a connection to ");
    Serial.println((*pServerAddress).toString().c_str());

    BLEClient *pClient = BLEDevice::createClient();
    Serial.println(" - Created client");

    // Connect to the  BLE Server.
    pClient->connect(*pServerAddress);
    Serial.println(" - Connected to server");

    // Obtain a reference to the service we are after in the remote BLE server.
    BLERemoteService *pRemoteService = pClient->getService(ubit_serviceUUID);
    if (pRemoteService == nullptr)
    {
        Serial.print("Failed to find our service UUID: ");
        Serial.println(ubit_serviceUUID.toString().c_str());
        return;
    }
    Serial.println(" - Found our service");

    // Obtain a reference to the characteristic in the service of the remote BLE server.
    pRemoteCharacteristic = pRemoteService->getCharacteristic(ubit_accUUID);
    if (pRemoteCharacteristic == nullptr)
    {
        Serial.print("Failed to find our characteristic UUID: ");
        Serial.println(ubit_accUUID.toString().c_str());
        return;
    }
    Serial.println(" - Found our characteristic");

    //enable Notify/Indicate 
    BLERemoteDescriptor *pRD = pRemoteCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902));
    if (pRD == nullptr)
    {
        Serial.print("Failed to find our descriptor UUID: ");
        Serial.println(BLEUUID((uint16_t)0x2902).toString().c_str());
        return;
    }

    uint8_t data[2] = {0x01, 0x00}; //Notify
    //uint8_t data[2] = {0x02, 0x00}; //Indicate 
    pRD->writeValue(data, 2, false);

    pRemoteCharacteristic->registerForNotify(Callback);

}

void loop()
{

}

サンプル(BLE_client.ino)を使う場合

ESP32 BLEライブラリの下記サンプルを使う場合ちょっと注意です。

https://github.com/nkolban/ESP32_BLE_Arduino/blob/master/examples/BLE_client/BLE_client.ino

notifyCallbackという関数がありますが、NotifyのCCCDを有効化していないので動きません。

上記コードのように有効化してあげましょう。

microbitのサービスUUID,キャラクタリスティックUUID一覧

サービス キャラクタリスティック UUID タイプ メモ
ボタン E95D9882-251D-470A-A062-FA1922DFA9A8
ボタンA E95DDA90-251D-470A-A062-FA1922DFA9A8 R/N 0 =押されてない、1 =押された、2 =長押し
ボタンB E95DDA91-251D-470A-A062-FA1922DFA9A8 R/N 同上
加速度 E95D0753-251D-470A-A062-FA1922DFA9A8
データ E95DCA4B-251D-470A-A062-FA1922DFA9A8 R/N XYZの順に各sint16、リトルエンディアンで格納 1000で割ると単位Gになる
周期 E95DFB24-251D-470A-A062-FA1922DFA9A8 R/W 1, 2, 5, 10, 20, 80, 160, 640(ms)を指定(初期値20ms)
IO E95D127B-251D-470A-A062-FA1922DFA9A8
データ E95D8D00-251D-470A-A062-FA1922DFA9A8 R/W/N 最大19個のピンの値を取得・指定 uint8配列
AD コンフィグ E95D5899-251D-470A-A062-FA1922DFA9A8 R/W ADモード取得・指定 ビットnがピンnに対応 0でデジタル、1でアナログ
IO コンフィグ E95DB9FE-251D-470A-A062-FA1922DFA9A8 R/W IOモード取得・指定 ビットnがピンnに対応 0で出力、1で入力
PWM     E95DD822-251D-470A-A062-FA1922DFA9A8 W   構造体PwmControlData型(詳細は下記URL)でPWM指令
LED E95Dd91D-251D-470A-A062-FA1922DFA9A8
状態 E95D7b77-251D-470A-A062-FA1922DFA9A8 R/W 5x5のLEDの全状態を取得・指定できる
テキスト E95D93EE-251D-470A-A062-FA1922DFA9A8 W 表示したいテキストを書き込み utf8s
スクロール遅延 E95D0d2d-251D-470A-A062-FA1922DFA9A8 R/W 文字を表示するまでの待機時間(ms)
磁気 E95DF2D8-251D-470A-A062-FA1922DFA9A8
データ E95Dfb11-251D-470A-A062-FA1922DFA9A8 R/N XYZの順に各sint16、リトルエンディアンで格納
周期 E95D386C-251D-470A-A062-FA1922DFA9A8 R/W 1, 2, 5, 10, 20, 80, 160, 640(ms)を指定(初期値20ms)
方位 E95D9715-251D-470A-A062-FA1922DFA9A8 R/N 北からの度数
温度 E95D6100-251D-470A-A062-FA1922DFA9A8
温度 E95D9250-251D-470A-A062-FA1922DFA9A8 R/N 摂氏
UART 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
TX 6E400002-B5A3-F393-E0A9-E50E24DCCA9E I マイクロビットから送信、uint8配列
RX 6E400003-B5A3-F393-E0A9-E50E24DCCA9E W マイクロビットが受信、uint8配列

R:READ, W:Write, N:Notify, I:Indicate

イベントサービスは省略。詳細は下記サイトに。
参考:Bluetooth Developer Studio - Profile Report


*1:もしかしたらこれが原因でMicro:bit側のアドレスタイプがランダムになっているかもしれません。
*2:継ぎ接ぎの末、コンパイルだけ通したコードなので動かないかも・・・。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away