修正flutter中原始数据读取问题

问题描述 投票:0回答:1

我收到血压测量的原始数据:[DE, E2, F4, 3E, F3, FF, 07, E8, 07, 03, 13, 02, 21, 00, 34, F3, 01, C0, 00]。我设法读取了收缩压、舒张压以及脉搏的值。然而,当我尝试读取平均动脉压 (meanAP) 的值(通常应在索引 5 和 6 处占用两个字节 (FF,07))时,我收到了meanAP=-20.41 mmHg。而使用 nRF Connect 时,它等于 2047.0 mmHg。请问我该如何在下面的代码中纠正这个问题?

import 'package:flutter/material.dart';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'dart:typed_data';
import 'dart:math';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'BLE Scanner',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final FlutterReactiveBle flutterReactiveBle = FlutterReactiveBle();
  List<DiscoveredDevice> devices = [];
  double systolic = 0;
  double diastolic = 0;
  List<double> result = [
    0.0,
    0.0,
    0.0,
    0.0,
  ]; // Déclaration de la variable result
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Mesurer votre Pression Arterielle'),
        backgroundColor: Colors.blue,
      ),
      body: Padding(
        padding: EdgeInsets.all(20.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: _scanForDevices,
              child: Text('Rechercher votre appareil BM96'),
              style: ElevatedButton.styleFrom(
                foregroundColor: Colors.white,
                backgroundColor: Colors.blue,
              ),
            ),
            SizedBox(height: 20),
            Text(
              'Discovered Devices:',
              style: TextStyle(
                fontSize: 18,
                fontWeight: FontWeight.bold,
                color: Colors.blue,
              ),
            ),
            SizedBox(height: 10),
            Expanded(
              child: ListView.builder(
                itemCount: devices.length,
                itemBuilder: (context, index) {
                  final device = devices[index];
                  return ListTile(
                    title: Text(
                      device.name ?? 'Unknown',
                      style: TextStyle(
                        fontSize: 16,
                        color: Colors.black,
                      ),
                    ),
                    subtitle: Text(
                      device.id,
                      style: TextStyle(
                        fontSize: 14,
                        color: Colors.grey,
                      ),
                    ),
                    onTap: () {
                      _connectToDevice(device.id);
                      _subscribeToBloodPressureMeasurement(device.id);
                    },
                  );
                },
              ),
            ),
            SizedBox(height: 20),
            Text(
              'Result Systolic: ${result[0]}',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 10),
            Text(
              'Result Diastolic: ${result[1]}',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 10),
            Text(
              'Result pulse: ${result[2]}',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 10),
            Text(
              'Result MeanAP: ${result[3]}',
              style: TextStyle(fontSize: 20),
            ),
          ],
        ),
      ),
    );
  }

  void _scanForDevices() {
    flutterReactiveBle.scanForDevices(
      withServices: [Uuid.parse('00001810-0000-1000-8000-00805f9b34fb')],
      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'): [
          Uuid.parse('00002a35-0000-1000-8000-00805f9b34fb'),
          Uuid.parse('00002a49-0000-1000-8000-00805f9b34fb'),
        ],
      },
      connectionTimeout: const Duration(seconds: 2),
    )
        .listen(
      (connectionState) {
        if (connectionState == DeviceConnectionState.connected) {
          print("Connected successfully to device: $deviceId");
          _subscribeToBloodPressureMeasurement(deviceId);
        }
      },
      onError: (error) {
        print('Error connecting to device: $error');
      },
    );
  }

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

      flutterReactiveBle
          .subscribeToCharacteristic(bloodPressureCharacteristic)
          .listen(
        (data) {
          print('Received raw data for blood pressure measurement: $data');
          setState(() {
            result = parseBloodPressureData(data);
          });
        },
        onError: (error) {
          print('Error subscribing to blood pressure measurement: $error');
        },
      );
    } catch (e) {
      print('Exception during subscribing to blood pressure measurement: $e');
    }
  }

  List<double> parseBloodPressureData(List<int> packet) {
    final data = ByteData.sublistView(Uint8List.fromList(packet));
    const startByte = 1;
    int value = 0;

//systolic
    value = data.getInt16(startByte, Endian.little);
    int mantissa = value & 0xfff;

    if (mantissa >= 0x0800) {
      mantissa = -((0x0FFF + 1) - mantissa);
    }

    int exponent = value >> 12;

    if (exponent >= 0x0008) {
      exponent = -((0x000F + 1) - exponent);
    }

    double magnitude = pow(10.0, exponent).toDouble();
    double systolic = mantissa * magnitude;

//diastolic
    value = data.getInt16(startByte + 2, Endian.little);
    mantissa = value & 0xfff;

    if (mantissa >= 0x0800) {
      mantissa = -((0x0FFF + 1) - mantissa);
    }

    exponent = value >> 12;

    if (exponent >= 0x0008) {
      exponent = -((0x000F + 1) - exponent);
    }

    magnitude = pow(10.0, exponent).toDouble();
    double diastolic = mantissa * magnitude;

    //pulse
    value = data.getInt16(startByte + 13, Endian.little);
    mantissa = value & 0xfff;

    if (mantissa >= 0x0800) {
      mantissa = -((0x0FFF + 1) - mantissa);
    }

    exponent = value >> 12;

    if (exponent >= 0x0008) {
      exponent = -((0x000F + 1) - exponent);
    }

    magnitude = pow(10.0, exponent).toDouble();
    double pulse = mantissa * magnitude;

    //meanAP
    value = data.getInt16(startByte + 5, Endian.little);
  
    mantissa = value & 0xfff;

    if (mantissa >= 0x0800) {
     mantissa = -((0x0FFF + 1) - mantissa);
     }

     exponent = value >> 12;

      if (exponent >= 0x0008) {
      exponent = -((0x000F + 1) - exponent);
      }

    magnitude = pow(10.0, exponent).toDouble();
      double meanAP= mantissa * magnitude;

    return [systolic, diastolic, pulse,meanAP];
    
  }
}

flutter floating-point bluetooth-lowenergy device ieee-11073
1个回答
0
投票

处理占用多个字节的 BLE 数据时,很容易忽略的一件事是 Endianness。字节的放置顺序至关重要。以你的价值观为例:

0xFF07 = 65287
0x07FF = 2047

有趣的是,您已经使用 Little Endian 提取了 int16 值。我在 DartPad 上尝试了你的代码并收到了 2047 结果:

import 'dart:typed_data';
import 'dart:math';

void main() {
  
  final data = ByteData.sublistView(Uint8List.fromList([0xFF, 0x07]));
  
  int value = data.getInt16(0, Endian.little);
  
    int mantissa = value & 0xfff;

    if (mantissa >= 0x0800) {
     mantissa = -((0x0FFF + 1) - mantissa);
     }

     int exponent = value >> 12;

      if (exponent >= 0x0008) {
      exponent = -((0x000F + 1) - exponent);
      }

    double magnitude = pow(10.0, exponent).toDouble();
      double meanAP= mantissa * magnitude;
  print(meanAP);
}
© www.soinside.com 2019 - 2024. All rights reserved.