本文章旨在解决两个6050以不同地址向MCU传输数据的功能,数据稳定可靠,加上无线通信可用于姿态控制
将ADO置高电平可将地址由默认ox68改为0x69**
一、检查你的陀螺仪地址是否不同
#include "I2CScanner.h"
I2CScanner scanner;
const byte address;
void debug(byte address)
{
Serial.print("Found at 0x");
Serial.println(address, HEX);
}
void setup()
{
Serial.begin(9600);
while (!Serial) {};
scanner.Init();
}
void loop()
{
scanner.Execute(debug);
delay(5000);
}
效果如图,这里是一块OLED的地址
二、传输数据`
#include <Wire.h>
#include <SoftwareSerial.h>
// 使用软件串口,在数字引脚5和4上创建一个新的串行端口对象
SoftwareSerial mySerial(5, 4);
// 全局变量定义
int num = 0, laststate = 0;
const int MPU2 = 0x69, MPU1 = 0x68; // 两个MPU传感器的I2C地址
const float alpha = 0.98; // 角度计算中的滤波系数
long accelX, accelY, accelZ; // 加速度计数据
float gForceX, gForceY, gForceZ; // 加速度值
float gyroX, gyroY, gyroZ, rotX, rotY, rotZ; // 陀螺仪数据
long accelX2, accelY2, accelZ2; // 第二个MPU的加速度计数据
float gForceX2, gForceY2, gForceZ2; // 第二个MPU的加速度值
float roll_1, pitch_1, roll_2, pitch_2; // 两个MPU的姿态角度
float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ; // 角度值
void setup() {
// 初始化串口通信
Serial.begin(115200);
mySerial.begin(115200);
// 初始化I2C通信
Wire.begin();
// 初始化MPU1传感器
Wire.beginTransmission(MPU1);
Wire.write(0x6B); // 寄存器地址:PWR_MGMT_1
Wire.write(0b00000000); // 设置设备为唤醒模式
Wire.endTransmission();
Wire.beginTransmission(MPU1);
Wire.write(0x1B); // 寄存器地址:GYRO_CONFIG
Wire.write(0x00000000); // 设置陀螺仪量程
Wire.endTransmission();
Wire.beginTransmission(MPU1);
Wire.write(0x1C); // 寄存器地址:ACCEL_CONFIG
Wire.write(0b00000000); // 设置加速度计量程
Wire.endTransmission();
// 初始化MPU2传感器
Wire.beginTransmission(MPU2);
Wire.write(0x6B); // 寄存器地址:PWR_MGMT_1
Wire.write(0b00000000); // 设置设备为唤醒模式
Wire.endTransmission();
Wire.beginTransmission(MPU2);
Wire.write(0x1B); // 寄存器地址:GYRO_CONFIG
Wire.write(0x00000000); // 设置陀螺仪量程
Wire.endTransmission();
Wire.beginTransmission(MPU2);
Wire.write(0x1C); // 寄存器地址:ACCEL_CONFIG
Wire.write(0b00000000); // 设置加速度计量程
Wire.endTransmission();
}
void loop() {
// 获取并打印MPU1和MPU2的数据
GetMpuValue(MPU1);
Serial.print("\t ||| \t");
GetMpuValue(MPU2);
Serial.println(" ");
}
void GetMpuValue(const int MPU) {
if (MPU == 0x68) {
// 读取MPU1的加速度计数据
Wire.beginTransmission(MPU);
Wire.write(0x3B); // 寄存器地址:ACCEL_XOUT_H
Wire.endTransmission();
Wire.requestFrom(MPU, 6);
while (Wire.available() < 6);
accelX = Wire.read() << 8 | Wire.read();
accelY = Wire.read() << 8 | Wire.read();
accelZ = Wire.read() << 8 | Wire.read();
// 读取MPU1的陀螺仪数据
Wire.beginTransmission(MPU);
Wire.write(0x43); // 寄存器地址:GYRO_XOUT_H
Wire.endTransmission();
Wire.requestFrom(MPU, 6);
while (Wire.available() < 6);
gyroX = Wire.read() << 8 | Wire.read();
gyroY = Wire.read() << 8 | Wire.read();
gyroZ = Wire.read() << 8 | Wire.read();
// 计算并打印MPU1的姿态角度
roll_1 = atan2(accelZ, accelY) * 180 / PI;
pitch_1 = -atan2(sqrt(accelY * accelY + accelZ * accelZ), accelX) * 180 / PI;
Serial.print("roll_1: ");
Serial.print(roll_1);
Serial.print(" ");
Serial.print("pitch_1: ");
Serial.print(pitch_1);
Serial.print(" ");
delay(50);
} else if (MPU == 0x69) {
// 读取MPU2的加速度计数据
Wire.beginTransmission(MPU);
Wire.write(0x3B); // 寄存器地址:ACCEL_XOUT_H
Wire.endTransmission();
Wire.requestFrom(MPU, 6);
while (Wire.available() < 6);
accelX = Wire.read() << 8 | Wire.read();
accelY = Wire.read() << 8 | Wire.read();
accelZ = Wire.read() << 8 | Wire.read();
// 读取MPU2的陀螺仪数据
Wire.beginTransmission(MPU);
Wire.write(0x43); // 寄存器地址:GYRO_XOUT_H
Wire.endTransmission();
Wire.requestFrom(MPU, 6);
while (Wire.available() < 6);
gyroX = Wire.read() << 8 | Wire.read();
gyroY = Wire.read() << 8 | Wire.read();
gyroZ = Wire.read() << 8 | Wire.read();
// 计算并打印MPU2的姿态角度
roll_2 = atan2(accelZ, accelY) * 180 / PI;
pitch_2 = -atan2(sqrt(accelY * accelY + accelZ * accelZ), accelX) * 180 / PI;
Serial.print("roll_2: ");
Serial.print(roll_2);
Serial.print(" ");
Serial.print("pitch_2: ");
Serial.print(pitch_2);
Serial.print(" ");
delay(50);
}
}
我上面发的代码使用加速度计的数据计算了滚转角(Roll)和俯仰角(Pitch)。
三、计算滚转角(Roll)和俯仰角(Pitch)的原理解释
滚转角(Roll):
使用 atan2 函数计算滚转角,这个函数可以避免在 y 轴加速度为零时出现除零错误,并且能够提供从 -π 到 π 的结果。计算结果转换为度数(从弧度转换为度数)。
俯仰角(Pitch):
在代码中实现如下:
pitch_1 = -atan2(sqrt(accelY * accelY + accelZ * accelZ), accelX) * 180 / PI;
这段代码使用 atan2 函数计算俯仰角,并且负号用于修正方向。结果也被转换为度数。通过读取 MPU6050 传感器的加速度计数据,并使用 atan2 函数计算滚转角和俯仰角,可以得到传感器在空间中的姿态角。这种方法利用了加速度计的静态特性(即在没有运动时,只测量重力加速度),从而得出姿态角。