Windows UWP读取BLE特征值时最大仅能获取20字节的问题咨询
问题背景
- 基于STM32蓝牙模块开发了自定义嵌入式C应用,包含多服务多特征值,部分特征值数据长度超过20字节
- 使用UWP蓝牙平台编写C# PC应用,通过Notify方式接收设备数据,但仅能读取最大20字节的数据
- 已通过手机ST应用及调试模式验证嵌入式设备确实发送了完整的长数据
代码片段
try { // BT_Code: read the value from the buffer to the characteristic. //GattReadResult result = await characteristic.ReadValueAsync(); GattCommunicationStatus status = await characteristic.WriteClientCharacteristicConfigurationDescriptorAsync( GattClientCharacteristicConfigurationDescriptorValue.Notify); if (status == GattCommunicationStatus.Success) { characteristic.ValueChanged += Characteristic_ValueChanged; } else { CharData.Text = "Read Unsucessfull:"; return; } } catch (Exception ex) { CharData.Text = $"Error while reading: {ex}\n"; }
void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args) { CharData.Invoke((MethodInvoker)(() => CharData.Clear())) ; // An Indicate or Notify reported that the value has changed. var reader = DataReader.FromBuffer(args.CharacteristicValue); byte[] input = new byte[reader.UnconsumedBufferLength]; reader.ReadBytes(input); }
解决方案
问题根源在于BLE协议默认ATT MTU为23字节(其中3字节为ATT协议头,有效数据载荷仅20字节),要传输超过20字节的数据,必须先完成MTU协商,让两端支持更大的数据包。
步骤1:UWP端发起MTU协商
在连接到蓝牙设备后、设置Notify之前,调用BluetoothLEDevice.RequestMtuAsync协商更大的MTU值(最大可设为512,需和嵌入式端匹配)。修改后的初始化代码示例:
// 假设已通过蓝牙扫描获取到目标BluetoothLEDevice实例 BluetoothLEDevice device = ...; // 协商MTU,这里请求512字节(根据你的需求调整) var mtuRequestResult = await device.RequestMtuAsync(512); if (mtuRequestResult.Status != GattCommunicationStatus.Success) { CharData.Text = "MTU协商失败"; return; } uint negotiatedMtu = mtuRequestResult.Mtu; // 协商成功后,单次Notify的有效数据长度为 negotiatedMtu - 3 // 接下来设置Notify try { GattCommunicationStatus status = await characteristic.WriteClientCharacteristicConfigurationDescriptorAsync( GattClientCharacteristicConfigurationDescriptorValue.Notify); if (status == GattCommunicationStatus.Success) { characteristic.ValueChanged += Characteristic_ValueChanged; } else { CharData.Text = "Notify设置失败"; return; } } catch (Exception ex) { CharData.Text = $"操作出错: {ex}\n"; }
步骤2:STM32端配置MTU扩展
确保你的STM32蓝牙栈(如STM32WB、BlueNRG)开启了MTU扩展功能,并设置了支持的最大MTU值:
- 以STM32WB为例,在BLE初始化时调用
aci_gatt_set_mtu函数设置最大MTU(比如512) - 确保嵌入式代码正确处理ATT层的
Exchange MTU Request请求,响应协商后的MTU值
额外注意
如果你的单条数据长度超过协商后的MTU-3字节,还需要在嵌入式端实现数据分段传输,或者使用GATT的可靠写入(Reliable Write)机制,UWP端则需要在ValueChanged事件中拼接分段数据。
内容的提问来源于stack exchange,提问作者Lenny018
相关产品推荐
相关产品推荐

