繁体   English   中英

如何在 ESP32 上动态 BLE 广告并反映在 Flutter 应用程序上

[英]How to dynamically BLE advertise on ESP32 and reflect on flutter app

我的基于 ESP32 的定制 PCB BLE 外设正在宣传 LiFP 电池的动态物理值,例如电流或 SoC(充电状态)。

基本上,代码如下:

/// Returns the manufacturer data as a String
void Ble :: setAdvertisingManufacturerData(BLEAdvertisementData *advertisementData) {

    const float soc = battery.getSoc();
    log("Advertising Soc %d%%", soc);
    
    const char bytes[] = {
        (manCode>>8)&0xff, manCode&0xff,
        // SoC: 2 bytes | 0~2 bytes
        (soc>>8)&0xff, soc&0xff,

    };

    advertisementData->setManufacturerData(std::string(bytes, sizeof(bytes)));
}

/// Prepares the advertising manif data
void Ble :: advertise() {
    BLEAdvertisementData advertisementData;
    advertisementData.setFlags(0x6);
    
    setAdvertisingManufacturerData(&advertisementData);

    pAdvertising = BLEDevice::getAdvertising();
    pAdvertising->setScanResponse(true);
    pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
    pAdvertising->setMinPreferred(0x12);
    
    pAdvertising->setAdvertisementData(advertisementData);
    pAdvertising->start();
}

void Ble :: setup() {
    // == Start the advertising
    advertise();
}

/// Dynamically advertises every seconds
void Ble :: loop() {
    // == Dynamically advertise
    static unsigned lastAdvertised = 0;
    const unsigned now = millis();
    
    if (!lastAdvertised || now - lastAdvertised > 1000) {
        lastAdvertised = now;

        BLEAdvertisementData scanResponse;
        setAdvertisingManufacturerData(&scanResponse);
        pAdvertising->stop();
        pAdvertising->setScanResponseData(scanResponse);
        pAdvertising->start();
    }
}

到目前为止,一切都很好。 但是从 Flutter 应用程序中,尽管我在 ESP32 日志中看到了不断变化的值,但广告制造商的数据仍然显示 SoC 为零(也就是初始值)。

我可能犯了一个错误,欢迎任何帮助!

[更新] 使用 nRF 移动应用程序,我得到了这个:

在此处输入图像描述

我看到有两个类型为 0x09 的部分:第一个是“空的”,而第二个有正确的数据。

我终于做到了,这使我的广告充满活力。

我删除了setScanResponseData()并替换为setAdvertisementData()的另一个调用,就像在advertise()中所做的那样。

但我仍然不明白setScanResponseData()的用途。


void Ble :: loop() {

    // == Dynamically advertise
    static unsigned lastAdvertised = 0;
    const unsigned now = millis();

    if (!lastAdvertised || now - lastAdvertised > 5000) {
        lastAdvertised = now;
        
        log("Dynamic advertising");

        BLEAdvertisementData scanResponse;
        std::string md = getAdvertisingManufacturerData();
        setAdvertisingManufacturerData(md, &scanResponse);
        pAdvertising->stop();
        //pAdvertising->setScanResponseData(scanResponse);
        pAdvertising->setAdvertisementData(scanResponse);
        pAdvertising->start();

    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM