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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 23:25:17