项目概述

本系统以零知派 ESP32 为主控,读取 Bosch BMI160 六轴惯性传感器(三轴加速度计 + 三轴陀螺仪),在 MCU 上用 Madgwick 算法融合成横滚角(Roll)、俯仰角(Pitch)、偏航角(Yaw)。

结果同时送到三路:

  • ST7789 1.54 寸 240×240 屏幕:本地仪表,含角度、水平气泡和状态灯
  • WiFi 热点网页:3D 正方体、实时数据、开始/停止记录、一键导出 CSV
  • USB 串口(可选):FireWater 协议对接 VOFA+,在电脑上看 3D

数据可写入 ESP32 内部 Flash(LittleFS),文件名为 log_01.csvlog_02.csv 等。网页「导出 CSV」即可下载到手机或电脑,无需拆机、无需 SD 卡读卡器。

适用场景:水平校准、短时姿态记录、IMU 教学演示。BMI160 没有磁力计,偏航角会随时间缓慢漂移,属六轴系统固有限制。

项目亮点

  1. 采集—解算—显示—记录—导出闭环,不是只打印原始加速度。
  2. 双界面:不连电脑时看屏幕;连热点后用浏览器看 3D 正方体并导出数据。
  3. 网页 3D 不依赖外网:正方体用 CSS 3D 绘制,连 ESP32 热点也能转。
  4. 陀螺零偏校准:上电静止约 2.5 秒采集零偏,网页可再次校准。
  5. I2C 掉线恢复:杜邦线接触不良时自动恢复总线并重新初始化传感器。
  6. 状态一目了然:绿=正常,黄=校准中,红=I2C 故障。

项目难点及解决方案

难点 现象 解决
BMI160 初始化失败 角度全 0 检查 3.3V、I2C 地址 0x68/0x69;驱动探测两个地址
开机立刻校准 静止时偏航仍快速漂 等陀螺进入 Normal 后再延时,丢掉前 0.4 s 样本
热点下 Three.js 拉不下来 3D 卡住很久 网页改用内置 CSS 立方体
读 I2C 失败仍推旧姿态 画面停在一个角度 连续失败则恢复总线;屏幕 I2C 灯变红
记录占满程序分区 无法写 CSV 使用 partitions.csv 划分 LittleFS,不要选 huge_app
同步 WebServer 占用 界面卡顿 屏幕 5 Hz、网页轮询约 3 Hz,串口 50 Hz

目录

一、硬件系统部分

1.1 硬件清单

1.2 接线方案

1.3 硬件连接图

1.4 实物连接图

二、软件架构设计

2.1 系统初始化

2.2 主循环逻辑

三、代码拆分讲解

3.1 配置 config.h

3.2 驱动 bmi160.cpp

3.3 融合 fusion.cpp

3.4 屏幕 display.cpp

3.5 记录 logger.cpp

3.6 网页 web.cpp + webpage.h

四、操作过程及数据展示

4.1 操作步骤

4.2 演示视频

五、技术原理

5.1 工作原理

5.2 工作模式配置

六、常见问题指引

Q1:点开始记录 REC 仍灰

Q2:导出是空的或 404

Q3:VOFA+ 打不开串口


一、硬件系统部分

1.1 硬件清单

名称 规格 数量 说明
零知派 ESP32 ESP32,4MB Flash 1 主控
BMI160 模块 I2C,3.3V 1 六轴 IMU
ST7789 屏幕 240×240,SPI 1 TFT_eSPI 驱动
杜邦线 / 排线 若干 建议尽量短
USB 线 供电与烧录 1 可选接电脑 VOFA+

电源:BMI160 与屏幕均用 3.3V,禁止给 BMI160 接 5V。

1.2 接线方案

BMI160(I2C)

BMI160 ESP32
VCC 3.3V
GND GND
SDA GPIO 21
SCL GPIO 22
SDO/SA0 GND → 地址 0x68(接 3.3V 则为 0x69,固件会自动尝试另一地址)

ST7789(SPI,引脚在 TFT_eSPI 的 User_Setup.h 中配置)

ST7789 ESP32
MOSI / SDA GPIO 23
SCLK / SCL GPIO 18
CS GPIO 15
DC GPIO 13
RST GPIO 4
VCC 3.3V
GND GND

I2C 与 SPI 分开,不要把屏幕的 SDA 接到 GPIO 21。屏幕方向在固件里为 tft.setRotation(3)(旋转 3)。

打开零知派;开发板选零知派 ESP32;分区选带 SPIFFS 的方案(工程内已有 partitions.csv)。库:Wire、WiFi、WebServer、LittleFS 随 ESP32 核心提供。

1.3 硬件连接图

1.4 实物连接图


二、软件架构设计

工程按功能拆文件,主程序只负责调度。

文件 职责
BMI160.ino setup / loop,串口命令
config.h 引脚、热点名、采样率
bmi160.h/.cpp 传感器初始化、读数、总线恢复
fusion.h/.cpp 零偏、Madgwick、欧拉角
display.h/.cpp ST7789 界面
logger.h/.cpp LittleFS 写/列/导出 CSV
web.h/.cpp SoftAP + HTTP
webpage.h 网页 HTML(含 CSS 3D 正方体)
partitions.csv 程序区 + LittleFS

2.1 系统初始化

setup() 顺序:

  1. 可选点亮 GPIO2 LED
  2. 串口 115200(VOFA+ 与 dump 共用,运行时不要开串口监视器抢口)
  3. imu.begin(21, 22, 0x68, 100kHz):软复位、加速度/陀螺 Normal、等 PMU 就绪、再稳定 500 ms
  4. fusion.begin
  5. loggerBegin:挂载 LittleFS(失败则无法记录)
  6. displayBegintft.init()setRotation(3),画状态栏
  7. webBegin:SoftAP BMI160-LOG / 12345678,HTTP 80
  8. 若 IMU 成功,开始约 2.5 s 陀螺校准(前 0.4 s 丢弃)

2.2 主循环逻辑

loop() 每一圈:

  1. pollVofaCommands():处理 start / stop / calibrate / reset_yaw / dump
  2. webLoop():处理网页请求
  3. 100 Hz:读 BMI160,融合;连续失败则 imu.recover()
  4. 50 Hz:串口输出 roll,pitch,yaw;若正在记录则写入 CSV 缓冲
  5. 5 Hz:刷新屏幕,并向网页模块更新 Live JSON

网页每约 300 ms 请求 /api/live 更新数字和正方体,不使用 WebSocket,热点下更稳。


三、代码拆分讲解

3.1 配置 config.h


        I2C 21/22、热点 SSID/密码、IMU_SAMPLE_HZ=100VOFA_HZ=50DISPLAY_HZ=5GYRO_CAL_MS=2500。改接线只动这里和 TFT_eSPI 的 User_Setup.h

3.2 驱动 bmi160.cpp


        Chip ID 0xD1。加速度 ±4 g(8192 LSB/g),陀螺 ±500 dps(65.6 LSB/°/s),ODR 100 Hz。从寄存器 0x0C 连续读 12 字节(先陀螺后加速度)。recoverBus() 在 SDA 被拉死时补时钟并重新 Wire.begin

3.3 融合 fusion.cpp


        校准阶段只累加陀螺均值。运行时减去零偏,Madgwick 输出四元数,再转欧拉角给屏幕和网页。静止一段时间会缓慢跟踪剩余零偏。无磁力计时偏航只能靠陀螺积分。

3.4 屏幕 display.cpp


        顶部 I2C / CAL / REC 圆点,中部三个角度,左下气泡(roll/pitch 映射到圆内),底部提示 192.168.4.1。角度变化小于 0.05° 不重绘,减少闪烁。

3.5 记录 logger.cpp


start 创建 /log_XX.csv,表头:

t_ms,roll,pitch,yaw,ax,ay,az,gx,gy,gz

t_ms 从本次记录开始计。内存攒 32 行再写盘。最多 99 个文件。

3.6 网页 web.cpp + webpage.h

路径 作用
GET / 主页面
GET /api/live 实时 JSON
GET /api/logs 文件列表
POST /api/start stop calibrate 记录与校准
GET /api/export 下载最近一份 CSV
GET /download?f=log_01.csv 下载指定文件

正方体用六个面拼成板状,JavaScript 按
rotateY(yaw) rotateX(pitch) rotateZ(-roll) 更新。


四、操作过程及数据展示

4.1 操作步骤

  1. 按 1.2 接线,确认 BMI160 为 3.3V。
  2. 打开 BMI160.ino,选零知派 ESP32,分区带 SPIFFS,编译上传。
  3. 上电后将模块放平静止约 3 秒,屏幕 CAL 由黄变绿。
  4. 手机连接 WiFi BMI160-LOG,密码 12345678
  5. 浏览器打开 http://192.168.4.1(屏幕底部也有该地址)。
  6. 转动模块:网页正方体与 ROLL/PITCH/YAW 应同步变化。
  7. 点 开始记录,REC 变绿;点 停止 保存。
  8. 点 导出 CSV,浏览器下载 log_xx.csv。用 Excel 或 Python 打开。
  9. 需要重新校准:点 校准,保持静止直到 CAL 变绿。

CSV 示例

t_ms,roll,pitch,yaw,ax,ay,az,gx,gy,gz
0,1.02,4.10,-0.12,-0.076,0.019,1.064,0.02,-0.01,0.00
20,1.05,4.08,-0.10,-0.077,0.018,1.063,0.01,-0.02,0.01

平放时 az 约 1 g,ax/ay 接近 0,roll/pitch 为小角度。

可选 VOFA+:协议 FireWater,115200,I0/I1/I2 绑定 3D。不要同时开串口监视器。

4.2 演示视频

零知派ESP32–基于BMI160的IMU姿态监测系统


五、技术原理

5.1 工作原理

加速度计测比力,静止时主要是重力,可得到 roll、pitch,但对偏航不敏感,动态时受运动加速度干扰。陀螺仪测角速度,积分得到相对转角,但有零偏,积分会漂。

本工程:

  1. 静止时估计陀螺零偏并减去。
  2. Madgwick 用陀螺预报四元数,用加速度作重力方向校正(主要稳住 roll/pitch)。
  3. 偏航没有地磁参考,长期会漂,可网页或串口 reset_yaw 把当前航向当作 0。

屏幕气泡只用 roll、pitch,不依赖航向。

5.2 工作模式配置

BMI160

  • 加速度、陀螺:Normal
  • 加速度:±4 g,100 Hz
  • 陀螺:±500 °/s,100 Hz
  • I2C:100 kHz(杜邦线比 400 kHz 更稳)

系统任务频率

任务 频率
IMU 采样与融合 100 Hz
串口 / 写 CSV 50 Hz
屏幕 5 Hz
网页轮询 约 3 Hz

存储
partitions.csv:应用约 1.75 MB,LittleFS 约 2.2 MB。50 Hz 记录大约可记十余分钟量级(视行长而定),不是长时间黑匣子。需要更久请改 SD 卡。

网络
仅 SoftAP,STA 不连路由器。IP 固定 192.168.4.1


六、常见问题指引

Q1:点开始记录 REC 仍灰

分区没有 LittleFS(不要 huge_app),或已有 99 个 log 文件。

Q2:导出是空的或 404

先成功记录并停止一次。导出最近一份;历史列表可下旧文件。

Q3:VOFA+ 打不开串口

关掉串口监视器后再连。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐