如何在 Swift 中从蓝牙特性中获取数据
Posted
技术标签:
【中文标题】如何在 Swift 中从蓝牙特性中获取数据【英文标题】:How to get data out of bluetooth characteristic in Swift 【发布时间】:2014-08-22 22:21:32 【问题描述】:我现在有一个Polar h7 设备在我身边(它是BTLE),我已经完成了所有工作,但我对如何获得characteristic.value
的BPM 感到困惑,因为它正在更新。我必须将一些字节转换为 bpm...
我的外围设备正在更新:
func peripheral(peripheral: CBPeripheral!, didUpdateValueForCharacteristic characteristic: CBCharacteristic!, error: NSError!)
if characteristic.UUID == CBUUID.UUIDWithString(heartRateChar)
getInfoAboutHeartRate(characteristic)
我正在获取有关心率的信息:
func getInfoAboutHeartRate(characteristic:CBCharacteristic)
println(characteristic.value)
var bytes = characteristic.value.bytes
我知道我需要将这些字节转换为 BPM。
根据bluetooth.org 的规范(这是我感到困惑的地方),字节 0 将是 1
或 0
.. 如果是 0
,则心率值是 @987654329 @ 如果它是 1
,那么它就是 uint16
,我可以从中获取 BPM。
如何确定字节 0
是 1
还是 0
?如何将其变成uint8
或uint16
。如果我这样做,我是直接提高 BPM 还是必须对它做其他事情?现在 BPM 以 <16447d03>
之类的形式返回,这是有道理的。
【问题讨论】:
【参考方案1】:这看起来应该很简单,但试图确认你在说什么。 “bytes”的最终值是否为“16447d03”?它是指向数据的指针,而不是数据本身,因此您需要执行以下操作才能获取实际值:
var data = characteristic.value
var values = [UInt8](count:data.length, repeatedValue:0)
data.getBytes(&values, length:data.length)
这里,“values”是一个包含实际值的数组。
在我们的一次私人讨论中,您将输出列为:
[22, 77, 22, 3]
[22, 78, 27, 3, 18, 3]
[22, 79, 2, 3]
[22, 78, 15, 3]
第一个字节是标志,在您列出的所有情况下都是 22。这是有道理的,因为它们都来自同一个心率硬件。
这些位是这样分组的: |保留 3 位 | 1 位用于 RR 间隔 | 1 位能量消耗状态 | 2 位传感器接触状态 | 1 位心率值格式 | 22 是二进制的 00010110,即 | 000 | 1 | 0 | 11 | 0 |。
心率值格式位:0(心率值格式设置为 UINT8) 传感器接触状态位:3(支持传感器接触功能并检测到接触) 能量消耗状态位:0(能量消耗字段不存在) RR-Interval 位:1(存在一个或多个 RR-Interval 值)
这意味着接下来的字节是心率(C1 字段),其余字节是 RR-Interval 值,无论它们是什么(C4 字段)。
因此,对于此数据,心率分别为 77、78、79、78。
【讨论】:
你为什么把它移到 3? 是的,你是对的,应该是 7。出于某种原因,我在考虑字符。我已经解决了。 所以从技术上讲你不需要data.getBytes(&bytes, length:data.length)
对吧?如果是这样,bytes
与我的问题中的字节相同吗?
[0, 0, 0, 0] [0, 0, 0, 0, 0, 0] [0, 0, 0, 0] [0, 0, 0, 0, 0, 0] [0, 0, 0, 0]
让我们continue this discussion in chat。【参考方案2】:
如果有人想知道如何计算 RR 值。以第一个数组为例:
[22, 77, 22, 3] in binary is 0001 0110 0100 1101 0001 0110 0000 0011
如果我们把它分成我们有的部分:
Flag (8bit) = 22 or 0001 0110
HRV (8bit) = 77 or 0100 1101
RR (16bit) = 22 & 3 or 0001 0110 0000 0011
因为Bluetooth.org 说订单是 LSO(最低有效八位字节)到 MSO(最高有效八位字节)22 和 3 需要交换离开:
790 or 0000 0011 0001 0110
因为分辨率是 1/1024 秒。 RR 值 = 790/1024 = 0.77s。
【讨论】:
我购买了 Mio Link,我的原始值为: [16, 59, 207, 3] [16, 59, 17, 4] 您如何通过此示例计算 RR 值?完全一样的方式?以上是关于如何在 Swift 中从蓝牙特性中获取数据的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Swift 的后台线程中从 CoreData 中获取未保存的数据?
在 NSURLConnection 中的 Swift 中从 completionHandler 中获取数据