You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32 BLE客户端获取数字输入特征值被ADC值覆盖问题求助

ESP32 BLE客户端数据被覆盖问题解决

问题根因排查

nRF Connect能正常读取所有特征值,说明服务器端的广播逻辑没问题,问题大概率出在客户端的通知回调处理环节——多个特征共用了同一个缓存变量,导致后接收的ADC数据覆盖了之前的数字输入数据。

具体修复步骤

1. 为每个特征配置独立的回调函数

不要用同一个回调处理所有特征,给每个特征单独写回调,直接在回调内处理对应数据,避免依赖全局共享变量。示例代码:

// 处理ejex ADC数据的回调
void onEjexNotify(BLERemoteCharacteristic* charPtr, uint8_t* data, size_t len, bool isNotify) {
  int ejexVal = *(int*)data;
  // 直接使用ejexVal做后续处理,比如打印或存入专属变量
}

// 处理ejey ADC数据的回调
void onEjeyNotify(BLERemoteCharacteristic* charPtr, uint8_t* data, size_t len, bool isNotify) {
  int ejeyVal = *(int*)data;
  // 处理ejey数据
}

// 处理boton数字输入的回调
void onBotonNotify(BLERemoteCharacteristic* charPtr, uint8_t* data, size_t len, bool isNotify) {
  bool botonVal = data[0];
  // 处理boton数据,与ADC变量完全隔离
}

2. 客户端订阅特征时绑定对应回调

订阅每个特征时,指定专属的回调函数,避免绑定错误导致数据混叠:

// 替换为你实际使用的特征UUID
BLERemoteCharacteristic* ejexChar = remoteService->getCharacteristic("XXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX");
ejexChar->registerForNotify(onEjexNotify);

BLERemoteCharacteristic* ejeyChar = remoteService->getCharacteristic("YYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY");
ejeyChar->registerForNotify(onEjeyNotify);

BLERemoteCharacteristic* botonChar = remoteService->getCharacteristic("ZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ");
botonChar->registerForNotify(onBotonNotify);

3. 检查服务器端数据更新逻辑

确保服务器更新每个特征时使用独立变量,不要复用同一个临时变量:

// 服务器端更新特征示例
int ejex = analogRead(34);
ejexCharacteristic->setValue(&ejex, sizeof(ejex));
ejexCharacteristic->notify();

int ejey = analogRead(35);
ejeyCharacteristic->setValue(&ejey, sizeof(ejey));
ejeyCharacteristic->notify();

bool boton = digitalRead(2);
botonCharacteristic->setValue(&boton, sizeof(boton));
botonCharacteristic->notify();

4. 校验数据长度匹配

ADC值如果是int类型(4字节),数字输入是布尔值(1字节),客户端回调中要按对应长度处理数据,避免越界拷贝覆盖其他变量。比如处理boton时只取第1字节,不要按4字节读取。

调试小技巧

  • 在每个回调函数中打印特征UUID和接收的数据,确认触发回调的是对应特征:
void onBotonNotify(BLERemoteCharacteristic* charPtr, uint8_t* data, size_t len, bool isNotify) {
  Serial.print("触发回调的特征UUID: ");
  Serial.println(charPtr->getUUID().toString().c_str());
  Serial.print("boton值: ");
  Serial.println(data[0]);
}
  • 服务器端每次发送数据前,打印对应特征的UUID和值,确认发送的数据正确。

内容的提问来源于stack exchange,提问作者Oscar Gonzalez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 07:10:11