見出し画像

【ESP32プログラム】Bluetoothを使ってみよう!(受信編)


スマートフォンからESP32へ指示を出したり、ESP32同士で通信するのに近距離であればBluetoothがとても便利です。今回はESP32におけるBluetooth通信のうち受信についての紹介をします。
Bluetoothプログラムを他のものに流用しやすくするため、それ以外の部分はできるだけシンプルにしておきます。今回はESP32基盤上の青色LEDを点灯・消灯するようにします。そのためESP32だけで試すことができます。
なお、ESP32基盤上の青色LEDはGPIO2をON/OFFすることで点灯・消灯できます。

プログラム

プログラムのうち重要なところを先に説明します。
それ以外の説明はプログラム内のコメントを参照してください。

SERVICE_UUID と CHARACTERISTIC_UUID

BLE(Bluetooth Low Energy)通信におけるサービスやキャラクタリスティックを識別するためのユニークな識別子です。これらは 任意 に設定できますが、いくつかの注意点があります。
(1)ランダムに生成する
一般的には、16バイト(128ビット)のランダムなUUIDを生成して使用します。UUIDジェネレーター(例: uuidgenerator.net)ようなオンラインツールなどで簡単に生成できます。
(2)規格に従ったUUIDを使用
BLEには、Bluetooth SIG が標準化した 16ビットまたは 32ビットのUUIDもあります(例: 0x180D は心拍数モニタリングサービス)。標準のUUIDを使う場合、特定の用途(心拍、バッテリー状態など)に制限されるので、汎用的な用途には128ビットの独自UUIDを使うのが一般的です。
(3)UUIDの用途
SERVICE_UUID

サービス全体を識別するためのUUID。例えば、モータ制御やセンサデータ転送といった特定の機能を定義する単位です。サービス内には複数のキャラクタリスティックを持つことができます。
CHARACTERISTIC_UUID
サービス内の個々のデータポイントや機能を識別するためのUUID。例えば、1つのサービスでモータAとモータBを制御する場合、それぞれの制御用キャラクタリスティックに別々のUUIDを設定することもできます。
(4)選択基準
ユニーク性が必要

UUIDは、BLE通信で衝突を避けるためにユニークである必要があります。同じアプリケーション内で複数のデバイスを扱う場合でも衝突しないよう、しっかり生成・管理しましょう。
他のデバイスと一致させる
受信側と送信側のUUIDは必ず一致させる必要があります。これが一致しないと接続や通信がうまくいきません。

デバイス名の設定

デバイス名を以下の関数で任意に設定します。BLEDevice::init("ESP32_LED_Control"); 
他のデバイスから当該のESP32を見つけるのに必要です。

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

#define LED_PIN 2 // ESP32の内蔵LEDピン

// サービスとキャラクタリスティックのUUID
#define SERVICE_UUID "4fafc2xx-1fb5-459e-8fcc-c5c9c33191xx"
#define CHARACTERISTIC_UUID "beb548xx-36e1-4688-b7f5-ea07361b26xx"

BLECharacteristic *pCharacteristic;

class MyCallbacks : public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *pCharacteristic) override {
    // 値を取得 (String型を使用)
    String value = pCharacteristic->getValue().c_str(); // getValue() は std::string を返すので c_str() で String に変換

    // 値に応じて動作
    if (value == "ON") {
      digitalWrite(LED_PIN, HIGH); // LEDを点灯
      Serial.println("LEDを点灯しました");
    } else if (value == "OFF") {
      digitalWrite(LED_PIN, LOW); // LEDを消灯
      Serial.println("LEDを消灯しました");
    } else {
      Serial.println("不明なコマンドを受信しました: " + value);
    }
  }
};

void setup() {
  Serial.begin(115200);

  pinMode(LED_PIN, OUTPUT); // LEDピンを出力モードに設定
  digitalWrite(LED_PIN, LOW); // 初期状態でLEDを消灯

  // BLEデバイスの初期化
  BLEDevice::init("ESP32_LED_Control"); // デバイス名を設定
  BLEServer *pServer = BLEDevice::createServer();

  // サービスを作成
  BLEService *pService = pServer->createService(SERVICE_UUID);

  // キャラクタリスティックを作成
  pCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID,
                      BLECharacteristic::PROPERTY_READ |
                      BLECharacteristic::PROPERTY_WRITE
                    );

  // キャラクタリスティックに初期値を設定
  pCharacteristic->setValue("Waiting for command...");
  pCharacteristic->setCallbacks(new MyCallbacks());

  // サービスを開始
  pService->start();

  // BLE広告を開始
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->start();

  Serial.println("BLEデバイスが起動しました。iPhoneで接続してください。");
}

void loop() {
  // 特に処理は不要。BLEはバックグラウンドで動作します。
}

実行してみよう

私はスマホからBluetoothでESP32に送信するのに「BLE Scanner」というアプリを使いました。
アプリを起動したら、「ESP32_LED_Control」を選択します(図1の「Connect」を押す)。これは今回、私が設定したものですので、皆さんの設定したものを選択してください。

図1 デバイスの選択

「CUSTOM CHARACTERISTIC」の「W」を押します(図2)。
ESP32に指令(WRITE)するためです。

図2 CUSTOM CHARACTERISTICの選択

図3のように出てきたダイアログボックスにONと入力して「OK」を押すとESP32の基盤上のLEDが点灯します。図4のように「OFF」と入力して「OK」を押すと消灯します。

図3 点灯「ON」指示
図4 消灯「OFF」指示

購入部品

最新情報「電子工作お買い物一覧」の記事を参照ください。
リンク切対応や代替部品の紹介もしています。


いいなと思ったら応援しよう!