【发布时间】:2018-07-09 15:41:37
【问题描述】:
我正在开发一个 iOS 应用程序,该应用程序将在 iOS 11.4 上使用 CoreBluetooth 从支持 Bluetooth LE 的设备读取脉搏血氧仪数据> 在 Swift 4.1 中。
我有 CBCentralManager 搜索外围设备,我找到了我感兴趣的 CBPeripheral,我确认它具有 0x1822 脉搏血氧仪服务,如蓝牙 SIG here 所述。 (您可能需要在 Bluetooth SIG 注册才能访问该链接。它是免费的,但需要一两天时间。)
之后,我连接到它,然后我发现服务:
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
peripheral.discoverServices(nil)
}
然后在我的 peripheral:didDiscoverServices 中发现 GATT 特征:
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?){
for service in peripheral.services ?? [] {
if service.uuid.uuidString == "1822" {
peripheral.discoverCharacteristics(nil, for: service)
}
}
}
从中我看到以下可用特征 (CBCharacteristic.uuid):0x2A5F、0x2A5E、0x2a60 和 0x2A52。然后我订阅 0x2A5F 的更新,即 PLX 连续测量,描述为 here:
if service.uuid.uuidString == "1822" && characteristic.uuid.uuidString == "2A5F" {
// pulseox continuous
print("[SUBSCRIBING TO UPDATES FOR SERVICE 1822 'PulseOx' for Characteristic 2A5F 'PLX Continuous']")
peripheral.setNotifyValue(true, for: characteristic)
}
然后我开始在我的 peripheral:didUpdateValueFor 方法中接收返回的 20 字节数据包:
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if characteristic.service.uuid.uuidString == "1822" && characteristic.uuid.uuidString == "2A5F" {
if let data = characteristic.value {
var values = [UInt8](repeating:0, count:data.count)
data.copyBytes(to: &values, count: data.count)
}
}
}
从参考文档中,您可以看到第一个字节是一组位域,描述了数据包中包含哪些可选值。接下来的 2 个字节是 SpO2PR-Normal - SpO2(氧合)读数的 SFLOAT 值,接下来的 2 个字节是另一个 SFLOAT 值为了 SpO2PR-Normal - PR(脉率)值。
蓝牙 SIG 将 SFLOAT 列为 IEEE-11073 16 位 SFLOAT here。 IEEE 的 document on IEEE-11073 未公开列出,而是 available for purchase,但我宁愿避免这样做。
知道如何解码吗?我在 Stack Overflow 上发现了另一个问题,引用了普通的 32-bit Float,但该问题是针对不同类型的 Float,其答案不适用。
【问题讨论】:
标签: ios swift bluetooth-lowenergy core-bluetooth gatt