0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

零知开源——ESP8266结合ICM20948实现高精度姿态解算

零知实验室 来源:PCB56242069 作者:PCB56242069 2025-03-07 14:09 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

零知实验室发布新版ICM20948模块,可以非常方便的应用在零知各个系列开发板或其他类似MCU,它可以作为已经停产的MPU9250的替代品,下面演示它在零知ESP8266上的使用。

一、ICM20948深度解析:九轴传感器的核心技术

1.1 什么是IMU?

IMU(Inertial Measurement Unit)即惯性测量单元,是融合加速度计、陀螺仪和磁力计的核心传感器。ICM20948作为新一代九轴IMU,具备以下技术特性:

参数 规格 技术优势
加速度测量范围 ±2g/±4g/±8g/±16g 16位ADC,0.98mg/LSB@±16g
陀螺仪量程 ±250/±500/±1000/±2000 dps 0.0038°/s/LSB@±250dps
磁力计量程 ±4900μT 16位分辨率,0.15μT/LSB
数据输出速率 最高1125Hz 支持SPI/I2C接口
工作电压 1.71V-3.6V 超低功耗模式<5μA

1.2 硬件架构解析

芯片内部采用三层堆叠结构:

wKgZPGfKjYyASdcTAAElvoPR1Zw19.jpegwKgZO2fKh2WANM0GAAEXnILISKw454.png

MEMS传感层:包含三轴加速度计和陀螺仪

ASIC处理层:集成数字运动处理器(DMP)

磁力计层:AK09916磁力计通过I2C从接口连接

1.3 九轴数据融合原理

姿态解算通过传感器融合算法实现:

姿态矩阵=加速度计校准✖陀螺仪积分✖磁力计补偿

典型算法对比:

算法 计算复杂度 精度 适用场景
互补滤波 一般 低速运动
卡尔曼滤波 动态环境
Mahony 中等 较高 嵌入式系统

二、硬件系统搭建

2.1 物料清单

组件 型号
主控板 零知ESP8266
九轴传感器 ICM20948
连接线 杜邦线
电源 USB适配器

2.2 电路连接详解

零知ESP8266和ICM20948九轴加速度传感器的接线图:

零知ESP8266 ICM20948
3.3V VCC
GND GND
SCL SCL
SDA SDA

wKgZPGfKh7mAYtalAAQhqhel-rk212.pngESP8266和ICM20948接线图

三、软件系统开发

3.1 校准验证代码

​​// 在setup()中添加的校准验证
if(SerialDebug) {
  Serial.println("Post-Calibration Accel Bias (mg):");
  Serial.print(1000*myIMU.accelBias[0]); 
  Serial.print(" ");
  Serial.print(1000*myIMU.accelBias[1]);
  Serial.print(" ");
  Serial.println(1000*myIMU.accelBias[2]);
}

将加速度偏置转换为mg单位(1g=1000mg)

X/Y轴偏置应<50mg,Z轴接近0(理想值)

确保校准过程有效,避免硬件安装误差

3.2 动态零位补偿

​static int calibration_cnt = 0;
if(calibration_cnt < 1000 && abs(myIMU.gx)< 0.5 && abs(myIMU.gy)< 0.5) {
  myIMU.accelBias[0] += myIMU.ax * 0.001;
  myIMU.accelBias[1] += myIMU.ay * 0.001;
  calibration_cnt++;
}

前1000次采样持续修正加速度偏置

0.001为学习率系数,控制校准速度

实现动态自适应,消除温度漂移影响

3.3传感器数据预处理

1.加速度计处理

myIMU.ax = (float)myIMU.accelCount[0] * myIMU.aRes - myIMU.accelBias[0];
myIMU.ay = (float)myIMU.accelCount[1] * myIMU.aRes - myIMU.accelBias[1];
myIMU.az = (float)myIMU.accelCount[2] * myIMU.aRes - myIMU.accelBias[2];

数据处理流程

accelCount:原始ADC值

aRes:分辨率计算(例如±16g量程时为2048 LSB/g)

减去校准偏置消除零位误差

关键参数

量程设置:建议初始化时配置为±8g

分辨率公式:aRes = 16.0 / 32768.0 (16位ADC)

2.陀螺仪处理

​myIMU.gx = (float)myIMU.gyroCount[0] * myIMU.gRes - myIMU.gyroBias[0];
myIMU.gy = (float)myIMU.gyroCount[1] * myIMU.gRes - myIMU.gyroBias[1]; 
myIMU.gz = (float)myIMU.gyroCount[2] * myIMU.gRes - myIMU.gyroBias[2];

漂移控制

典型偏置值应<1°/s

温度每升高1℃,零偏变化约0.01°/s

改进建议:添加温度补偿函数

3.磁力计数据融合

float mx_raw = (float)myIMU.magCount[1] * myIMU.mRes; // X/Y交换
float my_raw = (float)myIMU.magCount[0] * myIMU.mRes;
float mz_raw = -(float)myIMU.magCount[2] * myIMU.mRes; // Z反转

myIMU.mx = (mx_raw - myIMU.magBias[1]) * myIMU.magScale[1];
myIMU.my = (my_raw - myIMU.magBias[0]) * myIMU.magScale[0];
myIMU.mz = (mz_raw - myIMU.magBias[2]) * myIMU.magScale[2];

magBias:硬铁干扰补偿

magScale:软铁畸变校正

注意:校准数据需对应新坐标系

3.4姿态解算核心算法

1.Mahony滤波器调用

MahonyQuaternionUpdate(
  myIMU.ay,  // 加速度Y→X
  myIMU.ax,   // 加速度X→Y 
  -myIMU.az,  // 加速度Z反转
  myIMU.gy * DEG_TO_RAD, // 陀螺Y→X
  myIMU.gx * DEG_TO_RAD, // 陀螺X→Y
  -myIMU.gz * DEG_TO_RAD,// 陀螺Z反转
  myIMU.mx, 
  myIMU.my,
  myIMU.mz,
  myIMU.deltat
);

2.欧拉角转换

​      myIMU.yaw   = atan2(2.0f * (*(getQ()+1) * *(getQ()+2) + *getQ()
                    * *(getQ()+3)), *getQ() * *getQ() + *(getQ()+1)
                    * *(getQ()+1) - *(getQ()+2) * *(getQ()+2) - *(getQ()+3)
                    * *(getQ()+3));
      myIMU.pitch = -asin(2.0f * (*(getQ()+1) * *(getQ()+3) - *getQ()
                    * *(getQ()+2)));
      myIMU.roll  = atan2(2.0f * (*getQ() * *(getQ()+1) + *(getQ()+2)
                    * *(getQ()+3)), *getQ() * *getQ() - *(getQ()+1)
                    * *(getQ()+1) - *(getQ()+2) * *(getQ()+2) + *(getQ()+3)
                    * *(getQ()+3));
      myIMU.pitch *= RAD_TO_DEG;
      myIMU.yaw   *= RAD_TO_DEG;

      // Declination of SparkFun Electronics (40°05'26.6"N 105°11'05.9"W) is
      // 	8° 30' E  ± 0° 21' (or 8.5°) on 2016-07-19
      // - http://www.ngdc.noaa.gov/geomag-web/#declination
      myIMU.yaw  -= 8.5;
      myIMU.roll *= RAD_TO_DEG;

3.5数据输出

串口协议设计

//打印格式与processing端格式一致
  Serial.print("Or: ");
  Serial.print(myIMU.yaw, 2);
  Serial.print(" ");
  
  Serial.print(myIMU.pitch, 2);
  Serial.print(" ");

  Serial.print(myIMU.roll, 2);
  Serial.println(" ");

3.6Processing 3D可视化验证

将代码库文件安装包解压到C:UsersAdministratorDocumentsProcessinglibraries,然后在Processing中选择开发板对应的串口号,就可以看到我们的3D模型根据九轴的姿态进行变化啦:

import processing.serial.*;

// 传感器数据
float roll, pitch, yaw;
PVector accelerometer = new PVector();
PVector gyroscope = new PVector();
PVector magneticField = new PVector();

// 3D模型
PShape model;
PImage bgImage;

// 串口配置
Serial port;
String[] serialPorts;
int selectedPort = 0;
boolean printSerial = false;

void setup() {
  size(1024, 800, P3D);
  frameRate(60);
  
  // 加载资源
  bgImage = loadImage("background.png");
  model = loadShape("biplane.obj"); // 确保使用标准OBJ格式
  model.scale(30);
  
  // 初始化串口
  serialPorts = Serial.list();
  if(serialPorts.length > 0) connectSerial(serialPorts[0]);
}

void draw() {
  background(bgImage);
  
  // 3D场景设置
  pushMatrix();
  translate(width/2, height/2, 0);
  lights();
  
  // 应用旋转
  rotateX(radians(pitch));
  rotateY(radians(yaw));
  rotateZ(radians(roll));
  
  // 绘制模型
  shape(model);
  popMatrix();
  
  // 显示数据
  displaySensorData();
}

void serialEvent(Serial p) {
  try {
    String rawData = p.readStringUntil('n').trim();
    if(printSerial) println(rawData);
    
    String[] parts = split(rawData, ' ');
    if(parts.length >= 4) {
      switch(parts[0]) {
        case "Or:": // 欧拉角格式:Or: yaw pitch roll
          yaw = float(parts[1]);
          pitch = float(parts[2]);
          roll = float(parts[3]);
          break;
        case "Accel:":
          accelerometer.set(float(parts[1]), float(parts[2]), float(parts[3]));
          break;
        case "Gyro:":
          gyroscope.set(float(parts[1]), float(parts[2]), float(parts[3]));
          break;
        case "Mag:":
          magneticField.set(float(parts[1]), float(parts[2]), float(parts[3]));
          break;
      }
    }
  } catch(Exception e) {
    println("Serial Error: " + e.getMessage());
  }
}

void displaySensorData() {
  fill(0, 255, 0);
  textSize(16);
  textAlign(LEFT, TOP);
  String data = "Accelerometer(g): " 
    + nfp(accelerometer.x,1,2) + ", " 
    + nfp(accelerometer.y,1,2) + ", " 
    + nfp(accelerometer.z,1,2) + "n"
    + "Gyroscope(deg/s): " 
    + nfp(gyroscope.x,1,2) + ", "
    + nfp(gyroscope.y,1,2) + ", " 
    + nfp(gyroscope.z,1,2) + "n"
    + "Orientation: n"
    + "Yaw: " + nfp(yaw,1,1) + "°n"
    + "Pitch: " + nfp(pitch,1,1) + "°n"
    + "Roll: " + nfp(roll,1,1) + "°";
  text(data, 20, 20);
}

void connectSerial(String portName) {
  if(port != null) port.stop();
  try {
    port = new Serial(this, portName, 115200);
    port.bufferUntil('n');
    println("Connected to: " + portName);
  } catch(Exception e) {
    println("Connection failed: " + e.getMessage());
  }
}

void keyPressed() {
  // 切换串口
  if(key == ' ') {
    selectedPort = (selectedPort + 1) % serialPorts.length;
    connectSerial(serialPorts[selectedPort]);
  }
  // 切换调试输出
  if(key == 'P' || key == 'p') printSerial = !printSerial;
  // 重置视角
  if(key == 'R' || key == 'r') {
    yaw = pitch = roll = 0;
  }
}

四、实现结果分析

观察串口打印输出的DMP姿态解算数据如下:

wKgZPGfKjEeAbnDtAAEXLhFsW3k087.png

Processing 3D可视化验证:https://www.bilibili.com/video/BV1n3RPYWE8E/?share_source=copy_web&vd_source=75d3b293c1933aa8dc6757ac429e12da

五、项目资源汇总

5.1 参考资料

ICM20948数据手册

ESP8266技术参考

5.2 源码获取

https://github.com/Leeri1y/ICM20948-ESP8266

参考Github仓库

​​

64位Windows系统的Processing安装包:

通过网盘分享的文件:processing-4.3.3.7z
链接: https://pan.baidu.com/s/12B4F33M1caRncVjSJiFPTg?pwd=9h5i 提取码: 9h5i

5.3 扩展学习

Mahony滤波器数学推导

欢迎各位道友相互讨论,一直在学习的路上!

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Processing
    +关注

    关注

    0

    文章

    11

    浏览量

    9210
  • IMU
    IMU
    +关注

    关注

    6

    文章

    403

    浏览量

    47584
  • ESP8266
    +关注

    关注

    51

    文章

    966

    浏览量

    48992
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    开源——ESP8266+MPU6050 实现运动姿态检测

    ESP8266的I2C通信        在运动姿态检测、机器人平衡控制、VR头戴设备等应用中,MPU6050(三轴加速度计+三轴陀螺仪)是一个常见的
    的头像 发表于 02-20 17:54 2798次阅读
    <b class='flag-5'>零</b><b class='flag-5'>知</b><b class='flag-5'>开源</b>——<b class='flag-5'>ESP8266</b>+MPU6050 <b class='flag-5'>实现</b>运动<b class='flag-5'>姿态</b>检测

    开源——ESP8266+MPU6050 实现运动姿态检测

    ,减少漂移,提高yaw角的计算精度。 一、硬件连接 MPU6050模块采用I2C通信连接到ESP8266开发板 1.所需材料:
    发表于 02-20 17:44

    开源——ESP8266结合ICM20948实现高精度姿态

    实验室发布新版ICM20948模块,可以非常方便的应用在各个系列开发板或其他类似MCU,它可以作为已经停产的MPU9250的替代品,
    发表于 03-07 15:46

    《电子发烧友电子设计周报》聚焦硬科技领域核心价值 第2期:2025.03.3--2025.03.7

    可以跨楼层的智能配送机器人 2、ESP8266结合ICM20948实现高精度姿态
    发表于 03-07 18:03

    经验——STM32F4驱动ICM20948 九轴运动传感器 + VOFA上位机可视化验证与抗漂移优化

    六、资源下载1.优化后完整工程代码 通过百度网盘分享工程文件,链接(提取码: m9dw)。 增强板ICM20948姿态角校准工程源文件: https://pan.baidu.c
    发表于 06-06 10:03

    开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

    STM32F1本教程使用标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态
    发表于 06-09 14:53

    使用esp8266实现STM32联网(最简单USART方法)

    到电脑上的java程序 这一篇 esp8266与STM32连接,电脑通过STM32配置esp8266实现联网发送数据具体流程如下图 2= esp8266怎么和STM32连接(引脚连
    发表于 11-22 11:51 1.3w次阅读

    Esp8266单机开源分享

    电子发烧友网站提供《Esp8266单机开源分享.zip》资料免费下载
    发表于 07-04 14:55 3次下载
    <b class='flag-5'>Esp8266</b>单机<b class='flag-5'>开源</b>分享

    ESP8266迷你系统开源分享

    电子发烧友网站提供《ESP8266迷你系统开源分享.zip》资料免费下载
    发表于 08-08 10:07 7次下载
    <b class='flag-5'>ESP8266</b>迷你系统<b class='flag-5'>开源</b>分享

    开发板ESP8266开源分享

    电子发烧友网站提供《开发板ESP8266开源分享.zip》资料免费下载
    发表于 08-10 14:49 17次下载
    开发板<b class='flag-5'>ESP8266</b><b class='flag-5'>开源</b>分享

    BIM时钟ESP8266开源项目

    电子发烧友网站提供《BIM时钟ESP8266开源项目.zip》资料免费下载
    发表于 08-16 11:18 2次下载
    BIM时钟<b class='flag-5'>ESP8266</b><b class='flag-5'>开源</b>项目

    ESP8266物联网开源分享

    电子发烧友网站提供《ESP8266物联网开源分享.zip》资料免费下载
    发表于 12-06 14:45 4次下载
    <b class='flag-5'>ESP8266</b>物联网<b class='flag-5'>开源</b>分享

    ESP8266编程盾开源

    电子发烧友网站提供《ESP8266编程盾开源.zip》资料免费下载
    发表于 02-02 14:25 1次下载
    <b class='flag-5'>ESP8266</b>编程盾<b class='flag-5'>开源</b>

    经验——STM32F4驱动ICM20948 九轴运动传感器 + VOFA上位机可视化验证与抗漂移优化

    温度补偿的偏补偿系统、数据校验容错机制及动态参数姿态算算法。经VOFA+验证,静态漂移降低94.7%,响应延迟缩短62.5%,摇摆幅度减少79.3%,达到工业级应用标准。该方案为无人机、机器人等需要
    的头像 发表于 06-06 09:43 1277次阅读
    <b class='flag-5'>零</b><b class='flag-5'>知</b>经验——STM32F4驱动<b class='flag-5'>ICM20948</b> 九轴运动传感器 + VOFA上位机可视化验证与抗漂移优化

    开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

    本教程使用标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态
    的头像 发表于 06-09 14:01 1188次阅读
    <b class='flag-5'>零</b><b class='flag-5'>知</b><b class='flag-5'>开源</b>——STM32F103RBT6驱动 <b class='flag-5'>ICM20948</b> 九轴传感器及 vofa + 上位机可视化教程