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

从蓝牙Characteristic读取长属性值时无法一次性获取完整数据

解决BLE特征值一次性读取128字节数据的问题

你遇到的是BLE默认MTU(最大传输单元)限制的问题。BLE协议默认MTU为23字节,其中1字节用于操作指令,所以实际能承载的用户数据只有22字节。要一次性读取完整的128字节数据,需要先与外设协商更大的MTU值,具体实现步骤如下:

1. 连接外设后主动请求扩展MTU

在外设连接成功的代理方法中,调用requestMTU(_:)请求更大的MTU。由于你需要读取128字节数据,建议请求185字节的MTU(该值在多数BLE 4.2及以上设备中都支持,足够容纳128字节用户数据):

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
    // 请求扩展MTU
    peripheral.requestMTU(185)
    peripheral.delegate = self
}

2. 监听MTU更新结果

实现peripheral(_:didUpdateMTU:error:)代理方法,确认MTU是否协商成功,成功后再执行服务和特征值的发现操作:

func peripheral(_ peripheral: CBPeripheral, didUpdateMTU mtu: Int, error: Error?) {
    if let error = error {
        print("MTU协商失败: \(error.localizedDescription)")
        // 协商失败时,只能退而处理分块读取逻辑
        peripheral.discoverServices([CBUUID(string: "FFA1")])
        return
    }
    print("MTU已更新为: \(mtu)")
    // MTU协商成功,开始发现目标服务
    peripheral.discoverServices([CBUUID(string: "FFA1")])
}

3. 修改特征值读取逻辑

保持你原有的特征值发现和读取逻辑,但确保这部分代码在MTU协商完成后执行。此时读取特征值就能一次性获取完整的128字节数据:

public func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
    guard error == nil, let characteristics = service.characteristics else {
        print("发现特征值失败: \(error?.localizedDescription ?? "未知错误")")
        return
    }
    
    if service.uuid.uuidString == "FFA1" {
        for characteristic in characteristics {
            peripheral.setNotifyValue(true, for: characteristic)
            if characteristic.uuid.uuidString == "FFF3" {
                peripheral.readValue(for: characteristic)
                print("找到设备名称特征值")
                print("\(characteristic)")
                if let value = characteristic.value {
                    print("完整数据: \(value as NSData)")
                    // 这里可以直接处理128字节的完整数据
                }
            }
        }
    }
}

关键注意事项

  • 外设必须支持BLE 4.2或更高版本,且固件中配置了允许扩展MTU,否则无法协商更大的MTU
  • 如果外设不支持扩展MTU,你只能通过分块读取的方式拼接完整数据(监听peripheral(_:didUpdateValueFor:error:)多次回调并累加数据)
  • 请求的MTU值不能超过外设支持的最大值,否则会被自动调整为外设支持的最大MTU

内容的提问来源于stack exchange,提问作者Gopi Gowda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 16:46:13