我最近一直在玩CoreBluetooth,虽然我可以连接到某些设备,但我似乎无法正确读取数据(特征值)。
现在我正在连接Wahoo BT Heartrate显示器,我收到所有信号,但我无法将数据变成任何合理的信息。 (是的,我知道有一个API,但是我试图在没有它的情况下进行连接,以便正确地使用CoreBluetooth)。
到目前为止,我还没能将NSData(characteristic.value)变成任何合理的东西。如果您有任何关于如何理解这些数据的建议,那将是非常令人沮丧的。
答案 0 :(得分:2)
在某些代码下方,可以完全解析所有HeartRate测量特征数据。
如何处理数据取决于以下几点:
以下是Heart_rate_measurement characteristic
的实际规格// Instance method to get the heart rate BPM information
- (void) getHeartBPMData:(CBCharacteristic *)characteristic error:(NSError *)error
{
// Get the BPM //
// https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml //
// Convert the contents of the characteristic value to a data-object //
NSData *data = [characteristic value];
// Get the byte sequence of the data-object //
const uint8_t *reportData = [data bytes];
// Initialise the offset variable //
NSUInteger offset = 1;
// Initialise the bpm variable //
uint16_t bpm = 0;
// Next, obtain the first byte at index 0 in the array as defined by reportData[0] and mask out all but the 1st bit //
// The result returned will either be 0, which means that the 2nd bit is not set, or 1 if it is set //
// If the 2nd bit is not set, retrieve the BPM value at the second byte location at index 1 in the array //
if ((reportData[0] & 0x01) == 0) {
// Retrieve the BPM value for the Heart Rate Monitor
bpm = reportData[1];
offset = offset + 1; // Plus 1 byte //
}
else {
// If the second bit is set, retrieve the BPM value at second byte location at index 1 in the array and //
// convert this to a 16-bit value based on the host’s native byte order //
bpm = CFSwapInt16LittleToHost(*(uint16_t *)(&reportData[1]));
offset = offset + 2; // Plus 2 bytes //
}
NSLog(@"bpm: %i", bpm);
// Determine if EE data is present //
// If the 3rd bit of the first byte is 1 this means there is EE data //
// If so, increase offset with 2 bytes //
if ((reportData[0] & 0x03) == 1) {
offset = offset + 2; // Plus 2 bytes //
}
// Determine if RR-interval data is present //
// If the 4th bit of the first byte is 1 this means there is RR data //
if ((reportData[0] & 0x04) == 0)
{
NSLog(@"%@", @"Data are not present");
}
else
{
// The number of RR-interval values is total bytes left / 2 (size of uint16) //
NSUInteger length = [data length];
NSUInteger count = (length - offset)/2;
NSLog(@"RR count: %lu", (unsigned long)count);
for (int i = 0; i < count; i++) {
// The unit for RR interval is 1/1024 seconds //
uint16_t value = CFSwapInt16LittleToHost(*(uint16_t *)(&reportData[offset]));
value = ((double)value / 1024.0 ) * 1000.0;
offset = offset + 2; // Plus 2 bytes //
NSLog(@"RR value %lu: %u", (unsigned long)i, value);
}
}
}
答案 1 :(得分:1)
那么,您应该实施使用心率服务的心率配置文件(请参阅here)。如果查看Heart Rate Service Specifications,您将看到Heart Rate Measurement Characteristic的格式根据数据包中最低有效八位字节中设置的标志而变化。
这意味着您需要设置代码来处理动态数据包大小。
所以你的一般过程是:
value
属性的第一个字节并检查它:
使用NSData - 特别是使用Core蓝牙 - 需要一些时间来习惯,但是一旦你掌握了这个概念就没那么糟。
祝你好运!答案 2 :(得分:0)
唉...
当您阅读特征的值时,您需要做什么:
NSData *data = [characteritic value];
theTypeOfTheData value;
[data getByte:&value lenght:sizeof(value)];
但是, theTypeOfTheData 可以是设备开发人员的想法。所以它可能是UInt8,UInt16或结构(有或没有位域)...你必须通过联系设备的开发人员或查看是否有一些文档来获取信息。
例如,我的同事根据需要使用消耗较少空间的数据类型(因为设备没有无限内存)。
查看特征的描述符。它可能指出数据的类型。