Как получить данные из характеристики bluetooth в Swift

Рядом со мной сейчас находится устройство Polar h7 (это BTLE ), и у меня все работает, но я не понимаю, как получить BPM нашего characteristic.value теперь, когда он обновляется. Мне нужно преобразовать несколько байтов в удары в минуту...

Мое периферийное устройство обновляется:

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, значение пульса будет uint8, а если 1 тогда это uint16, и я могу получить BPM от этого.
Как узнать, является ли байт 0 1 или 0? Как превратить это в uint8 или uint16. И если я это сделаю, я получу BPM прямо или мне нужно будет сделать что-то еще? Прямо сейчас BPM возвращается как что-то вроде <16447d03>, что имеет смысл.


person Johnston    schedule 22.08.2014    source источник


Ответы (2)


Кажется, это должно быть достаточно просто, но попытка подтвердить то, что вы говорите. Завершается ли «байты» значением «16447d03»? Это указатель на данные, а не сами данные, поэтому вам нужно сделать что-то вроде этого, чтобы получить фактическое значение:

var data = characteristic.value
var values = [UInt8](count:data.length, repeatedValue:0)
data.getBytes(&values, length:data.length)

Здесь «значения» — это массив, содержащий фактические значения.

Из частного обсуждения, которое у нас было, вы перечислили вывод как:

[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.

person Gary Makin    schedule 22.08.2014
comment
Почему ты перевел его на 3? - person Johnston; 23.08.2014
comment
Да, ты прав, должно было быть 7. Я почему-то думал о символах. Я исправил это. - person Gary Makin; 23.08.2014
comment
Итак, технически вам не нужно data.getBytes(&bytes, length:data.length), верно? Если да, то это bytes одни и те же байты в моем вопросе? - person Johnston; 23.08.2014
comment
Давайте продолжим обсуждение в чате. - person Gary Makin; 23.08.2014
comment
Я неправильно понял ваш вопрос о data.getBytes(&bytes, length:data.length). При редактировании своего ответа я переименовал байты в значения, но пропустил эту строку. Извиняюсь. - person Gary Makin; 23.08.2014
comment
версия swift3: var values = [UInt8](repeating: 0, count: data.count); data.copyBytes(to: &values, count: data.count) - person nebiros; 17.01.2017

Если кому-то интересно, как рассчитать значение 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,77 с.

person Eric Hodgins    schedule 30.05.2016
comment
Я купил Mio Link, и мое необработанное значение: [16, 59, 207, 3] [16, 59, 17, 4] Как рассчитать значение RR в этом примере? Точно так же? - person jeroenvdbergh; 08.02.2017