Декодирование данных Bluetooth из характеристики данных для внутреннего велосипеда

#javascript #bluetooth #bluetooth-lowenergy

#javascript #bluetooth #bluetooth -низкое энергопотребление

Вопрос:

Я пытаюсь использовать сервис фитнес-тренажеров характеристику данных для внутреннего велосипеда, чтобы получить данные о частоте вращения. Используя приложение nRF Connect для Android, я вижу, что данные есть, образец данных:

 inst. speed  8.5km/h
inst. cadence 45.0 per min
inst. power 8W
Heart rate 0 bpm

//same data as hex 44 02 52 03 5A 00 08 00 00 
  

Глядя на спецификацию для характеристики данных для внутреннего велосипеда, говорится, что поле флага должно быть закодировано как 16 бит (спецификация), но когда я пытаюсь что-то вроде,

 const characteristic = await char.startNotifications()
characteristic.addEventListener('characteristicvaluechanged', (data) => {
  const flags = data.getUint16(0, true);
    
  console.table([ flags amp; 0x0,flags amp; 0x1, flags amp; 0x2,flags amp; 0x3, flags amp; 0x4,flags amp; 0x5, flags amp; 0x6,flags amp; 0x7, flags amp; 0x8,flags amp; 0x9, flags amp; 0x10,flags amp; 0x11, flags amp; 0x12,flags amp; 0x13, flags amp; 0x14,flags amp; 0x15, flags amp; 0x16])
});
  

который выводит:

введите описание изображения здесь

Данные не совпадают с приведенными выше данными из nRF Connect Android. Кто-нибудь знает, почему предоставленные данные и значения на скриншоте не совпадают и как я могу получить остальные данные?

Ответ №1:

Ваша побитовая операция с полем флагов не выглядит корректной.

Я сделал следующее:

 var ble_bytes = new Uint8Array([0x44, 0x02, 0x52, 0x03, 0x5A, 0x00, 0x08, 0x00, 0x00]).buffer;
var view = new DataView(ble_bytes)

flags = view.getUint16(0, true);
var i;
for (i = 0; i < 16; i  ) {
  console.log('flags['   i   '] = '   (!!(flags >>> i amp; 1)));
}
console.log('Instantaneous Speed = '   view.getUint16(2, true) / 100)
console.log('Instantaneous Cadence = '   view.getUint16(4, true) * 0.5)
console.log('Instantaneous Power  = '   view.getInt16(6, true))
console.log('Heart Rate  = '   view.getUint8(8, true))

  

Что дало мне вывод:

 > "flags[0] = false"
> "flags[1] = false"
> "flags[2] = true"
> "flags[3] = false"
> "flags[4] = false"
> "flags[5] = false"
> "flags[6] = true"
> "flags[7] = false"
> "flags[8] = false"
> "flags[9] = true"
> "flags[10] = false"
> "flags[11] = false"
> "flags[12] = false"
> "flags[13] = false"
> "flags[14] = false"
> "flags[15] = false"
> "Instantaneous Speed = 8.5"
> "Instantaneous Cadence = 45"
> "Instantaneous Power  = 8"
> "Heart Rate  = 0"
  

Что указывает на наличие Instantaneous Cadence present , Instantaneous Power present , Heart Rate present . Поле Instantaneous Speed всегда присутствует.

Я преобразовал байты в соответствии с этим, и, похоже, они совпадают с тем, что вы получили из приложения nRF Connect.

Комментарии:

1. Спецификация обслуживания тренажера показывает, что полярность бита 2 обратная, что истинное значение указывает на отсутствие мгновенной частоты вращения.

2. @TomHarrington в соответствии с XML , с bit 2 1 тем, что требуется c3 , который является Instantaneous Cadence . Я согласен, что это не соответствует спецификации обслуживания тренажеров. Вероятно, вам следует поднять его с помощью сигнала Bluetooth, который является правильным.

3. Спасибо, я не заметил, что спецификации PDF и XML противоречат друг другу.

4. Сигналы Bluetooth заменили файлы XML двумя документами. 1) 16-bit UUIDs при bluetooth.com/specifications/assigned-numbers и 2) GATT Specification Supplement при bluetooth.com/specifications/specs . Согласно этому последнему документу flags for Indoor Bike Data имеет Instantaneous Power present бит as 6 и бит Expended Energy present as 8