ESP32 FlightLab:从六轴传感器到实时无人机姿态仪表盘
ESP32 FlightLab:从六轴传感器到实时无人机姿态仪表盘
从一块 ESP32、一个标着 MPU6050 的六轴模块开始,我搭了一套无人机飞控实验平台:传感器通过 I²C 接入 ESP32,实时数据经 USB 串口传到电脑,再由本地网页显示 Roll、Pitch、加速度、角速度、人工地平线和四旋翼姿态模拟。

项目源码:liuhao192/ESP32-FlightLab
目前它还不是一套可以直接装上电机起飞的完整飞控。现阶段的目标,是先把硬件识别、传感器采集、数据链路、姿态显示和水平校准做扎实。
1. 已经完成的功能
- ESP32 与 MPU6050/MPU6500 兼容六轴模块通信;
- 读取三轴加速度、三轴角速度和芯片温度;
- 通过 USB 串口输出 JSON Lines 实时遥测;
- 在电脑浏览器中显示实时姿态仪表盘;
- 四旋翼模型和人工地平线随传感器同步运动;
- 气泡水平仪与“将当前位置设为水平”校准;
- PlatformIO 一键编译和烧录。
整个数据链路如下:
MPU6050 / MPU6500
│ I²C
▼
ESP32
│ USB 串口 JSON Lines
▼
Python 本机服务
│ HTTP
▼
浏览器实时仪表盘
2. 开发板与传感器识别
ESP32 通过 USB 接入 Mac 后,系统识别到了 CH340 串口:
/dev/cu.wchusbserial1430
读取到的开发板信息如下:
| 项目 | 实测结果 |
|---|---|
| 芯片 | ESP32-D0WD-V3 revision 3.1 |
| 处理器 | 双核,最高 240 MHz |
| 晶振 | 40 MHz |
| Flash | 16 MB,3.3 V |
| 无线 | Wi-Fi + Bluetooth |
| USB 转串口 | CH340 |
项目使用 PlatformIO,开发板选择通用的 esp32dev,同时按实测容量配置 16 MB Flash:
[platformio]
default_envs = esp32dev
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
upload_speed = 460800
board_upload.flash_size = 16MB
board_build.flash_size = 16MB
board_build.partitions = default_16MB.csv
3. 六轴模块接线
ESP32 使用 GPIO 21 和 GPIO 22 连接 I²C。接线前先断开 USB 电源:
| 六轴模块 | ESP32 | 说明 |
|---|---|---|
| VCC | 3V3 | 使用 3.3 V 供电 |
| GND | GND | 必须共地 |
| SDA | GPIO 21 | I²C 数据线 |
| SCL | GPIO 22 | I²C 时钟线 |
| AD0 | GND | 地址设为 0x68 |
| INT | 暂不连接 | 后续用于中断采样 |
| XDA / XCL | 不连接 | 辅助 I²C |
ESP32 MPU6050 / MPU6500
3V3 ──────────────► VCC
GND ──────────────► GND
GPIO21──────────────► SDA
GPIO22──────────────► SCL
GND ──────────────► AD0
4. 第一个坑:模块实际不是 MPU6050
I²C 扫描顺利在 0x68 找到设备:
Found device at 0x68
但是读取 WHO_AM_I 身份寄存器时,返回的是:
WHO_AM_I: 0x70
原版 MPU6050 的身份值通常是 0x68,0x70 则对应 MPU6500 或兼容芯片。也就是说,模块虽然以 MPU6050 的名字出售,实际更接近 MPU6500。
两者的基础加速度、陀螺仪和温度寄存器兼容,因此程序同时接受两个身份值:
if (whoAmI != 0x68 && whoAmI != 0x70) {
return false;
}
硬件项目不能只相信模块丝印。先扫描地址,再读取芯片身份寄存器,能省掉很多后续排查时间。
5. 从原始值换算到姿态数据
默认量程下,加速度计灵敏度为 16384 LSB/g,陀螺仪灵敏度为 131 LSB/(°/s):
const float ax = rawAx / 16384.0F;
const float ay = rawAy / 16384.0F;
const float az = rawAz / 16384.0F;
const float gx = rawGx / 131.0F;
const float gy = rawGy / 131.0F;
const float gz = rawGz / 131.0F;
静止时,三个加速度分量的合成值应接近 1g。哪一个轴接近正负 1g,取决于模块当前安装方向。
Roll 和 Pitch 暂时主要由加速度计算:
roll = atan2(ay, az) * 180 / PI;
pitch = atan2(-ax, sqrt(ay * ay + az * az)) * 180 / PI;
这种方法适合作为静态安装和调平参考。快速移动时,线性加速度会被误认为重力方向,因此后续还需要加入陀螺仪零偏校准、低通滤波和姿态融合。
6. USB 串口遥测
ESP32 以 115200 波特率发送一行一个 JSON 对象:
{"valid":true,"ms":4270,"ax":1.0193,"ay":-0.0215,"az":-0.0896,"gx":5.275,"gy":1.313,"gz":1.260,"temp":43.02,"roll":-166.52,"pitch":-84.83}
其中:
ax、ay、az:加速度,单位 g;gx、gy、gz:角速度,单位 °/s;temp:芯片内部温度,单位 °C;roll、pitch:姿态角,单位 °;ms:ESP32 启动后的毫秒数。
Python 服务持续读取串口并保存最新数据,同时提供 /api/sensor 接口。浏览器每 100ms 获取一次数据,网页刷新约为 10Hz;ESP32 串口输出为 20Hz。
网页不直接托管在 ESP32 上,主要是为了让固件保持简单,同时方便修改界面、记录数据和调试串口。开发阶段也不需要为了看数据反复切换 Wi-Fi。
7. 实时姿态仪表盘
仪表盘显示:
- Roll 与 Pitch;
- 三轴加速度;
- 三轴角速度;
- 芯片温度和运行时间;
- 四旋翼姿态模型;
- 人工地平线;
- 气泡水平仪。
移动六轴模块时,四旋翼模型会跟着倾斜。人工地平线根据 Roll 旋转,并根据 Pitch 上下移动,比只看一串传感器数字直观得多。
8. 如何判断机架是否水平
模块焊接、减震安装、机架和桌面本身都可能存在误差,因此不能简单地认为“模块正面朝上就是 0°”。
正确的调平流程是:
- 将传感器按最终方向牢固安装到机架;
- 使用实体水平仪确认桌面或测试架水平;
- 将机架静置在水平面上;
- 点击网页中的“将当前位置设为水平”;
- 气泡进入绿色中心区域时,代表 Roll 和 Pitch 都处于零点 ±2° 内。
水平零点保存在浏览器本地。传感器安装方向改变后,需要重新设置。
这个功能解决的是安装偏差,不是陀螺仪零偏。陀螺仪静止时仍可能显示几度每秒,后面要单独进行启动静止校准。
9. 编译、烧录与启动
克隆项目并准备环境:
git clone https://github.com/liuhao192/ESP32-FlightLab.git
cd ESP32-FlightLab
python3 -m venv .venv
source .venv/bin/activate
pip install platformio -r requirements.txt
编译并烧录:
pio run --target upload
启动本机仪表盘:
python tools/dashboard.py --port /dev/cu.wchusbserial1430
Linux 常见端口是 /dev/ttyUSB0,Windows 则可能是 COM3。可以执行 pio device list 查看实际设备。
最后访问:
http://127.0.0.1:8765
10. 推荐的后续硬件
第一次自研飞控,不建议直接做 5 英寸穿越机或 450 级四旋翼。我更倾向于 3~3.5 英寸、3S、低 KV 电机和全包围桨保护的方案。
| 类别 | 推荐规格 |
|---|---|
| 机架 | 3~3.5 英寸 X 型,全包围桨保护,确认能固定 ESP32 开发板 |
| 电机 | 1404、约 3500~3900KV、支持 3S |
| 电调 | 20~30A 四合一、2~4S、支持 DShot300/600 |
| 螺旋桨 | 3 或 3.5 英寸低螺距三叶桨,正反桨成对 |
| 电池 | 3S 850~1100mAh、XT30 |
| 稳压 | 3~4S 输入、稳定 5V/3A 输出的独立 BEC |
| 遥控器 | RadioMaster Pocket M2 ELRS 2.4GHz |
| 接收机 | RadioMaster RP1 V2 ELRS 2.4GHz,CRSF UART |
| 充电器 | SkyRC B6neo 或同级正品平衡充电器 |
| 安全器材 | Smoke Stopper、阻燃电池袋、蜂鸣器、万用表、护目镜和固定测试架 |
电机可参考 GEPRC SPEEDX2 1404 系列。这个项目优先考虑 3850KV + 3S,不建议第一次测试就组合 4600KV、4S 和高螺距桨。
遥控链路可选择 RadioMaster Pocket M2 ELRS 和 RP1 V2 接收机。RP1 使用 5V 供电和 CRSF 串口,可以连接 ESP32 的硬件 UART。
充电器可参考支持 1~6S 锂电池平衡充电、放电和存储模式的 SkyRC B6neo。还要准备匹配的输入电源和 XT60 转 XT30 充电线。
第一次真正离地时,更稳妥的方案是让成熟的 F405/F722 飞控先负责上锁、失联保护、电机输出和基础姿态控制,ESP32 作为遥测与算法实验的伴随控制器。等固定周期、姿态融合、PID、看门狗和保护逻辑全部通过固定测试架验证,再考虑让 ESP32 直接控制电机。
11. 接下来的计划
- 上电静止校准和陀螺仪零偏补偿;
- 加速度与角速度低通滤波;
- 互补滤波或 Madgwick 姿态融合;
- 固定周期高速传感器任务;
- ELRS/CRSF 遥控接收;
- 角速度内环和姿态外环 PID;
- 电调输出与四电机混控;
- 上锁、失联、低电压、传感器故障和看门狗保护;
- 固定测试架验证;
- 最后才是符合当地规定的低空试飞。
12. 项目地址
完整源码、中英文 README、接线方法和运行步骤已经发布在 GitHub:
这个项目目前还不会飞,但第一层基础已经搭好:传感器数据能够可靠地从硬件流到浏览器,并通过姿态模型和水平仪快速判断数据是否合理。
下一步从陀螺仪零偏校准和姿态融合开始,让这个“静态姿态仪”逐步接近真正的飞控核心。