风筝
发表于: 2023-2-23 16:17:02 | 显示全部楼层

在孩童时代,科学博览会上的陀螺仪总是让我们惊叹不已,因为它们以奇怪的方式移动,甚至似乎可以抵抗重力。它们独特的特性使它们在从小型遥控直升机到航天飞机上的高级导航系统的一切事物中都至关重要。


近年来,巧妙的工程师成功地开发了微机电陀螺仪。这些MEMS(微机电系统)陀螺仪为一系列全新的创新应用铺平了道路,包括手势识别、增强游戏、增强现实、全景照片捕捉、车辆导航和健身监测等。


毫无疑问,陀螺仪和加速度计各有千秋。 然而,当我们将它们放在一起时,我们可以获得关于物体方向的极其精确的数据。 这就是MPU6050发挥作用的地方。MPU6050包括一个陀螺仪和一个加速度计,使我们能够测量沿所有三个轴的旋转、重力引起的静态加速度和运动引起的动态加速度。


在我们的 Arduino 项目中使用 MPU6050 之前,最好了解加速度计和陀螺仪的工作原理。


加速度计如何工作?

要了解加速度计的工作原理,请想象一个位于3D立方体中的小球。

Accelerometer-Working-Illustration-Weightless-State.jpg


假设立方体在外太空,那里的一切都是失重的,球会简单地漂浮在立方体的中心。


现在,假设每面墙代表一个特定的轴。


如果我们突然以1g的加速度向左移动盒子(单个G力1g相当于重力加速度9.8m/s2),球无疑会撞到墙壁X。如果我们测量球对墙壁X施加的力 ,我们可以获得沿X轴的1g的输出值。

Accelerometer-Working-Illustration-Sudden-Movement.jpg


让我们看看当把这个立方体放在地球上时会发生什么。 球将简单地落在墙Z上,施加1g的力,如下图所示:

Accelerometer-Working-Illustration-Gravitation-Force.jpg


在这种情况下,盒子没有移动,但我们仍然在Z轴上得到1g的读数。 这是因为重力(实际上是加速度的一种形式)以1g的力向下拉球。


虽然此模型并不完全代表真实世界的加速度计传感器是如何构建的,但它通常有助于理解为什么加速度计的输出信号通常以±g为单位指定,或者为什么加速度计在静止时在z轴上读数为1g,或者您可以在不同方向上获得什么样的加速度计读数。


在现实世界中,加速度计基于微机电系统(MEMS 制造技术)。 那么,让我们了解MEMS加速度计的工作原理。


MEMS加速度计如何工作?

MEMS(微机电系统)加速度计是一种建立在硅晶片顶部的微机械结构。

MEMS-Accelerometer-Working.gif


该结构由多晶硅弹簧悬挂。 它允许结构在沿 X、Y 和/或 Z 轴加速时偏转。


由于偏转,固定板和连接到悬挂结构的板之间的电容发生变化。 这种电容变化与沿该轴的加速度成正比。传感器处理这种电容变化并将其转换为模拟输出电压。


陀螺仪是如何工作的?

加速度计测量线性加速度,而陀螺仪测量角旋转。 为此,他们测量了科里奥利效应产生的力。


科里奥利效应

科里奥利效应(Coriolis Effect)指出,当质量 (m) 以速度 (v) 沿特定方向移动并施加外部角速率 (Ω)(红色箭头)时,科里奥利效应会产生一个力(黄色箭头),导致质量垂直移动。 该位移的值与应用的角速率直接相关。

Coriolis-Force-On-a-Mass.png

考虑以恒定频率沿相反方向振荡的两个质量。 当施加角速率时,每个质量块产生的科里奥利效应方向相反,导致质量块之间的电容成比例变化。 通过测量这种电容变化,可以计算出角速率。

Coriolis-Force-On-Two-Masses.png


MEMS陀螺仪如何工作?

MEMS 传感器由一个质量块(由 M1、M2、M3 和 M4四个部分组成)组成,该质量块保持连续振荡运动,以便对科里奥利效应做出响应。 它们在水平面上同时向内和向外移动。

MPU6050-Accel-Gyro-Working-Drive-Mode-Output.gif


当我们开始旋转结构时,作用在移动质量块上的科里奥利力会导致振动从水平方向变为垂直方向。


根据应用角度旋转的轴,存在三种模式。


滚动模式(Roll Mode):

当沿 X 轴施加角速率时,由于科里奥利效应,M1和M3将在平面外上下移动。 这会导致滚动角度发生变化,因此称为滚动模式。

MPU6050-Accel-Gyro-Working-Roll-Mode-Output.gif

俯仰模式(Pitch Mode):

当沿Y轴施加角速率时,M2和M4将在平面外上下移动。 这会导致俯仰角发生变化,因此称为俯仰模式。

MPU6050-Accel-Gyro-Working-Pitch-Mode-Output.gif


偏航模式(Yaw Mode):

当沿 Z 轴施加角速率时,M2和M4将沿相反方向水平移动。 这会导致偏航角发生变化,因此称为偏航模式。

MPU6050-Accel-Gyro-Working-Yaw-Mode-Output.gif


每当检测到科里奥利效应时,驱动块的恒定运动将引起电容 (ΔC) 的变化,该变化由传感结构检测并转换为电压信号。


供您参考,以下就是3轴数字陀螺仪的MEMS结构芯片的外观。 感谢Adam McCombs分享这张拆开的L3GD20HTR MEMS陀螺仪图片。

Decaped-L3GD20HTR-MEMS-Gyroscope.jpg


MPU6050模块硬件概述

该模块的核心是一个低功耗、低成本的6轴运动跟踪芯片 – MPU6050, 将3轴陀螺仪、3轴加速度计和数字运动处理器 (DMP) 集成到一个4mm x 4mm 的微型芯片中。


它可以测量沿所有三个轴的角动量或旋转、重力引起的静态加速度以及运动、冲击或振动引起的动态加速度。

MPU6050-Module-Hardware-Overview.jpg


该模块包括一个板载LD3985 3.3V稳压器,因此您可以安全地将它与Arduino等5V逻辑微控制器一起使用。


MPU6050 在测量期间消耗的电流小于 3.6mA,闲置时仅为 5μA。 由于其低功耗,可用于电池供电设备。


此外,该模块有一个电源LED,当模块通电时会亮起。


测量加速度

MPU6050有一个片上加速度计,可以在±2g、±4g、±8g 和 ±16g四个可编程满量程范围内测量加速度。

MPU6050-Module-Accelerometer-Axis.jpg

MPU6050配备三个16位模数转换器,可同时对三个运动轴(沿 X、Y 和 Z 轴)进行采样。


测量旋转

MPU6050有一个片上陀螺仪,可以在±250°/s、±500°/s、±1000°/s 和 ±2000°/s的四个可编程满量程范围内测量角旋转。

MPU6050-Module-Gyroscope-Axis.jpg

MPU6050 配备了三个 16 位模数转换器,可同时对三个旋转轴(沿 X、Y 和 Z 轴)进行采样。 采样率可以在每秒3.9到8000个样本之间调整。


测量温度

MPU6050包括一个嵌入式温度传感器,可以以 ±1°C 的精度测量 -40 至 85°C 的温度。


请注意,此温度测量是硅芯片本身的温度,而不是环境温度。 这些测量通常用于补偿加速度计和陀螺仪校准或检测温度变化,而不是测量绝对温度。


I2C接口

该模块通过I2C接口与Arduino通信。 它支持两种不同的I2C地址:0x68H和0x69H。这允许两个MPU6050在同一总线上使用或避免与总线上的其他设备发生地址冲突。

MPU6050-Module-I2C-Address-Selection-Pin.jpg


ADO引脚决定模块的 I2C 地址。 该引脚通过4.7K电阻下拉。 因此,当您不连接ADO引脚时,默认I2C地址为0x68H; 当你将它连接到3.3V时,线路被拉高,I2C地址变为0x69H。


跳转到指定楼层
风筝
发表于: 2023-2-23 16:46:31 | 显示全部楼层

MPU6050模块的引脚分布

MPU6050模块的引脚分布如下所示:

MPU6050-3-axis-Accelerometer-Gyroscope-Module-Pinout.png

VCC 为模块供电。

GND 是接地引脚。

SCL 是I2C接口的串行时钟引脚。

SDA 是I2C接口的串行数据引脚。

XDA 是外部I2C数据线。外部I2C总线用于连接外部传感器,例如磁力计。

XCL 是外部I2C时钟线。

AD0 允许您更改MPU6050模块的I2C地址。

INT 是中断输出引脚。


将MPU6050模块连接到Arduino开发板

MPU6050模块与Arduino开发板之间的连接很简单。 首先将VCC引脚连接到Arduino的5V输出,然后将GND引脚连接到地。


现在我们只剩下用于 I2C 通信的引脚。 请注意,每个Arduino开发板都有不同的I2C引脚,必须正确连接。 在Arduino UNO R3开发板上,SDA和SCL位于靠近AREF引脚的排针上。 它们也称为 A5 (SCL) 和 A4 (SDA)。

Wiring-MPU6050-Accel-Gyro-Module-with-Arduino.png


安装库

设置MPU6050 块以开始捕获设备的原始数据输出非常简单。 另一方面,将数据处理成有意义的东西更困难,但我们可以使用一些库。


要安装库,请导航到 Sketch > Include Library > Manage Libraries…等待库管理器下载库索引并更新已安装库的列表。

Manage-Libraries.png


输入“mpu6050”筛选搜索结果。 查找Adafruit提供的Adafruit MPU6050库。 单击该条目,然后选择安装。

Adafruit-MPU6050-Library-Installation.png


Adafruit MPU6050库在内部使用Adafruit Unified Sensor DriverAdafruit Bus IO Library库。 因此,在库管理器中搜索Adafruit Unified Sensor和 BusIO并安装它们。


Arduino示例代码

以下是一个简单的程序,它从MPU6050模块读取线性加速度、角旋转和温度,并将它们打印在串口监视器上。

  1. #include <Adafruit_MPU6050.h>
  2. #include <Adafruit_Sensor.h>
  3. #include <Wire.h>

  4. Adafruit_MPU6050 mpu;

  5. void setup(void) {
  6.         Serial.begin(115200);

  7.         // Try to initialize!
  8.         if (!mpu.begin()) {
  9.                 Serial.println("Failed to find MPU6050 chip");
  10.                 while (1) {
  11.                   delay(10);
  12.                 }
  13.         }
  14.         Serial.println("MPU6050 Found!");

  15.         // set accelerometer range to +-8G
  16.         mpu.setAccelerometerRange(MPU6050_RANGE_8_G);

  17.         // set gyro range to +- 500 deg/s
  18.         mpu.setGyroRange(MPU6050_RANGE_500_DEG);

  19.         // set filter bandwidth to 21 Hz
  20.         mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);

  21.         delay(100);
  22. }

  23. void loop() {
  24.         /* Get new sensor events with the readings */
  25.         sensors_event_t a, g, temp;
  26.         mpu.getEvent(&a, &g, &temp);

  27.         /* Print out the values */
  28.         Serial.print("Acceleration X: ");
  29.         Serial.print(a.acceleration.x);
  30.         Serial.print(", Y: ");
  31.         Serial.print(a.acceleration.y);
  32.         Serial.print(", Z: ");
  33.         Serial.print(a.acceleration.z);
  34.         Serial.println(" m/s^2");

  35.         Serial.print("Rotation X: ");
  36.         Serial.print(g.gyro.x);
  37.         Serial.print(", Y: ");
  38.         Serial.print(g.gyro.y);
  39.         Serial.print(", Z: ");
  40.         Serial.print(g.gyro.z);
  41.         Serial.println(" rad/s");

  42.         Serial.print("Temperature: ");
  43.         Serial.print(temp.temperature);
  44.         Serial.println(" degC");

  45.         Serial.println("");
  46.         delay(500);
  47. }
复制代码

确保在串口监视器中将波特率设置为115200。 因为MPU6050返回了过多的数据,所以需要更高的速度来显示它。


会显示很多信息,比如线加速度、角旋转、温度等。 四处移动传感器并观察数据如何变化。

MPU6050-Arduino-Code-Acceleration-Gyro-Temperature-Output.png


代码说明

在草图的开头,包括了所有必要的库。 如前所述,Adafruit_MPU6050库实现了MPU6050的硬件功能,而Adafruit_Sensor库实现了统一的传感器抽象层。 还包括允许我们与I2C设备通信的 Wire.h。

  1. #include <Adafruit_MPU6050.h>
  2. #include <Adafruit_Sensor.h>
  3. #include <Wire.h>
复制代码

接下来,创建 Adafruit_MPU6050 类的实例以访问其相关方法。

  1. Adafruit_MPU6050 mpu;
复制代码

在setup()函数中,我们首先初始化与PC的串口通信,并调用begin()函数。 begin() 函数初始化I2C接口并验证芯片ID是否正确。 然后软复位芯片并等待传感器在唤醒后进行校准。

  1. Serial.begin(115200);

  2. // Try to initialize!
  3. if (!mpu.begin()) {
  4.         Serial.println("Failed to find MPU6050 chip");
  5.         while (1) {
  6.           delay(10);
  7.         }
  8. }
复制代码

然后使用以下三个函数来配置MPU6050的测量范围。

setAccelerometerRange()函数设置加速度计测量范围。 此函数接受以下值:

●    MPU6050_RANGE_2_G – ±2g 范围(默认)

●    MPU6050_RANGE_4_G – ±4g 量程

●    MPU6050_RANGE_8_G – ±8g 量程

●    MPU6050_RANGE_16_G – ±16g 量程

请记住,范围越小,加速度计读数就越敏感。


setGyroRange() 函数设置陀螺仪测量范围。 此函数接受以下值:

●    MPU6050_RANGE_250_DEG – 每秒 250 度的范围(默认)

●    MPU6050_RANGE_500_DEG – 每秒 500 度的范围

●    MPU6050_RANGE_1000_DEG – 每秒 1000 度的范围

●    MPU6050_RANGE_2000_DEG – 每秒 2000 度的范围

请记住,较小的每秒度数范围会导致更灵敏的输出。


setFilterBandwidth() 函数设置数字低通滤波器的带宽。 此函数接受以下值:

●    MPU6050_BAND_260_HZ – 用于 260 Hz 带宽(根据文档,这会禁用滤波器)

●    MPU6050_BAND_184_HZ – 用于 184 Hz 带宽

●    MPU6050_BAND_94_HZ – 用于 94 Hz 带宽

●    MPU6050_BAND_44_HZ – 用于 44 Hz 带宽

●    MPU6050_BAND_21_HZ – 用于 21 Hz 带宽

●    MPU6050_BAND_10_HZ – 用于 10 Hz 带宽

●    MPU6050_BAND_5_HZ – 用于 5 Hz 带宽

带宽选择允许您改变低通滤波器的截止频率,允许您通过去除高频噪声来平滑信号。


在此示例中,我们将加速度计范围设置为±8G,将陀螺仪范围设置为±500°/s,并将滤波器带宽设置为21Hz。

  1. mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  2. mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  3. mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
复制代码

在loop()函数中,我们创建了三个类型为 sensors_event_t 的对象来保存我们的结果。 sensors_event_t只是一种用户定义的数据类型,用于存储各种传感器数据,例如加速度、陀螺仪、温度、光、压力等。

  1. sensors_event_t a, g, temp;
复制代码

然后调用函数 getEvent()。 此函数从传感器读取一组新值,将它们转换为正确的SI单位和比例,然后将结果分配给我们的mpu对象。

  1. mpu.getEvent(&a, &g, &temp);
复制代码

最后,在串口监视器上显示这些值。

  1. Serial.print("Acceleration X: ");
  2. Serial.print(a.acceleration.x);
  3. Serial.print(", Y: ");
  4. Serial.print(a.acceleration.y);
  5. Serial.print(", Z: ");
  6. Serial.print(a.acceleration.z);
  7. Serial.println(" m/s^2");

  8. Serial.print("Rotation X: ");
  9. Serial.print(g.gyro.x);
  10. Serial.print(", Y: ");
  11. Serial.print(g.gyro.y);
  12. Serial.print(", Z: ");
  13. Serial.print(g.gyro.z);
  14. Serial.println(" rad/s");

  15. Serial.print("Temperature: ");
  16. Serial.print(temp.temperature);
  17. Serial.println(" degC");
复制代码

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 700 | 回复: 1480



手机版|

GMT+8, 2024-4-20 09:20 , Processed in 0.141099 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表