現在のあなたのIPは

18.116.15.124

ESP32-S3のCoded Phyを試す

ESP32

CodedPhyとは?

低スピードで長距離を飛ばす設定であり、50m~100m程度飛ばせる機能です。CodedPhyの機能がESP32S3で試せることがわかっていたのですが、成功している人がほとんどいなかったので、調べながら実行しました。

ESP32S3で実行した結果

適当に試しただけですが、50m~70mくらいは飛ばせました。通常Bluetoothはせいぜい20mくらい繋がっていればいいくらいのイメージでしたので、かなり長距離飛ばせるのだなあというのが素直な感想です。

コードについて

少しハマりどころもありましたので、platformIOで実行したコードはこちらに上げておきます。Espressif-idfのv5.4では修正されていますので、2025年1月リリースではうまく動くであろうと考えられますので、その時期になったら、再度試してみたいと思います。

Client

#include <Arduino.h>
#include "BLEDevice.h"
#include <esp_gap_ble_api.h>

#define SERVER_BLE_NAME "ESP32_BLE_Server" // 接続するサーバー名
#define SERVICE_UUID "12345678-1234-5678-1234-56789abcdef0"
#define CHARACTERISTIC_UUID "87654321-4321-6789-4321-abcdef012345"

BLEClient* pClient = NULL;
BLERemoteCharacteristic* pRemoteCharacteristic = NULL;
BLEAddress serverAddress = BLEAddress("24:0A:C4:00:00:00");

static void gapEventHandler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t* param) {
    if (event == ESP_GAP_BLE_READ_PHY_COMPLETE_EVT) {
        if (param->phy_update.status == ESP_BT_STATUS_SUCCESS) {
            Serial.println("PHY情報取得完了:");
            Serial.print("Tx PHY: ");
            Serial.println(param->phy_update.tx_phy);
            Serial.print("Rx PHY: ");
            Serial.println(param->phy_update.rx_phy);
        } else {
            Serial.print("PHY情報の取得に失敗しました: ");
            Serial.println(param->phy_update.status);
        }
    }
}


// データ受信コールバック
static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic, 
                           uint8_t* pData, size_t length, bool isNotify) {
    String receivedData = String((char*)pData).substring(0, length);
    Serial.print("受信データ: ");
    Serial.println(receivedData);
    // remote address
    // typedef uint8_t esp_bd_addr_t[ESP_BD_ADDR_LEN];
    Serial.print(serverAddress.toString().c_str());
    esp_bd_addr_t bd_addr = {0x24, 0x0A, 0xC4, 0x00, 0x00, 0x00}; // ここはサーバーのアドレスを指定
    esp_err_t res = esp_ble_gap_read_phy(bd_addr);
    Serial.println(res);

}

void setup() {
    Serial.begin(115200);
    Serial.println("ESP32 BLE クライアント - データ受信開始");

    // BLEデバイス初期化
    BLEDevice::init("");


    // BLEスキャン設定
    BLEScan* pBLEScan = BLEDevice::getScan();
    pBLEScan->setActiveScan(true);
    BLEScanResults foundDevices = pBLEScan->start(5);

    // サーバー検索
    for (int i = 0; i < foundDevices.getCount(); i++) {
        BLEAdvertisedDevice device = foundDevices.getDevice(i);
        if (device.getName() == SERVER_BLE_NAME) {
            Serial.println("サーバーを発見しました。接続中...");
            pClient = BLEDevice::createClient();
            serverAddress = device.getAddress();
            if (pClient->connect(&device)) {
                Serial.println("サーバーに接続しました!");

                // サービスとキャラクタリスティックを取得
                BLERemoteService* pRemoteService = pClient->getService(SERVICE_UUID);
                if (pRemoteService) {
                    pRemoteCharacteristic = pRemoteService->getCharacteristic(CHARACTERISTIC_UUID);
                    if (pRemoteCharacteristic) {
                        Serial.println("キャラクタリスティックを取得しました。");
                        pRemoteCharacteristic->registerForNotify(notifyCallback);
                    }
                }
            }
            break;
        }
    }
    esp_err_t res = esp_ble_gap_register_callback(gapEventHandler);
    Serial.println(res);
    
}

void loop() {
    if (pClient && pClient->isConnected()) {
        delay(1000); // 接続維持
    } else {
        Serial.println("サーバー接続が切れました。再試行します...");
        setup();
    }
}

Server

#include <Arduino.h>
#include "BLEDevice.h"
#include <esp_gap_ble_api.h>

#define DEVICE_NAME "ESP32_BLE_Server"   // サーバーデバイス名
#define SERVICE_UUID "12345678-1234-5678-1234-56789abcdef0"
#define CHARACTERISTIC_UUID "87654321-4321-6789-4321-abcdef012345"

BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
bool deviceConnected = false;

// 接続状態を検知するコールバック
class MyServerCallbacks : public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
        Serial.println("クライアントが接続しました!");
        deviceConnected = true;
    }

    void onDisconnect(BLEServer* pServer) {
        Serial.println("クライアントが切断しました。");
        deviceConnected = false;
        BLEDevice::startAdvertising();  // 広告を再開
    }
};

void setup() {
    Serial.begin(115200);
    Serial.println("ESP32 BLE サーバー - データ送信開始");

    // BLEデバイス初期化
    BLEDevice::init(DEVICE_NAME);

    // サーバーとサービスの作成
    pServer = BLEDevice::createServer();
    pServer->setCallbacks(new MyServerCallbacks());
    BLEService* pService = pServer->createService(SERVICE_UUID);

    // キャラクタリスティック作成(Notifyのみ)
    pCharacteristic = pService->createCharacteristic(
        CHARACTERISTIC_UUID,
        BLECharacteristic::PROPERTY_NOTIFY
    );

    esp_err_t res = esp_ble_gap_set_prefered_default_phy(ESP_BLE_GAP_PHY_CODED_PREF_MASK, ESP_BLE_GAP_PHY_CODED_PREF_MASK);

    if (res == ESP_OK) {
        Serial.println("PHY設定成功");
    } else {
        Serial.println("PHY設定失敗");
    }
    

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

    // 広告の開始
    BLEAdvertising* pAdvertising = BLEDevice::getAdvertising();
    pAdvertising->addServiceUUID(SERVICE_UUID);
    BLEDevice::startAdvertising();

    Serial.println("BLE広告を開始しました。");
}

void loop() {
    static int count = 0; // 送信カウンタ
    if (deviceConnected) {
        String message = "Count: " + String(count++);  // 送信するデータ
        pCharacteristic->setValue(message.c_str());
        pCharacteristic->notify();  // データを送信
        Serial.println("送信データ: " + message);
    }
    delay(1000); // 1秒ごとにデータ送信
}

ハマりどころとしては、esp_ble_gap_set_prefered_phyの関数は動きませんでした。

変わりに、esp_ble_gap_set_prefered_default_phyを設定することで、設定できました。

コメント

タイトルとURLをコピーしました