Получить значения (давление крови) от устройства ble в флаттере

Я использовал этот код и пакет flutter_reactive_ble для считывания артериального давления (систолического, диастолического) с моего устройства в мм рт. ст. и частоты пульса в ударах в минуту, но я изо всех сил пытаюсь понять, как это сделать. В моей консоли я получил:

D/BluetoothGatt(21288): setCharacteristicNotification() - uuid: 00002a35-0000-1000-8000-00805f9b34fb Enable: true I/трепетание (21288): Получены необработанные данные для измерения артериального давления: [222, 136, 244, 32, 243, 255, 7, 228, 7, 1, 19, 22, 55, 0, 188, 242, 1, 68, 1]

@override
Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: Text('BLE Scanner'),
        ),
        body: Center(
            child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                    ElevatedButton(
                        onPressed: _scanForDevices,
                        child: Text('Scan for Devices'),
                    ),
                    SizedBox(height: 20),
                    Text('Discovered Devices:'),
                    Expanded(
                        child: ListView.builder(
                            itemCount: devices.length,
                            itemBuilder: (context, index) {
                                final device = devices[index];
                                return ListTile(
                                    title: Text(device.name ?? 'Unknown'),
                                    subtitle: Text(device.id),
                                    onTap: () {
                                        _connectToDevice(device.id);
                                        _subscribeToBloodPressureMeasurement(device.id);
                                    },
                                );
                            },
                        ),
                    ),
                ],
            ),
        ),
    );
}

void _scanForDevices() {
    flutterReactiveBle.scanForDevices(
        withServices: [],
        scanMode: ScanMode.lowLatency,
    ).listen(
        (device) {
            final existingDeviceIndex =
                devices.indexWhere((d) => d.id == device.id);
            if (existingDeviceIndex != -1) {
                setState(() {
                    devices[existingDeviceIndex] = device;
                });
            } else {
                setState(() {
                    devices.add(device);
                });
            }
        },
        onError: (error) {
            print('Error: $error');
        },
    );
}

void _connectToDevice(String deviceId) {
    flutterReactiveBle
        .connectToDevice(
        id: deviceId,
        servicesWithCharacteristicsToDiscover: {
            Uuid.parse('00001810-0000-1000-8000-00805f9b34fb'): [                    // Caractéristique de mesure de la pression artérielle                    Uuid.parse('00002a35-0000-1000-8000-00805f9b34fb'),                    // Caractéristique des fonctionnalités de la pression artérielle                    Uuid.parse('00002a49-0000-1000-8000-00805f9b34fb'),                ],
        },
        connectionTimeout: const Duration(seconds: 2),
    )
        .listen(
        (connectionState) {
            // Gérez les mises à jour de l'état de connexion
            if (connectionState == DeviceConnectionState.connected) {
                print("Connected successfully to device: $deviceId");
                _subscribeToBloodPressureMeasurement(deviceId);
            }
        },
        onError: (error) {
            print('Error connecting to device: $error');
            // Gérez les erreurs éventuelles
        },
    );
}

void _subscribeToBloodPressureMeasurement(String deviceId) {
    final bloodPressureCharacteristic = QualifiedCharacteristic(
        characteristicId: Uuid.parse('00002a35-0000-1000-8000-00805f9b34fb'),
        deviceId: deviceId,
        serviceId: Uuid.parse('00001810-0000-1000-8000-00805f9b34fb'),
    );

    // Souscrire à la caractéristique de mesure de la pression artérielle
    flutterReactiveBle
        .subscribeToCharacteristic(bloodPressureCharacteristic)
        .listen(
        (data) {
            print('Received raw data for blood pressure measurement: $data');
            // Traitez les données de notification ici
        },
        onError: (error) {
            print('Error subscribing to blood pressure measurement: $error');
            // Gérez les erreurs éventuelles lors de l'abonnement
        },
    );
}

}

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
109
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Начните с сервиса: 00001810-0000-1000-8000-00805f9b34fb. Это 16-битный шаблон UUID, поэтому фактическое число, которое вас интересует, — 0x1810.

Посмотрите это в документе Назначенные номера и обнаружите, что это Служба артериального давления.

Перейдите на страницу Технические характеристики и найдите последнюю версию.

Прочтите этот документ. Серьезно, люди так теряются, потому что не читают документацию.

Тем не менее, эта конкретная спецификация ужасна. Просто ужас. В нем нет подробного объяснения формата, но рассказывается, как работает услуга.

При этом мы ищем характерный UUID 0x2a35, который является показателем артериального давления. Как я уже сказал, этот служебный документ ужасен и плохо его объясняет, но он хорошо документирован в YAML.

Итак, имея это в виду, давайте декодируем.

Флаги (1 байт)

222 = b11011110 : чтение от младшего к старшему биту, это означает:

  • Давление в мм рт.ст.
  • Временная метка включена
  • Частота пульса включена
  • Идентификатор пользователя включен
  • Статус включен
  • И в зарезервированной секции есть установленные биты (110, должно быть 000). Это странно. Это может означать, что используется неочевидное, но документированное расширение, или это может означать, что производитель делает что-то особенное. Вы хотели бы проверить их документы.

Систолическое мм рт. ст. (medfloat16, 2 байта, прямой порядок байтов)

136, 244 -> 116

Здесь используется формат medfloat16, также называемый sfloat, и представляет собой 16-битное число с плавающей запятой. Пример расчета см. в разделе Как извлечь значение SFLOAT из данных Bluetooth LE для пульсоксиметра 1822 с помощью CoreBluetooth.

Диастолическое мм рт.ст. (medfloat16)

32, 243 -> 80

КАРТА (medfloat16)

255, 7 -> NaN (так что на самом деле это недоступно)

Временная метка (7 байт date_time структура)

228, 7 -> 2020 (7<<8 + 228, потому что это прямой порядок байтов)

1, 19, 22, 55, 0 -> 19 янв, 22:55:00

Идентификатор пользователя (1 байт)

1

Статус (2 байта)

0001 0100 0100

  • Нерегулярный пульс
  • Зарезервированные биты, которые должны быть равны нулю, — это 000101. Опять же, это может быть документированное расширение, о котором я не знаю, или собственное расширение. Вам придется проверить документы.

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

Спасибо за ответ. Не могли бы вы рассказать мне, как вы это посчитали? Как вы получили 116 из 136, 244?

al ice 18.03.2024 02:50

Посмотрите ссылку в этом разделе. «Пример вычисления см.…»

Rob Napier 18.03.2024 13:32

Другие вопросы по теме