#include <Arduino.h>
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"
class IMU {
/*类(Class) 是C++中用于封装数据和功能的用户自定义类型。
示例中的 IMU 是类名,用于表示一个惯性测量单元(Inertial Measurement Unit)的抽象模型。
类可以包含:
成员变量(属性):如 ax, ay, az(存储传感器原始数据)
成员函数(方法):如 init(), update()(操作数据的函数)*/
private:
MPU6050 imu;
int16_t ax, ay, az;
int16_t gx, gy, gz;
int16_t temperature;
/*private:
表示后续成员(直到下一个访问修饰符出现前)都是 私有成员,
只能在类的内部(成员函数中)访问,外部代码无法直接操作。
成员变量列表:
这些变量存储了MPU6050传感器的原始数据*/
public:
int init();
void update();
int16_t getAccelX();
int16_t getAccelY();
int16_t getAccelZ();
int16_t getGyroX();
int16_t getGyroY();
int16_t getGyroZ();
int16_t getTemperature();
};
IMU imu;
void setup() {
Serial.begin(115200);
imu.init();
}
void loop() {
imu.update();
// display tab-separated accel/gyro x/y/z values
Serial.print("a/g/t:\t");
Serial.print(imu.getAccelX()); Serial.print("\t");
Serial.print(imu.getAccelY()); Serial.print("\t");
Serial.print(imu.getAccelZ()); Serial.print("\t");
Serial.print(imu.getGyroX()); Serial.print("\t");
Serial.print(imu.getGyroY()); Serial.print("\t");
Serial.print(imu.getGyroZ()); Serial.print("\t");
Serial.println(imu.getTemperature());
delay(100);
}
int IMU::init()
{
// initialize i2c
Wire.begin();
Wire.setClock(400000);
/*Wire 库是 Arduino 和 ESP32 等嵌入式平台用于 I2C/TWI(Inter-Integrated
Circuit)通信 的核心库,它允许微控制器通过I2C协议与传感器、存储器、显示屏
等外设进行数据交换。*/
// initialize device
Serial.println("Initializing I2C devices...");
imu.initialize();
// verify connection
Serial.println("Testing device connections...");
if (imu.testConnection()) {
Serial.println("MPU6050 connection successful");
return 0;
} else {
Serial.println("MPU6050 connection failed");
return -1;
}
}
void IMU::update()
{
// read raw accel/gyro measurements from device
imu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
// read temperature
temperature = imu.getTemperature();
}
int16_t IMU::getAccelX()
{
return ax;
}
int16_t IMU::getAccelY()
{
return ay;
}
int16_t IMU::getAccelZ()
{
return az;
}
int16_t IMU::getGyroX()
{
return gx;
}
int16_t IMU::getGyroY()
{
return gy;
}
int16_t IMU::getGyroZ()
{
return gz;
}
int16_t IMU::getTemperature()
{
return temperature;
}
1. 代码结构解析
(1) 头文件引入
#include <Arduino.h> // Arduino核心库
#include "I2Cdev.h" // I2C通信基础库
#include "MPU6050.h" // MPU6050专用驱动
#include "Wire.h" // Arduino I2C库
- 作用:提供I2C通信和MPU6050传感器的基础支持。
(2) IMU类定义
class IMU {
private:
MPU6050 imu; // MPU6050传感器对象
int16_t ax, ay, az; // 加速度计原始数据
int16_t gx, gy, gz; // 陀螺仪原始数据
int16_t temperature; // 温度数据
public:
int init(); // 初始化传感器
void update(); // 更新传感器数据
// 数据获取方法...
};
- 封装设计:将MPU6050操作封装为类,提高代码复用性。
(3) 关键方法实现
方法 | 功能 |
---|---|
IMU::init() | 初始化I2C总线(400kHz时钟),检测MPU6050连接状态 |
IMU::update() | 读取加速度计、陀螺仪和温度的原始数据 |
getAccelX() 等 | 提供私有数据的访问接口 |
(4) 主程序逻辑
void setup() {
Serial.begin(115200); // 初始化串口
imu.init(); // 初始化IMU
}
void loop() {
imu.update(); // 更新传感器数据
// 打印数据到串口...
delay(100); // 控制输出频率
}
- 工作流程:每100ms读取一次传感器数据并通过串口输出。
2. 代码流程图
流程图说明:
-
初始化阶段:
- 启动串口通信(115200波特率)。
- 初始化I2C总线并检测MPU6050连接状态。
-
主循环阶段:
- 持续调用
imu.update()
获取最新传感器数据。 - 将数据格式化为表格形式通过串口输出。
- 通过
delay(100)
控制数据更新频率(10Hz)。
- 持续调用
3. 关键技术细节
(1) I2C高速模式
Wire.setClock(400000); // 设置I2C时钟为400kHz
- 意义:MPU6050支持高速I2C模式,提升数据读取效率。
(2) 数据读取方法
imu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
- 功能:一次性读取6轴数据(加速度XYZ + 陀螺仪XYZ),减少I2C通信次数。
(3) 串口数据格式
a/g/t: -1234 5678 -9012 3456 -7890 1234 36
- 字段顺序:加速度X/Y/Z → 陀螺仪X/Y/Z → 温度值。