基于bluepy获取BLE设备指定NOTIFY特征值失败问题求助
BLE设备Notify特征数据接收异常问题(Raspberry Pi 4 + Ubuntu + bluepy)
问题背景
在搭载Ubuntu系统的Raspberry Pi 4上使用bluepy库开发Python程序,目标是连接指定BLE设备,获取特征00001011-1212-efde-1523-785feabcd123(handle:15)的Notify值。通过bluepy扫描得到设备的服务与特征信息如下:
Service UUID: 00001800-0000-1000-8000-00805f9b34fb -> Characteristic UUID: 00002a00-0000-1000-8000-00805f9b34fb Characteristic handle: 3 Characteristic properties: READ Value: b'' -> Characteristic UUID: 00002a01-0000-1000-8000-00805f9b34fb Characteristic handle: 5 Characteristic properties: READ Value: b'\x00\x00' -> Characteristic UUID: 00002a04-0000-1000-8000-00805f9b34fb Characteristic handle: 7 Characteristic properties: READ Value: b'\xff\xff\xff\xff\x00\x00\xff\xff' Service UUID: 00001801-0000-1000-8000-00805f9b34fb -> Characteristic UUID: 00002a05-0000-1000-8000-00805f9b34fb Characteristic handle: 10 Characteristic properties: INDICATE Service UUID: 00001523-1212-efde-1523-785feabcd123 -> Characteristic UUID: 00001027-1212-efde-1523-785feabcd123 Characteristic handle: 13 Characteristic properties: READ WRITE -> Characteristic UUID: 00001011-1212-efde-1523-785feabcd123 Characteristic handle: 15 Characteristic properties: NOTIFY Service UUID: 0000180d-0000-1000-8000-00805f9b34fb -> Characteristic UUID: 00002a37-0000-1000-8000-00805f9b34fb Characteristic handle: 19 Characteristic properties: NOTIFY
已确认指令通过peripheral.writeCharacteristic送达设备,且BLE Scanner连接时能看到目标特征的Notify值更新,但代码仅能收到handle:19的特征数据,无法获取handle:15的Notify值。当前使用的代码如下:
def threadWrite(characteristic, peripheral): # is the Characteristic UUID: 00001027-1212-efde-1523-785feabcd123 characteristic.write(b"reset\n") time.sleep(1) characteristic.write(b"read ppg 4\n") time.sleep(1) peripheral.setDelegate(classes.MyDelegate()) svc = peripheral.getServiceByUUID("00001523-1212-efde-1523-785feabcd123") ch = svc.getCharacteristics("00001011-1212-efde-1523-785feabcd123")[0] ch_cccd = ch.getDescriptors(forUUID=0x2902)[0] ch_cccd.write(b"\0x1\x00") characteristic.write(b"read ppg 5\n") while True: if peripheral.waitForNotifications(1.0): # handleNotification() was called continue print("Waiting...") # different module class MyDelegate(btle.DefaultDelegate): def __init__(self): btle.DefaultDelegate.__init__(self) def handleNotification(self, cHandle, data): print ("Notification received: handle =", cHandle, "; Raw data =", binascii.b2a_hex(data))
问题分析与解决方案
1. CCCD写入格式错误
你写入客户端特征配置描述符(CCCD)的字节序列b"\0x1\x00"是错误的:
- 正确启用Notify的字节序应为小端模式的
b"\x01\x00"(对应数值0x0001) - 原代码中的
\0x1是无效转义,实际会被解析为两个独立字符:\0(空字符)和x1,导致CCCD设置失败,目标特征的Notify功能未被真正启用。
2. 优化Delegate设置与订阅顺序
建议先设置Delegate再进行CCCD写入,确保回调能正确捕获所有通知;同时添加withResponse=True参数,确保CCCD写入操作被设备确认。
修正后的代码
import time import binascii from bluepy import btle def threadWrite(characteristic, peripheral): # 先设置Delegate,确保通知回调就绪 peripheral.setDelegate(classes.MyDelegate()) # 发送初始化指令 characteristic.write(b"reset\n") time.sleep(1) characteristic.write(b"read ppg 4\n") time.sleep(1) # 获取目标Notify特征及对应的CCCD svc = peripheral.getServiceByUUID("00001523-1212-efde-1523-785feabcd123") ch = svc.getCharacteristics("00001011-1212-efde-1523-785feabcd123")[0] ch_cccd = ch.getDescriptors(forUUID=0x2902)[0] # 写入正确的CCCD值启用Notify,添加withResponse确保写入成功 ch_cccd.write(b"\x01\x00", withResponse=True) # 可选:验证CCCD设置结果 # print("CCCD value after write:", ch_cccd.read()) characteristic.write(b"read ppg 5\n") while True: if peripheral.waitForNotifications(1.0): continue print("Waiting...") # 另一个模块中的Delegate类 class MyDelegate(btle.DefaultDelegate): def __init__(self): super().__init__() def handleNotification(self, cHandle, data): print(f"Notification received: handle = {cHandle}; Raw data = {binascii.b2a_hex(data)}")
额外验证步骤
- 写入CCCD后,可通过
ch_cccd.read()读取其值,确认结果为b'\x01\x00',说明Notify已成功启用。 - 如果仍能收到handle:19的特征数据,可尝试禁用该特征的Notify:找到对应特征的CCCD,写入
b"\x00\x00"即可关闭其通知功能。
内容的提问来源于stack exchange,提问作者Tommaso Ceredi
相关产品推荐
相关产品推荐

