在Flutter中基于CC2650 STK的MPU-9250传感器检测移动方向与距离
在Dart中基于MPU-9250传感器BLE数据检测设备移动方向与距离
原始传感器数据
初始值
[138,255,185,0,164,0,84,2,160,0,108,64,50,2,101,253,28,252]
最终值
[120,255,122,0,203,0,152,2,216,0,112,64,27,29,253,44,247]
数据格式定义
陀螺仪数据(前6个字节)
GXLSB: X轴陀螺仪读数最低有效字节GXMSB: X轴陀螺仪读数最高有效字节GYLSB: Y轴陀螺仪读数最低有效字节GYMSB: Y轴陀螺仪读数最高有效字节GZLSB: Z轴陀螺仪读数最低有效字节GZMSB: Z轴陀螺仪读数最高有效字节
加速度计数据(接下来6个字节,索引6-11)
AXLSB: X轴加速度计读数最低有效字节AXMSB: X轴加速度计读数最高有效字节AYLSB: Y轴加速度计读数最低有效字节AYMSB: Y轴加速度计读数最高有效字节AZLSB: Z轴加速度计读数最低有效字节AZMSB: Z轴加速度计读数最高有效字节
Dart实现步骤
1. 字节转物理单位数值
首先将LSB和MSB拼接为16位有符号整数,再根据MPU-9250默认量程转换为物理单位:
- 陀螺仪:±250°/s,灵敏度131 LSB/(°/s)
- 加速度计:±2g,灵敏度16384 LSB/g(1g≈9.81m/s²)
// 拼接LSB和MSB为16位有符号整数 int combineBytes(int lsb, int msb) { int value = (msb << 8) | lsb; return value >= 0x8000 ? value - 0x10000 : value; } // 陀螺仪原始值转°/s double gyroRawToDps(int rawValue) { const sensitivity = 131.0; return rawValue / sensitivity; } // 加速度计原始值转m/s² double accelRawToMs2(int rawValue) { const sensitivity = 16384.0; return (rawValue / sensitivity) * 9.81; } // 解析传感器数据列表 Map<String, double> parseSensorData(List<int> data) { // 解析陀螺仪数据 final gxRaw = combineBytes(data[0], data[1]); final gyRaw = combineBytes(data[2], data[3]); final gzRaw = combineBytes(data[4], data[5]); // 解析加速度计数据 final axRaw = combineBytes(data[6], data[7]); final ayRaw = combineBytes(data[8], data[9]); final azRaw = combineBytes(data[10], data[11]); return { 'gx': gyroRawToDps(gxRaw), 'gy': gyroRawToDps(gyRaw), 'gz': gyroRawToDps(gzRaw), 'ax': accelRawToMs2(axRaw), 'ay': accelRawToMs2(ayRaw), 'az': accelRawToMs2(azRaw), }; }
2. 检测移动方向
通过校准加速度计去除重力影响,再根据三轴加速度值判断移动方向:
// 校准加速度计,移除初始静止时的重力分量 Map<String, double> calibrateAccel(Map<String, double> initial, Map<String, double> current) { final gravityX = initial['ax']!; final gravityY = initial['ay']!; final gravityZ = initial['az']!; return { 'ax': current['ax']! - gravityX, 'ay': current['ay']! - gravityY, 'az': current['az']! - gravityZ, }; } // 判断移动方向 String detectMovementDirection(Map<String, double> calibratedAccel) { final ax = calibratedAccel['ax']!; final ay = calibratedAccel['ay']!; final az = calibratedAccel['az']!; // 噪声过滤阈值 const threshold = 0.5; List<String> directions = []; if (ax > threshold) directions.add('X轴正方向'); else if (ax < -threshold) directions.add('X轴负方向'); if (ay > threshold) directions.add('Y轴正方向'); else if (ay < -threshold) directions.add('Y轴负方向'); if (az > threshold) directions.add('Z轴正方向'); else if (az < -threshold) directions.add('Z轴负方向'); return directions.isEmpty ? '无明显移动' : directions.join('、'); }
3. 估算移动距离
通过加速度积分计算位移(基础实现,实际需结合陀螺仪或滤波算法优化误差):
import 'dart:math'; // 估算移动距离(dt为初始到最终数据的时间差,单位秒) double estimateDistance(Map<String, double> initialAccel, Map<String, double> finalAccel, double dt) { final calibratedInitial = calibrateAccel(initialAccel, initialAccel); final calibratedFinal = calibrateAccel(initialAccel, finalAccel); // 计算三轴平均加速度 final avgAx = (calibratedInitial['ax']! + calibratedFinal['ax']!) / 2; final avgAy = (calibratedInitial['ay']! + calibratedFinal['ay']!) / 2; final avgAz = (calibratedInitial['az']! + calibratedFinal['az']!) / 2; // 积分计算位移(假设初始速度为0) final dx = 0.5 * avgAx * dt * dt; final dy = 0.5 * avgAy * dt * dt; final dz = 0.5 * avgAz * dt * dt; return sqrt(dx*dx + dy*dy + dz*dz); }
4. 完整使用示例
void main() { final initialData = [138,255,185,0,164,0,84,2,160,0,108,64,50,2,101,253,28,252]; final finalData = [120,255,122,0,203,0,152,2,216,0,112,64,27,29,253,44,247]; // 解析数据 final initialParsed = parseSensorData(initialData); final finalParsed = parseSensorData(finalData); // 检测移动方向 final calibratedFinal = calibrateAccel(initialParsed, finalParsed); final direction = detectMovementDirection(calibratedFinal); print('移动方向:$direction'); // 估算距离(假设时间差为1秒,实际需按BLE采样频率设置) final distance = estimateDistance(initialParsed, finalParsed, 1.0); print('估算移动距离:${distance.toStringAsFixed(2)}米'); }
内容的提问来源于stack exchange,提问作者Kashif Niaz
相关产品推荐
相关产品推荐

