Flutter血压原始数据读取异常修正:平均动脉压数值错误
修正BLE血压数据中平均动脉压的读取错误
问题说明
原始血压测量数据:[DE, E2, F4, 3E, F3, FF, 07, E8, 07, 03, 13, 02, 21, 00, 34, F3, 01, C0, 00],其中平均动脉压(meanAP)对应索引5和6的字节FF, 07,当前代码计算结果为-20.41 mmHg,而正确结果应为2047.0 mmHg。
错误原因
- 字节偏移量错误:代码中读取meanAP时使用了
startByte + 5,导致读取了索引6和7的字节(07, E8),而非目标的索引5和6。 - 读取错误字节后,触发了不必要的负数转换逻辑,最终得到错误的负值结果。
修正后的完整代码
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, ]; // 声明result变量 @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('测量您的动脉血压'), backgroundColor: Colors.blue, ), body: Padding( padding: EdgeInsets.all(20.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ ElevatedButton( onPressed: _scanForDevices, child: Text('搜索您的BM96设备'), style: ElevatedButton.styleFrom( foregroundColor: Colors.white, backgroundColor: Colors.blue, ), ), SizedBox(height: 20), Text( '已发现设备:', 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 ?? '未知设备', 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[0]}', style: TextStyle(fontSize: 20), ), SizedBox(height: 10), Text( '舒张压结果: ${result[1]}', style: TextStyle(fontSize: 20), ), SizedBox(height: 10), Text( '脉搏结果: ${result[2]}', style: TextStyle(fontSize: 20), ), SizedBox(height: 10), Text( '平均动脉压结果: ${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'); }, ); } 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("成功连接到设备: $deviceId"); _subscribeToBloodPressureMeasurement(deviceId); } }, onError: (error) { print('连接设备错误: $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('接收到血压测量原始数据: $data'); setState(() { result = parseBloodPressureData(data); }); }, onError: (error) { print('订阅血压测量错误: $error'); }, ); } catch (e) { print('订阅血压测量时发生异常: $e'); } } List<double> parseBloodPressureData(List<int> packet) { final data = ByteData.sublistView(Uint8List.fromList(packet)); const startByte = 1; int value = 0; // 收缩压 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; // 舒张压 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; // 脉搏 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; // 平均动脉压(修正了字节偏移量) value = data.getInt16(startByte + 4, 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]; } }
关键修改点
仅修改了parseBloodPressureData函数中平均动脉压的读取偏移量:
// 原错误代码 value = data.getInt16(startByte + 5, Endian.little); // 修正后代码 value = data.getInt16(startByte + 4, Endian.little);
修正后,代码会正确读取索引5和6的字节FF, 07,小端序组合为0x07FF(即十进制2047),结合exponent为0的情况,最终计算出正确的2047.0 mmHg。
内容的提问来源于stack exchange,提问作者user23651217
相关产品推荐
相关产品推荐

