flutterbluetooth-lowenergyiotuuiddevice

get values(pressure blood) from ble device in flutter


I used this code and utilized the flutter_reactive_ble package to read the blood pressure (systolic, diastolic) from my device in mmHg and pulse rate in bpm, but I am struggling to figure out how to do it , In my console, I received :

D/BluetoothGatt(21288): setCharacteristicNotification() - uuid: 00002a35-0000-1000-8000-00805f9b34fb enable: true I/flutter (21288): Received raw data for blood pressure measurement: [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
        },
    );
}

}


Solution

  • Start with the service: 00001810-0000-1000-8000-00805f9b34fb. This is the 16-bit UUID template, so the actual number you care about is 0x1810.

    Look that up in the Assigned Numbers doc, and find that this is the Blood Pressure Service.

    Go the Specifications page and pull up the latest version.

    Read this document. Seriously, people get so lost because they won't read the docs.

    That said, this particular spec is terrible. Just terrible. It doesn't carefully explain the format, but it does tell you how the service works.

    With that, we look up the characteristic UUID, 0x2a35, which is the Blood Pressure Measurement. Like I said, this service doc is terrible and doesn't explain it well, but it is documented well in the YAML.

    So, with that in hand, let's decode.

    Flags (1 byte)

    222 = b11011110 : Reading from LSB to MSB, this indicates:

    Systolic mmHg (medfloat16, which is 2 bytes, little endian)

    136, 244 -> 116

    The format here, medfloat16, also called sfloat, is a 16-bit floating point. For an example of computing it, see How to extract SFLOAT value from Bluetooth LE data for 1822 PulseOximeter using CoreBluetooth. Specifically see the code at https://stackoverflow.com/a/51391743/97337.

    Diastolic mmHg (medfloat16)

    32, 243 -> 80

    MAP (medfloat16)

    255, 7 -> NaN (So this isn't actually available)

    Timestamp (7 byte date_time struct)

    228, 7 -> 2020 (7<<8 + 228 because it's little endian)

    1, 19, 22, 55, 0 -> Jan 19, 22:55:00

    Pulse rate (medfloat16)

    188, 242 -> 70

    User ID (1 byte)

    1

    Status (2 bytes)

    0001 0100 0100

    BTW, of some use is the Blood Pressure Profile specification, which is a collection of services, including the Blood Pressure Service, that most blood pressure reporting devices would include. It can be useful in order to know what else is likely to be available, and provides broader rules on how discovery works, etc. In practice, most people working on mobile apps can just skip to the service docs, but it's nice to know the profile docs exist.