蓝牙低功耗,如何解析R-R间隔值?

时间:2013-07-02 09:39:01

标签: iphone bluetooth-lowenergy

我的应用程序正在从智能心脏设备接收信息。现在我可以看到脉搏值。你能帮我解析R-R Interval值吗?如何检查设备是否支持R-R间隔值?

您的任何建议

由于

5 个答案:

答案 0 :(得分:7)

您检查了Bluetooth spec吗?下面的示例代码在C#中,但我认为它显示了解析每个心率包中数据的方法。

//first byte of heart rate record denotes flags
byte flags = heartRateRecord[0];

ushort offset = 1;

bool HRC2 = (flags & 1) == 1;
if (HRC2) //this means the BPM is un uint16
{
    short hr = BitConverter.ToInt16(heartRateRecord, offset);
    offset += 2;
}
else //BPM is uint8
{
    byte hr = heartRateRecord[offset];
    offset += 1;
}

//see if EE is available
//if so, pull 2 bytes
bool ee = (flags & (1 << 3)) != 0;
if (ee)
    offset += 2;

//see if RR is present
//if so, the number of RR values is total bytes left / 2 (size of uint16)
bool rr = (flags & (1 << 4)) != 0;
if (rr)
{
    int count = (heartRateRecord.Length - offset)/2;
    for (int i = 0; i < count; i++)
    {
        //each existence of these values means an R-Wave was already detected
        //the ushort means the time (1/1024 seconds) since last r-wave
        ushort value = BitConverter.ToUInt16(heartRateRecord, offset);

        double intervalLengthInSeconds = value/1024.0;
        offset += 2;
    }
}

答案 1 :(得分:2)

这篇文章有点陈旧但尚未给出完整答案。 当我遇到这篇文章时它最终帮助了我,我想分享我的最终代码。希望它能帮助别人。

Daniel Judge提供的代码实际上是正确的,但正如他已经写过的那样,它是C#。由于Daniel Judge的代码考虑到一条消息中可能有两个以上的RR值,因此HIs代码与Simon M最终提出的代码相比要好一些。 这是实际的spec of the Heart_rate_measurement characteristic

我已将Daniel Judge的代码翻译成Objective-C:

// 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);

        }

    }

}

答案 2 :(得分:0)

编辑: 这项工作对我来说,我得到正确的rr值: 在某些情况下,您可以同时为rr。

找到两个值
- (void) updateWithHRMData:(NSData *)datas {

    const uint8_t *reportData = [datas bytes];

    uint16_t bpm = 0;
    uint16_t bpm2 = 0;

    if ((reportData[0] & 0x04) == 0)
    {
        NSLog(@"%@", @"Data are not present");
    }
    else
    {

        bpm = CFSwapInt16LittleToHost(*(uint16_t *)(&reportData[2]));

        bpm2 = CFSwapInt16LittleToHost(*(uint16_t *)(&reportData[4]));

        if (bpm != 0 || bpm2 != 0) {

                NSLog(@"%u", bpm);

                if (bpm2 != 0) {
                    NSLog(@"%u", bpm2);
                }

        }

    }

}

答案 3 :(得分:0)

在@Brabbeldas解决方案中,我必须使用不同的标志来获得rri值。但可能取决于使用的设备。

if ((reportData[0] & 0x10) == 0)

而不是

if ((reportData[0] & 0x04) == 0)

答案 4 :(得分:0)

在&#34; C&#34;

中解析心率参数

我将示例应用程序上传到GitHub Heart-Rate-Bluegiga

{{1}}