Как прочитать и преобразовать характеристику Bluetooth из байтовых данных в правильные значения (Bluetooth для флаттера) - PullRequest
4 голосов
/ 27 мая 2019

Мне нужно прочитать и записать некоторые значения в тренажер Bike Smart с BLE (Bluetooth Low Energy), который используется с Flutter.Когда я пытаюсь прочитать значения из характеристики GATT org.bluetooth.characteristic.supported_power_range (находится на сайте bluetooth.org https://www.bluetooth.com/specifications/gatt/characteristics/), я получаю возвращаемое значение Int List [0,0,200,0,1,0].

Характеристика GATT гласит, что для мин., Макс. Есть 3 поля sint16.и размер шага Ватт (Мощность).

Порядок передачи байтов также говорит о том, что наименее значимый октет передается первым.

Я предполагаю, что 3 параметра возвращаются в массиве Int с8-битное значение каждый.Но я не могу интерпретировать 200 для максимальной настройки мощности.Потому что умный тренер должен обеспечить макс.Сопротивление 2300 Вт (ELITE Drivo https://www.elite -it.com / de / produkte / home-trainer / rollentrainer-интерактив / drivo )

Вывод результатов из этого фрагмента кода:

device.readCharacteristic(savedCharacteristics[Characteristics.SUPPORTED_POWER_RANGE]).then((List<int> result) {
  result.forEach((i) {
    print(i.toString());
  });
});
// result: [0,0,200,0,1,0]

Может быть, кто-то из вас знает, как интерпретировать двоичные значения / hex / dec выходных данных характеристики flutter_blue.Или некоторые подсказки были бы отличными

Edit

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

Возвращаемое значение [0,0,200,0,1,0] было для поддерживаемого уровня сопротивления .(что составляет 20%, а 200 показывает 20% с разрешением 0,1, как описано в спецификации GATT) Max resistance Level with a resolution of 0.1

Я также получил возвращаемое значение для поддерживаемый уровень мощности , который был [0,0,160,15,1,0].Теперь решение о том, как читать 2 байта максимального уровня мощности: вы получаете 160,15 спецификации LSO (наименее значимый октет первый, не путайте его с младшим значащим младшим битом бит первый).На самом деле вы должны прочитать это как 15 160.Теперь посчитайте с первым байтом 15 * 256 + 160 = 4000 , и это будет правильная максимальная поддерживаемая мощность тренера, как в таблице.

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

Ответы [ 2 ]

2 голосов
/ 06 июня 2019

У меня была такая же проблема при подключении к Polar H10 для восстановления интервалов ЧСС и ЧД. Может быть, это не на 100% то же самое, но я думаю, что мой случай поможет вам решить ваш.

Я получаю тот же список, что и вам, вот эти два примера:

  1. [0,60]
  2. [16,61,524,2]

Рассматривая технические характеристики Службы сердечного ритма Bluetooth GATT Я понял, что каждый элемент полученного списка соответствует 1 байту данных, передаваемых признаком, на который вы подписаны. Для этой услуги первый байт, то есть первый элемент списка, имеет несколько флагов, указывающих, существует ли значение RR после значения HR (16) или нет (0). Это всего лишь два случая из множества различных, которые могут возникать в зависимости от значений флагов, но я думаю, что это показывает, насколько важным может быть этот первый байт.

После этого значение HR кодируется как целое число без знака с 8 битами (UINT8), то есть значения HR соответствуют второму элементу списков, показанных ранее. Однако интервал RR кодируется как целое число без знака с 16 битами (UINT16), поэтому он усложняет перевод этих двух последних элементов списка # 2 [16,61, 524,2 ], потому что мы для получения этого значения следует использовать 16 бит, а байты расположены не в правильном порядке.

Это когда мы импортируем библиотеку dart: typed_data

import 'dart:typed_data';

...

_parseHr(List<int> value) {

// First sort the values in the list to interpret correctly the bytes
List<int> valueSorted = [];
valueSorted.insert(0, value[0]);
valueSorted.insert(1, value[1]);
for (var i=0; i< (value.length-3); i++) {
  valueSorted.insert(i+2, value[i+3]);
  valueSorted.insert(i+3, value[i+2]);
}

// Get flags directly from list
var flags = valueSorted[0];

// Get the ByteBuffer view of the data to recode it later
var buffer = new Uint8List.fromList(valueSorted).buffer; // Buffer bytes from list

if (flags == 0) {
  // HR
  var hrBuffer = new ByteData.view(buffer, 1, 1); // Get second byte
  var hr = hrBuffer.getUint8(0);                  // Recode as UINT8
  print(hr);
}

if (flags == 16) {
  // HR
  var hrBuffer = new ByteData.view(buffer, 1, 1); // Get second byte
  var hr = hrBuffer.getUint8(0);                  // Recode as UINT8

  // RR (more than one can be retrieved in the list)
  var nRr = (valueSorted.length-2)/2; // Remove flags and hr from byte count; then split in two since RR is coded as UINT16
  List<int> rrs = [];
  for (var i = 0; i < nRr; i++) {
    var rrBuffer = new ByteData.view(buffer, 2+(i*2), 2); // Get pairs of bytes counting since the 3rd byte
    var rr = rrBuffer.getUint16(0);                       // Recode as UINT16
    rrs.insert(i,rr);
  }
  print(rrs);
}

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

2 голосов
/ 28 мая 2019

Вы можете использовать мой пакет byte_data_wrapper , чтобы преобразовать эти данные в десятичное значение, которое вы можете понять:

  1. Получить буфер:
import 'dart:typed_data';

final buffer = Uint16List.fromList(result).buffer;
  1. Создайте byteDataCreator:
// Don't forget to add it to your pubspec.yaml
//dependencies:
//  byte_data_wrapper:
//    git: git://github.com/Taym95/byte_data_wrapper.git

import 'byte_data_wrapper/byte_data_wrapper.dart';

final byteDataCreator = ByteDataCreator.view(buffer);
  1. Получите ваши данные:
// You can use getUint8() if valeu is Uint8
final min = byteDataCreator.getUint16();
final max = byteDataCreator.getUint16();
final stepSize = byteDataCreator.getUint16();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...