低功耗蓝牙(ESP32 和 Android 智能手机之间):数据传输很慢

Posted

技术标签:

【中文标题】低功耗蓝牙(ESP32 和 Android 智能手机之间):数据传输很慢【英文标题】:Bluetooth Low Energy (between ESP32 and Android smartphone): Data transmission quite slow 【发布时间】:2021-10-11 22:23:01 【问题描述】:

这是我在这个板上提出的第一个问题

项目简介:

5 个传感器,与 esp32 板相连,每秒传输 1000 个样本,每个样本有 16 位。这些值应通过 BLE 传输(使用 BLE Arduino 库和 ESP32)。连接的设备(智能手机)应该读取这些值并对其进行处理(也通过 BLE,使用以下库:https://github.com/RobotPajamas/Blueteeth)。 ESP32 是服务器! Java 用于 Android Studio!

问题:

在测试 BLE 连接时,会传输一个简单的“hello world”作为特征值。每次我在 android-device 端收到“hello world”时,都会增加一个变量:问题是,该变量在一秒钟内只增加了 4 次。这意味着(假设 1 个字符在等于 1 字节的字符串中)正在传输 11byte*4(1/s)=44byte/s。 -> 这显然是不够的(BLE 不应该传输 ~2MBit/s(减去协议数据))

代码片段

ESP32:传输价值的BLE-Server

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


#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"


class MyCallbacks: public BLECharacteristicCallbacks 
    void onWrite(BLECharacteristic *pCharacteristic) 
      std::string value = pCharacteristic->getValue();

      if (value.length() > 0) 
        Serial.println("*********");
        Serial.print("New value: ");
        for (int i = 0; i < value.length(); i++)
          Serial.print(value[i]);

        Serial.println();
        Serial.println("*********");
      
    
;

void setup() 
  Serial.begin(115200);

  BLEDevice::init("MyESP32");
  BLEServer *pServer = BLEDevice::createServer();

  BLEService *pService = pServer->createService(SERVICE_UUID);

  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pCharacteristic->setCallbacks(new MyCallbacks());

  pCharacteristic->setValue("Hello World");
  pService->start();

  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();


void loop() 
  // put your main code here, to run repeatedly:
  delay(2000);

Android Studio 代码(接收源代码片段):

try
        
            while(sampleBluetoothData)
            
                this.selectedDevice.readCharacteristic(MainActivity.characteristicUUID, MainActivity.serviceUUID, (response, data) ->
                
                    if (response != BlueteethResponse.NO_ERROR) 
                            return;
                    
                    Log.d("AUSGANG", new String(data) + "times: "+ i);
                    i++;
                );
            
        
        catch (Exception e)
        
            e.printStackTrace();
        

ESP32 端的写入是 Arduino IDE 的空白示例代码,Android 端的读取由 BLE-Library 发布者进行。是的,Log.d 会影响性能,但不会降低太多。

Android代码的变量“data”是接收到的char-array。蓝牙读取在后台线程上运行。

我现在问自己的问题:

问题是 Android-Studio 库还是 Arduino 库 这是一种正常行为吗,如果特征值没有改变,它的传输速度会很慢。 更新特征值的速度有多快

提前致谢!

【问题讨论】:

您应该使用特征通知而不是特征读取。 【参考方案1】:

BLE 绝对可以每秒传输超过 4 个 11 字节的部分。

阅读方法:

    一般来说,一直持续读取并不是 BLE 的预期方式 - 最好订阅数据更改,因此 ESP32 只会在需要时通知(例如,执行一次 selectedDevice.subscribeToCharacteristic,而不是循环读取,然后是 ESP32代码应相应更改) 我猜selectedDevice.readCharacteristic 请求异步BLE 读取,当您在while(sampleBluetoothData) 中调用它时,您的蓝牙库正在添加越来越多的读取请求。也许明智的做法是在前一次读取完成后才请求新的读取 - 在读取回调中添加 if(sampleBluetoothData) this.readAgain();

考虑从这个 kickstart 示例制作一个测试原型:BLEProof on github - Android 和 ESP32,读取、写入、通知(但它只使用系统 API 没有蓝牙库,你的方法更好,它是使用该库更容易、更安全)。

还有什么要检查的:

    Android 端:您确定您的代码没有进入if (response != BlueteethResponse.NO_ERROR) 内部吗? Android 端:为确保蓝牙库不会因读取请求而过载,请尝试在读取循环中添加 50 毫秒的延迟(只是为了检查,这不是解决方案) Android 端:您确定在读取这些数据时没有其他 BLE 读/写操作吗? ESP32 端:使用更短的 BLE 连接间隔 (BLE throughput article) - 在 pAdvertising-&gt;start(); 之前添加 pAdvertising-&gt;setMinPreferred(0x06);pAdvertising-&gt;setMaxPreferred(0x20);(但这仅设置“首选”间隔,Android 可能会忽略它)

【讨论】:

感谢您的详细解答!好像我使用的是旧的库版本,在这个版本(2.0)上订阅是不可能的。我更新到4.0版本,现在可以了。【参考方案2】:

使用读取请求,您主要受限于传输速度的连接间隔 - 即请求 + 响应的 2 个间隔。

例如,如果您的客户端的连接间隔为 50 毫秒,那么您应该期望每秒 10 次读取最多 20 个字节的特征。

如果另一个客户端的连接间隔为 30 毫秒,则此速率提高到每秒 16.6 次读取。

最快的可协商连接间隔为 7.5 毫秒,每秒最多读取 66.6 次(读取 20 字节时为 10.7kbps)。

【讨论】:

【参考方案3】:

我正在阅读 BLE ***页面,最低数据速率为 125Kbit/s ,所以我认为在你的情况下是可行的,因为你只会传输 16Kbit/s。看看BLE wikipedia。

【讨论】:

以上是关于低功耗蓝牙(ESP32 和 Android 智能手机之间):数据传输很慢的主要内容,如果未能解决你的问题,请参考以下文章

原创Android 5.0 BLE低功耗蓝牙从设备应用

arduino ESP32 AndroidStudio BLE低功耗蓝牙 物联网

arduino ESP32 AndroidStudio BLE低功耗蓝牙 物联网

混合APP低功耗蓝牙项目解析数据可能用到的一些小方法---ble

esp32只开启ble的功耗

esp32低功耗远程唤醒