Как я могу получить значение измерения сердечного ритма от Polar H10 в iOS, используя Swift и Core Bluetooth? - PullRequest
0 голосов
/ 22 февраля 2020

Я использую Polar H10 в качестве монитора сердечного ритма, и я хотел бы получить значения, которые находятся в характеристиках измерения сердечного ритма c в iOS, используя Swift и Core Bluetooth.

Вот код в соответствующем методе обратного вызова CBPeripheralDelegate:

func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {

    print("didUpdateValueFor")

    if let error = error {
        print("error:", error)
    }

    guard let value = characteristic.value else {
        return
    }

    print("value:", value)

    guard let stringValue = String(data: value, encoding: .utf8) else {
        return
    }

    print("string value:", stringValue)

}

Официальная веб-страница Bluetooth для этого Измерения пульса показывает эту неформатированную информацию:

Обязательное 8-битное примечание. Формат поля «Значение измерения пульса» зависит от бита 0 поля «Флаги». C1 uint8 org.bluetooth.unit.period.beats_per_minute Примечание. Формат поля значения измерения частоты сердечных сокращений зависит от бита 0 поля Flags. C2 uint16 org.bluetooth.unit.period.beats_per_minute Наличие поля «Расход энергии» зависит от бита 3 поля «Флаги». C3 uint16 org.bluetooth.unit.energy.joule C4 uint16 org.bluetooth.unit.time.second Разрешение 1/1024 секунды Поля в приведенной выше таблице расположены в порядке от LSO до MSO. Где LSO = наименее значимый октет и MSO = наиболее значимый октет.

Я не могу понять, что означает документация. В частности, я не понимаю, к чему относятся C1, C2, C3 и C4.

Значение c .value - это тип данных. Что мне делать с этим объектом данных? Как получить нужные мне значения? Во-первых, я хочу получить значение RR.

Существуют похожие сообщения, подобные этим, но они мне не помогают, потому что они используют разные инструменты и другой язык, или у них нет хороших ответов.

Обновление:

Я с тех пор понял, что страница в Измерение пульса является xml файлом. Я смог получить необходимую информацию из этого файла после того, как открыл его с помощью приложения, которое могло бы показать его. Первый раз, когда я посмотрел на это, был в Сафари. Он не показывает xml файлов хорошо. Вот файл:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 2011 Bluetooth SIG, Inc. All rights reserved. -->
<Characteristic xsi:noNamespaceSchemaLocation="http://schemas.bluetooth.org/Documents/characteristic.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" type="org.bluetooth.characteristic.heart_rate_measurement" uuid="2A37" name="Heart Rate Measurement">
    <InformativeText>
    </InformativeText>
    <Value>
        <Field name="Flags">
            <Requirement>Mandatory</Requirement>
            <Format>8bit</Format>

            <BitField>
                <Bit index="0" size="1" name="Heart Rate Value Format bit">
                    <Enumerations>
                        <Enumeration key="0" value="Heart Rate Value Format is set to UINT8. Units: beats per minute (bpm)" requires="C1" />
                        <Enumeration key="1" value="Heart Rate Value Format is set to UINT16. Units: beats per minute (bpm)" requires="C2" />
                    </Enumerations>
                </Bit>
                <Bit index="1" size="2" name="Sensor Contact Status bits">
                    <Enumerations>
                        <Enumeration key="0" value="Sensor Contact feature is not supported in the current connection" />
                        <Enumeration key="1" value="Sensor Contact feature is not supported in the current connection" />
                        <Enumeration key="2" value="Sensor Contact feature is supported, but contact is not detected" />
                        <Enumeration key="3" value="Sensor Contact feature is supported and contact is detected" />
                    </Enumerations>
                </Bit>

                <Bit index="3" size="1" name="Energy Expended Status bit">
                    <Enumerations>
                        <Enumeration key="0" value="Energy Expended field is not present" />
                        <Enumeration key="1" value="Energy Expended field is present. Units: kilo Joules" requires="C3"/>
                    </Enumerations>
                </Bit>
                <Bit index="4" size="1" name="RR-Interval bit">
                    <Enumerations>
                        <Enumeration key="0" value="RR-Interval values are not present." />
                        <Enumeration key="1" value="One or more RR-Interval values are present." requires="C4"/>
                        </Enumerations>
                </Bit>
                <ReservedForFutureUse index="5" size="3"></ReservedForFutureUse>
                </BitField>
        </Field>
        <Field name="Heart Rate Measurement Value (uint8)">
              <InformativeText>
                Note: The format of the Heart Rate Measurement Value field is dependent upon bit 0 of the Flags field.
              </InformativeText>
            <Requirement>C1</Requirement>
            <Format>uint8</Format>
            <Unit>org.bluetooth.unit.period.beats_per_minute</Unit>

        </Field>    

         <Field name="Heart Rate Measurement Value (uint16)">
              <InformativeText>
                Note: The format of the Heart Rate Measurement Value field is dependent upon bit 0 of the Flags field.
              </InformativeText>
            <Requirement>C2</Requirement>
            <Format>uint16</Format>
            <Unit>org.bluetooth.unit.period.beats_per_minute</Unit>

        </Field>       

        <Field name="Energy Expended">
            <InformativeText>The presence of the Energy Expended field is dependent upon bit 3 of the Flags field.</InformativeText>
            <Requirement>C3</Requirement>
            <Format>uint16</Format>
            <Unit>org.bluetooth.unit.energy.joule</Unit>

        </Field>
        <Field name="RR-Interval">
            <InformativeText>
               <!-- The presence of the RR-Interval field is dependent upon bit 4 of the Flags field. 
                <p>The RR-Interval value represents the time between two R-Wave detections.</p> 

                <p>Because several RR-Intervals may be measured between transmissions of the HEART RATE MEASUREMENT characteristic, 
                multiple RR-Interval sub-fields may be present in the characteristic. The number of RR-Interval sub-fields present 
                is determined by a combination of the overall length of the characteristic and whether or not the characteristic contains 
                the Energy Expended field.</p>

                <p>Where there are multiple RR-Interval values transmitted in the HEART RATE MEASUREMENT characteristic, the field uses the following format:</p>
                <p>RR-Interval Value 0 (LSO...MSO), RR-Interval Value 1 (LSO...MSO), RR-Interval Value 2 (LSO...MSO), RR-Interval Value n (LSO...MSO).</p>
                <p>Where the RR-Interval Value 0 is older than the RR-Interval Value 1.</p>
                <p>RR-Interval Value 0 is transmitted first followed by the newer measurements.</p>-->

            </InformativeText>
            <Requirement>C4</Requirement>
            <Format>uint16</Format>
            <Unit>org.bluetooth.unit.time.second</Unit>
            <Description>Resolution of 1/1024 second</Description>



        </Field>
    </Value>
   <Note> <p>The fields in the above table are in the order of LSO to MSO. Where LSO = Least Significant Octet and MSO = Most Significant Octet.</p>
   </Note>
</Characteristic>

1 Ответ

1 голос
/ 22 февраля 2020

Во-первых, вам нужно преобразовать данные значения c характеристики в массив UInt8, затем вам нужно проверить, что ваш датчик ЧСС выдает значение, по какому индексу. Я использую следующий код в моем проекте, и он работает нормально. Надеюсь, это вам тоже поможет.

var heartRate: Int = 0
guard let characteristicData = characteristic.value else { return }
let byteArray = [UInt8](characteristicData)
let firstBitValue = byteArray[0] & 0x01
if firstBitValue == 0 {
    // Heart Rate Value Format is in the 2nd byte
    heartRate = Int(byteArray[1])
} else {
    // Heart Rate Value Format is in the 2nd and 3rd bytes
    heartRate = (Int(byteArray[2]) << 8) + Int(byteArray[1])
}
print("heart rate", heartRate)

Введите приведенный выше код в метод didUpdateValueFor CBPeripheralDelegate и попробуйте получить значение от вашего датчика сердечного ритма.

...