Мне трудно получить действительное значение из характеристик HR. Я явно неправильно обрабатываю значения в Dart.
Пример данных:
List<int> value = [22, 56, 55, 4, 7, 3];
Поле флагов: Я преобразовываю первый элемент в основном массиве байтов в двоичный, чтобы получить флаги
22 = 10110 (as binary)
это заставляет меня поверить, что это U16 (бит [0] == 1)
Значение ЧСС:
Поскольку он 16-битный, я пытаюсь получить байты в индексах 1 и 2. Затем я пытаюсь буферизовать их в ByteData. Оттуда я конвертирую их в Uint16 с Endian, установленным на Little. Это дает мне значение 14136. Очевидно, я упускаю что-то фундаментальное в том, как это должно работать.
Буду очень признателен за любую помощь в прояснении того, что я не понимаю в том, как обрабатывать 16-битные значения BLE.
Спасибо.
/*
Constructor - constructs the heart rate value from a BLE message
*/
HeartRate(List<int> values) {
var flags = values[0];
var s = flags.toRadixString(2);
List<String> flagsArray = s.split("");
int offset = 0;
//Determine whether it is U16 or not
if (flagsArray[0] == "0") {
//Since it is Uint8 i will only get the first value
var hr = values[1];
print(hr);
} else {
//Since UTF 16 is two bytes I need to combine them
//Create a buffer with the first two bytes after the flags
var buffer = new Uint8List.fromList(values.sublist(1, 3)).buffer;
var hrBuffer = new ByteData.view(buffer);
var hr = hrBuffer.getUint16(0, Endian.little);
print(hr);
}
}
Спасибо, Роб, я ценю ответ. Возможно, я неправильно получаю данные (в этом много нового), но я получаю их из примера проекта "flutter_blue". Вот что печатает на экран, когда дергаю характеристику (0x2A37). Вот еще один, намного короче (который может быть более надежным) [22, 56, 55, 4, 7, 3]. Учитывая, что биты LSB, означает ли это, что бит 8vs16 на самом деле равен 0 в моем примере? Я добавил полный список в OP. Пожалуйста, дайте мне знать, если вам нужно что-нибудь еще.
Ваши обновленные данные выглядят намного лучше. Вот как это расшифровать, и процесс, который вы использовали бы, чтобы понять это самостоятельно с нуля.
Сайт Bluetooth был недавно реорганизован (~ 2020 г.), и, в частности, они избавились от некоторых средств просмотра документов, что значительно усложняет поиск и чтение IMO. Вся документация находится в документе Heart Rate Service (HRS), ссылка на который находится на главной странице GATT , но для анализа формата лучшим известным мне источником является XML для org.bluetooth. характеристика.сердечный ритм_измерение. (После реорганизации я не знаю, как можно найти эту страницу без поиска. Кажется, она больше не связана.)
Биты нумеруются от LSB (0) до MSB (7).
Значение RR-интервалов объясняется в документе HRS, указанном выше. Похоже, вам просто нужно значение частоты сердечных сокращений, поэтому я не буду вдаваться в них здесь.
Поскольку бит 0 флагов равен 0, это количество ударов в минуту. 56.
Вы, вероятно, не заботитесь об этом, но здесь есть два значения UINT16 (может быть произвольное количество значений RR-Interval). BLE всегда имеет обратный порядок байтов, поэтому [55, 4] равно 1079 (55 + 4<<8), а [7, 3] равно 775 (7 + 3<<8).
Я считаю, что документы немного сбивают с толку. XML предполагает, что эти значения указаны в секундах, но в комментариях говорится: «Разрешение 1/1024 секунды». Нормальным способом выразить это было бы <BinaryExponent>-10</BinaryExponent>
, и я уверен, что они имели в виду именно это. Итак, это будут:
Роб, я действительно ценю время, которое вы потратили, чтобы четко объяснить это, и вы правы! Документация не так ясна, как эта. Большое спасибо! И так, чтобы я знал, что я на 100% ясен... Если бы первый флаг был 1, тогда я бы сделал ту же самую логику, чтобы получить BPM? hr = (значения[1] + значения[2] << 8 Верно ли это?
Точно. Я не знаю, насколько это распространено за пределами медицинских устройств (поскольку 8 бит дадут вам 255 ударов в минуту, и я надеюсь, что в этот момент задействуется врач), но вполне возможно, что вы столкнетесь с этим.
Привет @RobNapier, я до сих пор не понимаю, как интерпретировать значение частоты сердечных сокращений в байте 1. По мере увеличения значения оно переходит в отрицательные значения, такие как 126, 127, -127, -126, -125, ... Я поднял вопрос по этой теме. Может быть, вы можете пролить свет на это. Спасибо! -> stackoverflow.com/questions/67024800/…
@Emanuel UINT8 означает 8-битное целое число без знака, поэтому, если вы видите отрицательные значения, это просто означает, что вы привели его к целочисленному типу данных со знаком. Убедитесь, что вы используете беззнаковое целое число.
Я пытаюсь сделать сопутствующее приложение для своих умных часов. Я пытаюсь получить частоту сердечных сокращений и ударов в минуту через устройство. Я не знаю, что и с чего начать. Если бы кто-то из вас был готов помочь, было бы здорово.
Эти данные имеют неправильную длину. Если вы читаете org.bluetooth.characteristic.heart_rate_measurement, полезная нагрузка должна иметь длину от 2 до 5 байт (если только нет RR, чего я здесь не вижу), в зависимости от флагов. Поэтому я сильно подозреваю, что вы создаете
value
неправильно. Обратите внимание, что биты отсчитываются от LSB, а не от MSB (поэтому вы читаете их в обратном порядке). BLE также всегда имеет обратный порядок байтов, поэтому вам нужно сдвинуть второй байт на 8 бит, если вы читаете uint16. Но давайте начнем с того, откуда вы берете данные, потому что это выглядит неправильно.