上一篇简单介绍了陀螺仪的基本内容,本篇主要针对陀螺仪的代码使用进行分析。
上一篇关于陀螺仪的基本内容的链接:(58条消息) 【Arduino小车实践】陀螺仪的使用_禾风wyh的博客-CSDN博客
Adafruit_MPU6050.h |
包含了 MPU6050 加速度计的功能,包括初始化、获取数据等 |
Adafruit_Sensor.h |
为了支持 MPU6050 加速度计的传感器事件。它提供了一种统一的接口用于获取不同类型传感器(如加速度计、陀螺仪、磁力计等)的数据 |
Wire.h |
了支持 MPU6050 加速度计的传感器事件。它提供了一种统一的接口用于获取不同类型传感器(如加速度计、陀螺仪、磁力计等)的数据 |
Adafruit_MPU6050 mpu; //这行代码定义了一个名为 mpu 的对象,其类型为 Adafruit_MPU6050,用于与 MPU6050 加速度计进行通信和操作。
在代码中的其他部分,可以使用这个对象来调用 Adafruit_MPU6050
类中提供的方法,如 begin()
、getEvent()
、setAccelerometerRange()
等,以实现对 MPU6050 加速度计的初始化、数据获取和设置等操作。
void MPU_START(void){//用于启动 MPU6050 传感器
Wire.beginTransmission(0x68); //开启MPU6050的传输
Wire.write(0x6B); //指定寄存器地址,0x68 是 MPU6050 的 I2C 地址
Wire.write(0); //将 MPU6050 的寄存器 0x6B 写入 0,以启动 MPU6050
Wire.endTransmission(true); //结束传输,true表示释放总线
}
void GYRO_CONFIG_SET(int f){ //配置角速度倍率
Wire.beginTransmission(0x68); //开启MPU-6050的传
Wire.write(0x1B); //角速度倍率寄存器的地址
Wire.requestFrom(0x68, 1, true); //从 MPU6050 的寄存器地址 0x1B 请求读取 1 个字节的数据,读出原来的配置
unsigned char acc_conf = Wire.read();//将读取到的数据保存在变量 acc_conf 中。这个变量用于存储原配置的值
acc_conf = ((acc_conf & 0xE7) | (f << 3));//对 acc_conf 进行位运算,以设置新的角速度倍率。通过 f 参数左移 3 位,并和原配置进行按位或操作,从而实现设置新的角速度倍率
Wire.write(acc_conf);//将更新后的角速度倍率配置写入 MPU6050 的寄存器地址 0x1B
Wire.endTransmission(true); //结束传输,true表示释放总线
}
//配置加速度倍率
void ACCEL_CONFIG_SET(int f){
Wire.beginTransmission(0x68); //开启MPU-6050的传输
Wire.write(0x1C); //加速度倍率寄存器的地址
Wire.requestFrom(0x68, 1, true); //先读出原配置
unsigned char acc_conf = Wire.read();
acc_conf = ((acc_conf & 0xE7) | (f << 3));
Wire.write(acc_conf);
Wire.endTransmission(true); //结束传输,true表示释放总线
}
//获取MPU数据
void Get_Value(void){
//获取各个轴分量数据
Wire.beginTransmission(0x68); //开启MPU-6050的传输
Wire.write(0x3B);
Wire.requestFrom(0x68, 7 * 2, true);
Wire.endTransmission(true);
for (long i = 0; i < 7; ++i) {
val_seven[i] = Wire.read() << 8 | Wire.read();
}
//数据换算
val_seven[0] = (float)(val_seven[0] / 32768 * (2 ^ ACCEL_CONFIG) *G);//acc_x
val_seven[1] = (float)(val_seven[1] / 32768 * (2 ^ ACCEL_CONFIG) * G);//acc_y
val_seven[2] = (float)(val_seven[2] / 32768 * (2 ^ ACCEL_CONFIG) *G);//acc_z
val_seven[3] = (float)(val_seven[3] / 340 + 36.53);//acc_z
val_seven[4] = (float)(val_seven[4] / 32768 * (2 ^ GYRO_CONFIG) *250);//gyr_x
val_seven[5] = (float)(val_seven[5] / 32768 * (2 ^ GYRO_CONFIG) *250);//gyr_y
val_seven[6] = (float)(val_seven[6] / 32768 * (2 ^ GYRO_CONFIG) *250);//gyr_z
}
//接线方式:VCC--5V、GND--GND、SCL--A5、SDA--A4、AD0--AD0引脚为地址选择引脚,悬空或者接GND,硬件地址为0x68,接VCC/高电平硬件地址为0x69 INT--中断引脚,如果用到可以接中端口,此处不接
#include
#define ACCEL_CONFIG 1 //加速度倍率配置选项
#define GYRO_CONFIG 1 //角速度速度倍率配置选项
//(具体的倍率与具体的 MPU6050 模块和应用有关,在使用时需要根据实际情况进行设置和调整)
#define G 9.8 //重力加速度
float val_seven[7];
void MPU_START(void){//用于启动 MPU6050 传感器
Wire.beginTransmission(0x68); //开启MPU6050的传输
Wire.write(0x6B); //指定寄存器地址,0x68 是 MPU6050 的 I2C 地址
Wire.write(0); //将 MPU6050 的寄存器 0x6B 写入 0,以启动 MPU6050
Wire.endTransmission(true); //结束传输,true表示释放总线
}
//配置角速度倍率
void GYRO_CONFIG_SET(int f){
Wire.beginTransmission(0x68); //开启MPU-6050的传
Wire.write(0x1B); //角速度倍率寄存器的地址
Wire.requestFrom(0x68, 1, true); //从 MPU6050 的寄存器地址 0x1B 请求读取 1 个字节的数据,读出原来的配置
unsigned char acc_conf = Wire.read();//将读取到的数据保存在变量 acc_conf 中。这个变量用于存储原配置的值
acc_conf = ((acc_conf & 0xE7) | (f << 3));//对 acc_conf 进行位运算,以设置新的角速度倍率。通过 f 参数左移 3 位,并和原配置进行按位或操作,从而实现设置新的角速度倍率
Wire.write(acc_conf);//将更新后的角速度倍率配置写入 MPU6050 的寄存器地址 0x1B
Wire.endTransmission(true); //结束传输,true表示释放总线
}
//配置加速度倍率
void ACCEL_CONFIG_SET(int f){
Wire.beginTransmission(0x68); //开启MPU-6050的传输
Wire.write(0x1C); //加速度倍率寄存器的地址
Wire.requestFrom(0x68, 1, true); //先读出原配置
unsigned char acc_conf = Wire.read();
acc_conf = ((acc_conf & 0xE7) | (f << 3));
Wire.write(acc_conf);
Wire.endTransmission(true); //结束传输,true表示释放总线
}
//获取MPU数据
void Get_Value(void){
//获取各个轴分量数据
Wire.beginTransmission(0x68); //开启MPU-6050的传输
Wire.write(0x3B);
Wire.requestFrom(0x68, 7 * 2, true);
Wire.endTransmission(true);
for (long i = 0; i < 7; ++i) {
val_seven[i] = Wire.read() << 8 | Wire.read();
}
//数据换算
val_seven[0] = (float)(val_seven[0] / 32768 * (2 ^ ACCEL_CONFIG) *G);//acc_x
val_seven[1] = (float)(val_seven[1] / 32768 * (2 ^ ACCEL_CONFIG) * G);//acc_y
val_seven[2] = (float)(val_seven[2] / 32768 * (2 ^ ACCEL_CONFIG) *G);//acc_z
val_seven[3] = (float)(val_seven[3] / 340 + 36.53);//acc_z
val_seven[4] = (float)(val_seven[4] / 32768 * (2 ^ GYRO_CONFIG) *250);//gyr_x
val_seven[5] = (float)(val_seven[5] / 32768 * (2 ^ GYRO_CONFIG) *250);//gyr_y
val_seven[6] = (float)(val_seven[6] / 32768 * (2 ^ GYRO_CONFIG) *250);//gyr_z
}
// The setup() function runs once each time the micro-controller starts
void setup(){
Serial.begin(9600);
Wire.begin();//以主机模式开启总线
MPU_START();//启动MPU6050
GYRO_CONFIG_SET(0);//配置器件角速度倍率
ACCEL_CONFIG_SET(0);//配置器件加速度倍率
}
// Add the main program code into the continuous loop() function
void loop(){
Get_Value();
Serial.print("acc_x:");
Serial.print('\t');
Serial.println(val_seven[0]);
Serial.print("acc_y:");
Serial.print('\t');
Serial.println(val_seven[1]);
Serial.print("acc_z:");
Serial.print('\t');
Serial.println(val_seven[2]);
Serial.print("gyr_x:");
Serial.print('\t');
Serial.println(val_seven[4]);
Serial.print("gyr_y:");
Serial.print('\t');
Serial.println(val_seven[5]);
Serial.print("gyr_z:");
Serial.print('\t');
Serial.println(val_seven[6]);
Serial.print("TEMP:");
Serial.print('\t');
Serial.println(val_seven[3]);
delay(500);
}
设置 MPU6050 加速度计的初始化配置,并在串口终端上输出相关信息
void setup(){
Serial.begin(115200);//初始化串口通信,设置波特率为 115200
while (!Serial) delay(10);//等待直到串口连接完成,以防止一些板子(如Arduino Zero、Leonardo等)在未连接串口时继续执行
Serial.println("Adafruit MPU6050 test!");
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) delay(10);
}//尝试初始化 MPU6050 加速度计。如果初始化失败,则在串口终端上输出,并进入无限循环
Serial.println("MPU6050 Found!");
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);//设置加速度计的量程为 ±8G
Serial.print("Accelerometer range set to: ");
switch (mpu.getAccelerometerRange()){//检查并输出当前加速度计的量程设置
case MPU6050_RANGE_2_G:
Serial.println("+-2G");
break;
case MPU6050_RANGE_4_G:
Serial.println("+-4G");
break;
case MPU6050_RANGE_8_G:
Serial.println("+-8G");
break;
case MPU6050_RANGE_16_G:
Serial.println("+-16G");
break;
}
mpu.setGyroRange(MPU6050_RANGE_500_DEG);//设置陀螺仪的量程为 ±500°/s
Serial.print("Gyro range set to: ");
switch (mpu.getGyroRange()) {//检查并输出当前陀螺仪的量程设置
case MPU6050_RANGE_250_DEG:
Serial.println("+- 250 deg/s");
break;
case MPU6050_RANGE_500_DEG:
Serial.println("+- 500 deg/s");
break;
case MPU6050_RANGE_1000_DEG:
Serial.println("+- 1000 deg/s");
break;
case MPU6050_RANGE_2000_DEG:
Serial.println("+- 2000 deg/s");
break;
}
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);//设置滤波器的带宽为 21 Hz
Serial.print("Filter bandwidth set to: ");
switch (mpu.getFilterBandwidth()) {//检查并输出当前陀螺仪滤波器的带宽设置
case MPU6050_BAND_260_HZ:
Serial.println("260 Hz");
break;
case MPU6050_BAND_184_HZ:
Serial.println("184 Hz");
break;
case MPU6050_BAND_94_HZ:
Serial.println("94 Hz");
break;
case MPU6050_BAND_44_HZ:
Serial.println("44 Hz");
break;
case MPU6050_BAND_21_HZ:
Serial.println("21 Hz");
break;
case MPU6050_BAND_10_HZ:
Serial.println("10 Hz");
break;
case MPU6050_BAND_5_HZ:
Serial.println("5 Hz");
break;
}
Serial.println("");
delay(100);
}
void loop() {
sensors_event_t a, g, temp;//声明三个 sensors_event_t 类型的变量 a、g 和 temp,用于存储加速度、角速度和温度的传感器事件数据
mpu.getEvent(&a, &g, &temp);//通过调用 getEvent() 方法,获取最新的传感器事件数据,并将其保存到对应的变量中。
Serial.print("Acceleration X: ");
Serial.print(a.acceleration.x);
Serial.print(", Y: ");
Serial.print(a.acceleration.y);
Serial.print(", Z: ");
Serial.print(a.acceleration.z);
Serial.println(" m/s^2");
Serial.print("Rotation X: ");
Serial.print(g.gyro.x);
Serial.print(", Y: ");
Serial.print(g.gyro.y);
Serial.print(", Z: ");
Serial.print(g.gyro.z);
Serial.println(" rad/s");
Serial.print("Temperature: ");
Serial.print(temp.temperature);
Serial.println(" degC");
Serial.println("");
delay(500);
}
用于检测 MPU6050 模块的运动中断,并在检测到运动时打印加速度和角速度数据。
void setup(void) {
Serial.begin(115200);
while (!Serial) delay(10); // 等待串口打开,适用于 Zero、Leonardo 等板型
Serial.println("Adafruit MPU6050 test!");
// 尝试初始化 MPU6050
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) delay(10);
}
Serial.println("MPU6050 Found!");
// 设置运动检测
mpu.setHighPassFilter(MPU6050_HIGHPASS_0_63_HZ);
mpu.setMotionDetectionThreshold(1);
mpu.setMotionDetectionDuration(20);
mpu.setInterruptPinLatch(true); // 保持中断触发状态,重新初始化时将关闭
mpu.setInterruptPinPolarity(true);
mpu.setMotionInterrupt(true);
Serial.println("");
delay(100);
}
void loop() {
if (mpu.getMotionInterruptStatus()) {
/* 获取新的传感器事件数据 */
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
/* 打印数值 */
Serial.print("AccelX:");
Serial.print(a.acceleration.x);
Serial.print(",");
Serial.print("AccelY:");
Serial.print(a.acceleration.y);
Serial.print(",");
Serial.print("AccelZ:");
Serial.print(a.acceleration.z);
Serial.print(", ");
Serial.print("GyroX:");
Serial.print(g.gyro.x);
Serial.print(",");
Serial.print("GyroY:");
Serial.print(g.gyro.y);
Serial.print(",");
Serial.print("GyroZ:");
Serial.print(g.gyro.z);
Serial.println("");
}
delay(10);
}
通过 MPU6050 传感器获取加速度和角速度数据,并通过 SSD1306 OLED 显示屏显示数据
//导入库函数
#include
#include
#include
//创建对象
Adafruit_MPU6050 mpu;
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &Wire);
void setup() {
Serial.begin(115200);
while (!Serial);
Serial.println("MPU6050 OLED demo");
if (!mpu.begin()) {
Serial.println("Sensor init failed");
while (1) yield();
}
Serial.println("Found a MPU-6050 sensor");
//设置 SSD1306 OLED 显示屏的相关参数
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;)
;
}
display.display();
delay(500); // Pause for 2 seconds
display.setTextSize(1);
display.setTextColor(WHITE);
display.setRotation(0);
}
void loop() {
//获取 MPU6050 的加速度和角速度数据,并打印到串口和显示屏上
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
display.clearDisplay();
display.setCursor(0, 0);
Serial.print("Accelerometer ");
Serial.print("X: ");
Serial.print(a.acceleration.x, 1);
Serial.print(" m/s^2, ");
Serial.print("Y: ");
Serial.print(a.acceleration.y, 1);
Serial.print(" m/s^2, ");
Serial.print("Z: ");
Serial.print(a.acceleration.z, 1);
Serial.println(" m/s^2");
display.println("Accelerometer - m/s^2");
display.print(a.acceleration.x, 1);
display.print(", ");
display.print(a.acceleration.y, 1);
display.print(", ");
display.print(a.acceleration.z, 1);
display.println("");
Serial.print("Gyroscope ");
Serial.print("X: ");
Serial.print(g.gyro.x, 1);
Serial.print(" rps, ");
Serial.print("Y: ");
Serial.print(g.gyro.y, 1);
Serial.print(" rps, ");
Serial.print("Z: ");
Serial.print(g.gyro.z, 1);
Serial.println(" rps");
display.println("Gyroscope - rps");
display.print(g.gyro.x, 1);
display.print(", ");
display.print(g.gyro.y, 1);
display.print(", ");
display.print(g.gyro.z, 1);
display.println("");
display.display();
delay(100);
}
#include
Adafruit_MPU6050 mpu;
Adafruit_Sensor *mpu_temp, *mpu_accel, *mpu_gyro;
void setup(void) {
Serial.begin(115200);
while (!Serial) delay(10);
Serial.println("Adafruit MPU6050 test!");
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) delay(10);
}
Serial.println("MPU6050 Found!");
mpu_temp = mpu.getTemperatureSensor();
mpu_temp->printSensorDetails();
mpu_accel = mpu.getAccelerometerSensor();
mpu_accel->printSensorDetails();
mpu_gyro = mpu.getGyroSensor();
mpu_gyro->printSensorDetails();
}
void loop() {
sensors_event_t accel;
sensors_event_t gyro;
sensors_event_t temp;
mpu_temp->getEvent(&temp);
mpu_accel->getEvent(&accel);
mpu_gyro->getEvent(&gyro);
Serial.print("\t\tTemperature ");
Serial.print(temp.temperature);
Serial.println(" deg C");
Serial.print("\t\tAccel X: ");
Serial.print(accel.acceleration.x);
Serial.print(" \tY: ");
Serial.print(accel.acceleration.y);
Serial.print(" \tZ: ");
Serial.print(accel.acceleration.z);
Serial.println(" m/s^2 ");
Serial.print("\t\tGyro X: ");
Serial.print(gyro.gyro.x);
Serial.print(" \tY: ");
Serial.print(gyro.gyro.y);
Serial.print(" \tZ: ");
Serial.print(gyro.gyro.z);
Serial.println(" radians/s ");
Serial.println();
delay(100);
}