了解如何将 MPU-6050 加速度计和陀螺仪模块与 Arduino 板一起使用。MPU-6050 IMU(惯性测量单元)是一款 3 轴加速度计和 3 轴陀螺仪传感器。加速度计测量重力加速度,陀螺仪测量旋转速度。此外,该模块还可以测量温度。该传感器是确定移动物体方向的理想选择。
目录
推出 MPU-6050 陀螺仪加速度计传感器
MPU-6050 是一个带有 3 轴加速度计和 3 轴陀螺仪的模块。
陀螺仪测量旋转速度 (rad/s)。这是角位置沿 X、Y 和 Z 轴(横滚、俯仰和偏航)随时间的变化。这使我们能够确定对象的方向。
加速度计测量加速度(物体速度的变化率)。它可以感知重力(9.8m/s 2 )等静态力或振动或运动等动态力。MPU-6050 测量 X、Y 和 Z 轴上的加速度。理想情况下,在静态物体中,Z轴上的加速度等于重力,并且在X轴和Y轴上应为零。
使用加速度计的值,可以使用三角函数计算横滚角和俯仰角。但是,无法计算偏航。
我们可以将来自两个传感器的信息结合起来,以获得有关传感器方向的更准确信息。
MPU-6050 引脚排列
这是 MPU-6050 传感器模块的引脚排列。
VCC | 为传感器供电(3.3V 或 5V) |
GND | 公共 GND |
SCL | 用于 I2C 通信的 SCL 引脚 (A5) |
SDA | 用于 I2C 通信的 SDA 引脚 (A4) |
XDA | 用于将其他 I2C 传感器与 MPU-6050 连接 |
XCL | 用于将其他 I2C 传感器与 MPU-6050 连接 |
AD0 | 使用此引脚更改 I2C 地址 |
INT | 中断引脚 – 可用于指示新的测量数据可用 |
安装库
有多种方法可以从传感器获取读数。在本教程中,我们将使用 Adafruit MPU6050库。要使用此库,您还需要安装 Adafruit 统一传感器库和 Adafruit 总线 IO 库。
安装库后,重新启动Arduino IDE。
获取 MPU-6050 传感器读数:加速度计、陀螺仪和温度
在本节中,您将学习如何从 MPU-6050 传感器获取传感器读数:加速度 (x, y, z)、角速度 (x, y, z) 和温度。
所需零件
对于此示例,您需要以下部件:
- MPU-6050 加速度计陀螺仪
- Arduino
- 面包板
- 跳线
原理图 – Arduino with MPU-6050
如下图所示,将Arduino连接到MPU-6050传感器:将SCL引脚连接到A5,将SDA引脚连接到A4。
代码 – 获取 MPU-6050 传感器读数:加速度计、陀螺仪和温度
Adafruit 库提供了此传感器的几个示例。在本节中,我们将看一个打印串行监视器传感器读数的基本示例。
转到文件> Adafruit MPU6050 > basic_readings>示例。应加载以下代码。
它获取 x、y 和 z 轴上的角速度(陀螺仪)、x、y 和 z 轴上的加速度以及温度。
//Adafruit MPU6050的加速度计读数的基本演示
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
Adafruit_MPU6050 mpu;
void setup(void) {
Serial.begin(115200);
while (!Serial)
delay(10); // will pause Zero, Leonardo, etc until serial console opens
Serial.println("Adafruit MPU6050 test!");
// Try to initialize!
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) {
delay(10);
}
}
Serial.println("MPU6050 Found!");
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
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);
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_5_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() {
/* Get new sensor events with the readings */
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
/* Print out the values */
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);
}
代码的工作原理
首先包括 MPU-6050 传感器所需的库:Adafruit_MPU6050 和 Adafruit_Sensor。
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
创建一个名为 mpu 的Adafruit_MPU6050对象来处理传感器。
Adafruit_MPU6050 mpu;
setup()
在 setup() 中,以波特率为 115200 初始化串行监视器。
Serial.begin(115200);
初始化 MPU-6050 传感器。
if (!mpu.begin()) {
Serial.println("Sensor init failed");
while (1)
yield();
}
设置加速度计测量范围:
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
设置陀螺仪测量范围:
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
设置滤波器带宽:
mpu.setFilterBandwidth(MPU6050_BAND_5_HZ);
loop()
在 loop() 中,我们将获取传感器读数并将它们显示在串行监视器中。
首先,您需要获取包含当前读数的新传感器事件。
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
最后,打印读数。对于加速:
- a.acceleration.x:获取 x 轴上的加速度;
- a.acceleration.y:获取 y 轴上的加速度;
- a.acceleration.z:获取 z 轴上的加速度。
加速度以米/秒平方 (m/s 2 ) 为单位测量
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");
要获取陀螺仪读数:
- g.gyro.x:获取 x 轴上的角速度;
- g.gyro.y:获取 y 轴上的角速度;
- g.gyro.z:获取 z 轴上的角速度。
角速度以弧度每秒 (rad/s) 为单位。
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");
最后,打印温度——以摄氏度为单位。要访问温度读数,请使用 temp.temperature。
Serial.print("Temperature: ");
Serial.print(temp.temperature);
Serial.println(" degC");
每 500 毫秒显示一次新的传感器读数。
delay(500);
示范
将代码上传到Arduino板。
然后,以 115200 的波特率打开串行监视器,按下板载 RST 按钮。将显示传感器测量值。
移动传感器方向,并查看值的相应变化。
传感器校准
理想情况下,当传感器处于静态状态时,陀螺仪值在所有轴上都应为零,这在我们的例子中不会发生。当传感器静止时,我们得到的陀螺仪值如下:
- x:0.06弧度/秒
- Y:-0.02弧度/秒
- Z值:0.00弧度/秒
在实际应用中,您需要考虑误差并更正代码中的值以获得更准确的读数。
加速度值也是如此。Z 轴加速度应更接近重力 (9,8 m/s2),X 轴和 Y 轴上的加速度应更接近零。在我们的例子中,这些是传感器静态时我们得到的近似值:
- x:0.71 米/秒 2
- Y:0.28 米/秒 2
- Z轴:9.43 米/秒 2
在串行绘图仪上显示 MPU-6050 读数
有一个类似的示例,但在串行绘图仪上显示读数略有不同。
将以下代码上传到您的开发板:
上传代码后,在Arduino IDE中转到“工具”>“串行绘图仪”。
串行绘图仪在 X、Y 和 Z 轴上显示加速度计和陀螺仪读数随时间的变化。以不同的方式移动传感器,看看这些值是如何变化的。
在 OLED 显示屏上显示 MPU-6050 读数
Adafruit MPU6050库提供了一个示例,用于在 OLED 显示屏上显示 MPU-6050 陀螺仪和加速度计读数。
所需零件
以下是完成此示例所需的部分:
- MPU-6050 加速度计陀螺仪
- Arduino
- 0.96英寸I2C OLED显示屏SSD1306
- 面包板
- 跳线
原理图 – Arduino与MPU-6050和OLED显示屏
如下图所示连接所有部件。由于OLED显示器和MPU-6050传感器使用不同的I2C地址,因此我们可以将它们连接到相同的I2C总线(Arduino板上的相同引脚)。
代码 – 在 OLED 显示屏上显示 MPU-6050 传感器读数
要使用此示例,请确保已安装 Adafruit SSD1306库。该库可以通过Arduino库管理器进行安装。
转到 Sketch > Library > Manage Libraries,然后搜索“SSD1306”,然后从 Adafruit 安装 SSD1306 库。
对于此示例,请复制以下代码或转到 Adafruit MPU6050 > MPU6050_oled >文件>示例。
/********************************************
* Arduino/ESP8266/ESP32/STM32等相关教程
* 浏览趣讨教创客平台:https://www.qutaojiao.com
********************************************/
int rainPin = A0;
int greenLED = 6;
int redLED = 7;
// you can adjust the threshold value
int thresholdValue = 800;
void setup(){
pinMode(rainPin, INPUT);
pinMode(greenLED, OUTPUT);
pinMode(redLED, OUTPUT);
digitalWrite(greenLED, LOW);
digitalWrite(redLED, LOW);
Serial.begin(9600);
}
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(rainPin);
Serial.print(sensorValue);
if(sensorValue < thresholdValue){
Serial.println(" - Doesn't need watering");
digitalWrite(redLED, LOW);
digitalWrite(greenLED, HIGH);
}
else {
Serial.println(" - Time to water your plant");
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, LOW);
}
delay(500);
}
#include <Adafruit_MPU6050.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
Adafruit_MPU6050 mpu;
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &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_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64
Serial.println(F("SSD1306 allocation failed"));
for (;;)
; // Don't proceed, loop forever
}
display.display();
delay(500); // Pause for 2 seconds
display.setTextSize(1);
display.setTextColor(WHITE);
display.setRotation(0);
}
void loop() {
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);
}
代码的工作原理
首先包括 MPU-6050 传感器和 OLED 显示器所需的库。
#include <Adafruit_MPU6050.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
创建一个名为 mpu 的Adafruit_MPU6050对象来处理传感器。
Adafruit_MPU6050 mpu;
创建一个名为 display 的Adafruit_SSD1306对象来处理 OLED 显示器。这适用于具有 128×64 像素的显示器。
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);
setup()
在 setup() 中,以波特率为 115200 初始化串行监视器。
Serial.begin(115200);
初始化 MPU-6050 传感器。
if (!mpu.begin()) {
Serial.println("Sensor init failed");
while (1)
yield();
}
初始化OLED显示屏。
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64
Serial.println(F("SSD1306 allocation failed"));
for (;;)
; // Don't proceed, loop forever
}
display.display();
设置显示的字体大小和颜色。
display.setTextSize(1);
display.setTextColor(WHITE);
display.setRotation(0);
loop()
在 loop() 中,我们将获取传感器读数并将它们显示在 OLED 上。
首先为每个测量、加速度计、陀螺仪和温度创建事件。
sensors_event_t a, g, temp;
获取新的传感器读数。
mpu.getEvent(&a, &g, &temp);
清除每个 loop() 中的显示以写入新的读数。
display.clearDisplay();
将显示光标设置为 (0,0) – 左上角。它将从该位置开始写入文本。
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");
以下几行显示OLED显示屏上的加速度x、y和z值。
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() 以实际显示 OLED 上的读数。
display.display();
每 100 毫秒显示一次新读数。
delay(100);
示范
将代码上传到Arduino开发板。
以 115200 的波特率打开串行监视器,按下板载 RST 按钮。传感器测量值将显示在串行监视器和OLED显示屏上。
移动传感器并查看值的变化。
总结
MPU-6050 是一款加速度计和陀螺仪。它测量 X、Y 和 Z 轴上的加速度以及角速度。该模块还可以测量温度。
该传感器模块通过 I2C 通信协议进行通信。因此,接线很简单。只需将传感器连接到Arduino I2C引脚即可。
在本教程中,您学习了如何连接传感器并获取传感器读数。