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

BlueFruit库无法访问nRF52840设备BLE服务与特征问题求助

解决Bluefruit库无法处理Service与Characteristic UUID相同的BLE设备问题

问题核心

目标BLE设备的Notify特征UUID与Service UUID完全相同,Bluefruit库的默认服务发现逻辑无法处理这种非标准UUID配置,导致服务发现失败、通知无法启用、特征写入失败,而ESP32的BLE库可兼容该情况。

解决方案

绕过Bluefruit库的封装式发现方法,手动执行完整的服务与特征遍历,直接操作GATT属性表来找到并配置目标特征:

修改后的连接回调代码

// 声明目标服务与特征UUID(无需提前实例化BLEClientService/Characteristic)
BLEUUID pixelServiceUUID("6e400001-b5a3-f393-e0a9-e50e24dcca9e");
BLEUUID pixelNotifyUUID("6e400001-b5a3-f393-e0a9-e50e24dcca9e");
BLEUUID pixelWriteUUID("6e400002-b5a3-f393-e0a9-e50e24dcca9e");

void connectCallback(uint16_t conn_handle) {
  // 执行全服务扫描发现
  if (!Bluefruit.Discovery.discover(conn_handle)) {
    Serial.println("全服务发现失败");
    return;
  }

  // 遍历所有已发现的服务
  for (uint8_t service_idx = 0; service_idx < Bluefruit.Discovery.numServices(); service_idx++) {
    BLEClientService current_service = Bluefruit.Discovery.getService(service_idx);
    
    // 匹配目标服务UUID
    if (current_service.uuid() != pixelServiceUUID) continue;

    // 遍历当前服务下的所有特征
    for (uint8_t chr_idx = 0; chr_idx < current_service.numCharacteristics(); chr_idx++) {
      BLEClientCharacteristic current_chr = current_service.getCharacteristic(chr_idx);
      BLEUUID chr_uuid = current_chr.uuid();

      // 处理Notify特征
      if (chr_uuid == pixelNotifyUUID) {
        // 手动查找CCCD描述符(0x2902,用于启用通知)
        BLEClientDescriptor cccd = current_chr.findDescriptor(BLEUUID(0x2902));
        if (cccd.exists()) {
          uint8_t enable_notify[] = {0x01, 0x00}; // 启用通知的标准值
          if (cccd.write(enable_notify, sizeof(enable_notify))) {
            Serial.println("Notify已成功启用");
            // 绑定通知回调
            current_chr.setNotifyCallback(notif_callback_wrapper);
          } else {
            Serial.println("启用Notify失败");
          }
        } else {
          Serial.println("未找到CCCD描述符");
        }
      }

      // 处理Write特征
      if (chr_uuid == pixelWriteUUID) {
        // 测试写入命令
        Blink blink;
        uint8_t* dataPtr = (uint8_t*)&blink;
        int write_status = current_chr.write(dataPtr, sizeof(blink));
        Serial.print("Blink命令发送结果: ");
        Serial.println(write_status);
      }
    }
  }
}

关键修改说明

  1. 全服务发现:使用Bluefruit.Discovery.discover(conn_handle)执行完整服务扫描,替代原有的_discoverService内部方法,避免UUID冲突导致的过滤逻辑。
  2. 遍历匹配:手动遍历所有服务和特征,确保找到与目标UUID匹配的实体,即使特征UUID与服务UUID相同。
  3. 手动操作CCCD:直接查找并写入0x2902描述符启用通知,绕过Bluefruit库中依赖服务-特征UUID区分的自动查找逻辑。
  4. 动态绑定特征:在遍历中直接使用发现的BLEClientCharacteristic实例,而非提前创建的未关联实例,确保操作的是正确的GATT属性。

额外注意事项

  • 若需对接16台以上BLE设备,需修改初始化代码的最大连接数参数:Bluefruit.begin(0, 16)(第二个参数为最大并发连接数,可根据需求调整)。

内容的提问来源于stack exchange,提问作者Jean-Philippe Encausse

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 09:02:07