一、项目背景

想要实现手机和蓝牙设备的数据交互。客户端使用nrf connect ,服务器使用esp32c3基于esp-idf/examples/bluetooth/bluedroid/ble/gatt_server_service_table项目修改基础代码。自己配置了额外的服务和特征。想要实现居于notify和indicate的数据返回而不是通过nrf connect主动读。解决方案很简单,但是因为我太久没接触蓝牙了忘记了描述符的作用,在网上找了很久最后还是通过找例程自己逐步注释代码的方式最终找到需要描述符才能启用notify和indicate。写下这篇文章希望能对你有所帮助。

二、实现步骤

参照demo新增服务和特征,配置相应的服务和特征值。参照demo代码在nrf connect发送数据触发ESP_GATTS_WRITE_EVT事件后使用esp_ble_gatts_send_indicate返回特定的数据实现基本功能。

三、问题&解决方案

问题1:新增了服务和特征后在nrf connect软件上无法看到使能和关闭notify和indicate的按键。
解决方案:需要添加描述符。notify和indicate功能的开启必须要有描述符。

问题2:BT_GATT: Error in gatts_add_char_desc_value_check, line=1612,attribute actual length should not be larger than max length
解决方案:下图中描述符高亮的heart_measurement_ccc必须为static const uint8_t的两位,不然会超过规定长度。调整描述符最大长度应该也可以解决这个问题,但是我没有尝试在这里插入图片描述
问题3:如何在nrf connect开启监听notify和indicate
解决方案:1、点击红色按键在这里插入图片描述
2、点击红色按键
在这里插入图片描述
3、向上划
在这里插入图片描述
问题4:在使用vue3开发微信小程序时如何开启连接的蓝牙设备的notify和indicate。
解决方案:根据上面的步骤基本可以确认esp32端的notify和indicate功能已经启用,那么可以来开发小程序端的代码。参照问题3中对设备的操作。要想开启设备notify和indicate首先要对特征的CCCD描述符(0x2902)写入0x0001。在小程序中由于大小端的原因实际写入值为0100。具体代码如下,实际主要代码就是一个蓝牙的特征值写入(writeBLECharacteristicValue
),不过对于描述符的修改要带上描述符的uuid,而对于CCCD这个描述符的uuid固定为以下代码中的cccdDescriptor.ai说是蓝牙SIG定义的‌标准UUID基数‌没有具体查证。

 // 从目标特征值的描述符列表中查找0x2902(CCCD)
  const cccdDescriptor = '00002902-0000-1000-8000-00805f9b34fb'
  // 新增:使能notify(写入0x2902描述符,值为01 00)
  await new Promise((resolve, reject) => {
    // 0x0100表示启用notify(小端模式,对应16位值0x0001)
    const enableNotifyValue = new Uint8Array([0x01, 0x00]).buffer;
    uni.writeBLECharacteristicValue({
      deviceId,
      serviceId: targetService.uuid,
      characteristicId: targetChar.uuid, // 目标特征值UUID
      descriptorId: cccdDescriptor, // 0x2902描述符的完整UUID
      value: enableNotifyValue, // 写入值:01 00(ArrayBuffer格式)
      success: () => {
        console.log('notify使能成功');
        resolve();
      },
      fail: (err) => reject(new Error(`使能notify失败: ${err.message}`))
    });
  });
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐