Qt C++ Win10开发读取迪卡侬BLE心率传感器返回空缓冲区问题求解
故障排查方向
- Qt BLE模块Windows平台适配问题:Qt 5.14之前版本的Windows平台QtBluetooth模块存在BLE通知接收缺陷,Windows 10 1809以下版本系统原生BLE栈也存在兼容性问题
- 信号绑定逻辑错误:当前绑定的是自定义封装类的通知信号,未绑定Qt原生
QLowEnergyService的characteristicChanged信号,自定义类未正确转发原生信号导致通知无法触发槽函数 - CCC描述符写入逻辑错误:直接修改原描述符的值,如果初始值为空会导致数组越界,写入的配置值不符合BLE标准规范
- 特征操作逻辑错误:BLE标准中心率测量特征默认仅支持通知属性,无主动读属性,主动调用
readCharacteristic会被设备忽略,轮询读取本地缓存的特征值也只能拿到空值
解决方案
- 基础环境适配
升级Qt版本至5.15.2及以上,Windows 10系统升级至20H2及以上版本,在项目.pro文件中确保添加了QT += bluetooth配置,在程序入口main函数中指定Qt蓝牙后端为WinRT:
#include <QCoreApplication> #include <QByteArray> int main(int argc, char *argv[]) { qputenv("QT_BLUETOOTH_BACKEND", "winrt"); QCoreApplication a(argc, argv); // 原有业务逻辑 return a.exec(); }
- 修正特征通知信号绑定逻辑
找到心率测量特征后直接绑定Qt原生的特征变更信号,不需要自定义封装类接收通知:
void TWindowsStatistique::serviceDetailsDiscovered(QLowEnergyService::ServiceState newState) { if(newState != QLowEnergyService::ServiceDiscovered) return; const QList<QLowEnergyCharacteristic> chars = heart_rate_service->characteristics(); for (int i=0;i<chars.size();i++) { QLowEnergyCharacteristic tmp_char=chars.at(i); if(tmp_char.uuid() == QBluetoothUuid::HeartRateMeasurement) { // 绑定原生特征变更信号 connect(heart_rate_service, &QLowEnergyService::characteristicChanged, this, [=](const QLowEnergyCharacteristic &c, const QByteArray &value){ if(c.uuid() == tmp_char.uuid()){ // 按照BLE心率标准解析数据 quint8 flag = value.at(0); int heartRate = 0; if(flag & 0x01){ // 16位心率值 heartRate = qFromLittleEndian<quint16>(value.mid(1,2)); }else{ // 8位心率值 heartRate = static_cast<quint8>(value.at(1)); } qDebug() << "采集到的心率值:" << heartRate; } }); // 开启通知 QLowEnergyDescriptor cccDesc = tmp_char.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); if(cccDesc.isValid()){ QByteArray enableNotify = QByteArray::fromHex("0100"); heart_rate_service->writeDescriptor(cccDesc, enableNotify); } // 移除原有无效的readCharacteristic调用、自定义类绑定、定时器轮询逻辑 } } }
- 清理无效逻辑
- 移除主动调用
readCharacteristic的代码 - 移除定时器轮询读取特征值的逻辑
- 移除自定义
THeartRateCharacteristic类相关的绑定和初始化逻辑
内容的提问来源于stack exchange,提问作者ppac
相关产品推荐
相关产品推荐

