ESP32-WROOM-32 + MPU6050 获取设备姿态信息(Arduino-CLI 版)
📌 本文档适用于 树莓派 上通过 arduino-cli 构建 ESP32-WROOM-32 + MPU6050 项目。
📋 目录
- 1. 硬件连接
- 2. 安装 arduino-cli 和 ESP32 开发环境
- 3. 安装依赖库
- 4. 创建 Arduino Sketch 项目
- 5. 编译并上传代码
- 6. 查看输出结果
- 7. 常见问题排查
- 8. 进阶建议
1. 硬件连接
MPU6050 引脚 | ESP32-WROOM-32 引脚 |
---|---|
VCC | 3.3V |
GND | GND |
SCL | GPIO22(I2C SCL) |
SDA | GPIO21(I2C SDA) |
INT | GPIO16(中断引脚) |
AD0 | GND(I2C地址0x68) |
✅ 注意:ESP32 的 I2C 引脚可自定义,默认使用 GPIO21(SDA)和 GPIO22(SCL)。
2. 安装 arduino-cli 和 ESP32 开发环境
# 安装 arduino-cli
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh
# 添加到环境变量
echo 'export PATH=$PATH:$HOME/bin' >> ~/.bashrc
source ~/.bashrc
# 初始化配置
arduino-cli config init
arduino-cli core update-index
# 安装 ESP32 开发板支持
arduino-cli core install esp32:esp32
3. 安装依赖库
# 安装库
arduino-cli lib install "I2Cdevlib-MPU6050"
⚠️ 若无法通过
arduino-cli lib install
安装,可手动下载:
bash cd ~/Arduino/libraries git clone https://github.com/jrowberg/i2cdevlib mv i2cdevlib/Arduino/I2Cdev . mv i2cdevlib/Arduino/MPU6050 .
4. 创建 Arduino Sketch 项目
创建项目目录:
mkdir -p ~/esp32_mpu6050_dmp
cd ~/esp32_mpu6050_dmp
创建主文件:esp32_mpu6050_dmp.ino
#include <Arduino.h>
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include "Wire.h"
#define INTERRUPT_PIN 16
MPU6050 mpu;
volatile bool mpuInterrupt = false;
bool dmpReady = false;
uint8_t mpuIntStatus;
uint8_t devStatus;
uint16_t packetSize;
uint8_t fifoBuffer[64];
Quaternion q;
VectorFloat gravity;
float ypr[3]; // [yaw, pitch, roll]
void IRAM_ATTR dmpDataReady() {
mpuInterrupt = true;
}
void setup() {
Serial.begin(115200);
Wire.begin(21, 22);
Wire.setClock(400000);
mpu.initialize();
if (!mpu.testConnection()) {
Serial.println("MPU6050连接失败!");
while (1);
}
devStatus = mpu.dmpInitialize();
if (devStatus != 0) {
Serial.printf("DMP初始化失败,状态码:%d\n", devStatus);
while (1);
}
mpu.setXGyroOffset(220);
mpu.setYGyroOffset(76);
mpu.setZGyroOffset(-85);
mpu.setZAccelOffset(1788);
mpu.CalibrateAccel(6);
mpu.CalibrateGyro(6);
mpu.setDMPEnabled(true);
pinMode(INTERRUPT_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();
dmpReady = true;
packetSize = mpu.dmpGetFIFOPacketSize();
Serial.println("ESP32 + MPU6050 DMP 初始化完成!");
}
void loop() {
if (!dmpReady) return;
if (!mpuInterrupt && fifoCount < packetSize) return;
mpuInterrupt = false;
mpuIntStatus = mpu.getIntStatus();
uint16_t fifoCount = mpu.getFIFOCount();
if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
mpu.resetFIFO();
Serial.println("FIFO溢出!");
return;
}
if (mpuIntStatus & 0x02) {
while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
mpu.getFIFOBytes(fifoBuffer, packetSize);
fifoCount -= packetSize;
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
Serial.print("Yaw: "); Serial.print(ypr[0] * 180/M_PI);
Serial.print(" Pitch: "); Serial.print(ypr[1] * 180/M_PI);
Serial.print(" Roll: "); Serial.println(ypr[2] * 180/M_PI);
}
}
5. 编译并上传代码
# 编译
arduino-cli compile --fqbn esp32:esp32:esp32 esp32_mpu6050_dmp
# 上传(替换为你的串口)
arduino-cli upload -p /dev/ttyUSB0 --fqbn esp32:esp32:esp32 esp32_mpu6050_dmp
6. 查看输出结果
打开串口监视器:
arduino-cli monitor -p /dev/ttyUSB0 -c baudrate=115200
示例输出:
Yaw: -12.34 Pitch: 45.67 Roll: -3.21
7. 常见问题排查
问题 | 解决方案 |
---|---|
上传失败 | 按住 BOOT 键再上电,进入下载模式 |
I2C 地址不对 | AD0 接 GND 为 0x68,接 VCC 为 0x69 |
FIFO 溢出 | 检查中断引脚连接,确保中断服务函数已注册 |
数据不稳定 | 确保 MPU6050 固定牢靠,必要时重新校准 |
8. 进阶建议
- 姿态融合优化:使用 Mahony 或 Madgwick 滤波算法,提升动态精度。
- 无线传输:利用 ESP32 的 WiFi 或蓝牙功能,将姿态数据发送到手机或服务器。
- 三维可视化:使用 Processing 或 Unity 接收串口数据,实时显示 3D 模型。