Arduino教程:MPU6050的数据获取、分析与处理

摘要

MPU6050是一种非常流行的空间运动传感器芯片,可以获取器件当前的三个加速度分量和三个旋转角速度。由于其体积小巧,功能强大,精度较高,不仅被广泛应用于工业,同时也是航模爱好者的神器,被安装在各类飞行器上驰骋蓝天。

随着Arduino开发板的普及,许多朋友希望能够自己制作基于MPU6050的控制系统,但由于缺乏专业知识而难以上手。此外,MPU6050的数据是有较大噪音的,若不进行滤波会对整个控制系统的精准确带来严重影响。

MPU6050芯片内自带了一个数据处理子模块DMP,已经内置了滤波算法,在许多应用中使用DMP输出的数据已经能够很好的满足要求。关于如何获取DMP的输出数据,我将在以后的文章中介绍。本文将直接面对原始测量数据,从连线、芯片通信开始一步一步教你如何利用Arduino获取MPU6050的数据并进行卡尔曼滤波,最终获得稳定的系统运动状态。

一、Arduino与MPU-6050的通信

为避免纠缠于电路细节,我们直接使用集成的MPU6050模块。MPU6050的数据接口用的是I2C总线协议,因此我们需要Wire程序库的帮助来实现Arduino与MPU6050之间的通信。请先确认你的Arduino编程环境中已安装Wire库。

Wire库的官方文档(http://www.arduino.cc/en/Reference/Wire
)中指出:在UNO板子上,SDA接口对应的是A4引脚,SCL对应的是A5引脚。MPU6050需要5V的电源,可由UNO板直接供电。按照下图连线。

ba2110a496c04f3b99b751a9b226db6f.png

(紫色线是中断线,这里用不到,可以不接) 

MPU6050的数据写入和读出均通过其芯片内部的寄存器实现,这些寄存器的地址都是1个字节,也就是8位的寻址空间,其寄存器的详细列表说明书请点击下载:https://www.olimex.com/Products/Modules/Sensors/MOD-MPU6050/resources/RM-MPU-60xxA_rev_4.pdf

1.1 将数据写入MPU-6050

在每次向器件写入数据前要先打开Wire的传输模式,并指定器件的总线地址,MPU6050的总线地址是0x68(AD0引脚为高电平时地址为0x69)。然后写入一个字节的寄存器起始地址,再写入任意长度的数据。这些数据将被连续地写入到指定的起始地址中,超过当前寄存器长度的将写入到后面地址的寄存器中。写入完成后关闭Wire的传输模式。下面的示例代码是向MPU6050的0x6B寄存器写入一个字节0。

Wire.beginTransmission(0x68); //开启MPU6050的传输
Wire.write(0x6B); //指定寄存器地址
Wire.write(0); //写入一个字节的数据
Wire.endTransmission(true); //结束传输,true表示释放总线

1.2 从MPU-6050读出数据

读出和写入一样,要先打开Wire的传输模式,然后写一个字节的寄存器起始地址。接下来将指定地址的数据读到Wire库的缓存中,并关闭传输模式。最后从缓存中读取数据。下面的示例代码是从MPU6050的0x3B寄存器开始读取2个字节的数据:

Wire.beginTransmission(0x68); //开启MPU6050的传输
Wire.write(0x3B); //指定寄存器地址
Wire.requestFrom(0x68, 2, true); //将输据读出到缓存
Wire.endTransmission(true); //关闭传输模式
int val = Wire.read() << 8 | Wire.read(); //两个字节组成一个16位整数

1.3 具体实现 

通常应当在setup函数中对Wire库进行初始化:

Wire.begin(); 

在对MPU6050进行各项操作前,必须启动该器件,向它的0x6B写入一个字节0即可启动。通常也是在setup函数完成,代码见1.1节。 

二、 MPU6050的数据格式

我们感兴趣的数据位于0x3B到0x48这14个字节的寄存器中。这些数据会被动态更新,更新频率最高可达1000HZ。下面列出相关寄存器的地址,数据的名称。注意,每个数据都是2个字节。

0x3B,加速度计的X轴分量ACC_X
0x3D,加速度计的Y轴分量ACC_Y
0x3F,加速度计的Z轴分量ACC_Z
0x41,当前温度TEMP
0x43,绕X轴旋转的角速度GYR_X
0x45,绕Y轴旋转的角速度GYR_Y
0x47,绕Z轴旋转的角速度GYR_Z 
MPU6050芯片的座标系是这样定义的:令芯片表面朝向自己,将其表面文字转至正确角度,此时,以芯片内部中心为原点,水平向右的为X轴,竖直向上的为Y轴,指向自己的为Z轴。见下图:

 

 

2a1d889625b44cf1b217a83055f9ab76.png

 

我们只关心加速度计和角速度计数据的含义,下面分别介绍。 

加速度计的三轴分量ACC_X、ACC_Y和ACC_Z均为16位有符号整数,分别表示器件在三个轴向上的加速度,取负值时加速度沿座标轴负向,取正值时沿正向。

三个加速度分量均以重力加速度g的倍数为单位,能够表示的加速度范围,即倍率可以统一设定,有4个可选倍率:2g、4g、8g、16g。以ACC_X为例,若倍率设定为2g(默认),则意味着ACC_X取最小值-32768时,当前加速度为沿X轴正方向2倍的重力加速度;若设定为4g,取-32768时表示沿X轴正方向4倍的重力加速度,以此类推。显然,倍率越低精度越好,倍率越高表示的范围越大,这要根据具体的应用来设定。

我们用f表示倍率,f=0为2g,f=3为16g,设定加速度倍率的代码如下:

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表示释放总线

再以ACC_X为例,若当前设定的加速度倍率为4g,那么将ACC_X读数换算为加速度的公式为:


ax=4g×ACC\_X/32768
,g可取当地重力加速度。

2.2 角速度计

绕X、Y和Z三个座标轴旋转的角速度分量GYR_X、GYR_Y和GYR_Z均为16位有符号整数。从原点向旋转轴方向看去,取正值时为顺时针旋转,取负值时为逆时针旋转。

三个角速度分量均以“度/秒”为单位,能够表示的角速度范围,即倍率可统一设定,有4个可选倍率:250度/秒、500度/秒、1000度/秒、2000度/秒。以GYR_X为例,若倍率设定为250度/秒,则意味着GYR取正最大值32768时,当前角速度为顺时针250度/秒;若设定为500度/秒,取32768时表示当前角速度为顺时针500度/秒。显然,倍率越低精度越好,倍率越高表示的范围越大。

我们用f表示倍率,f=0为250度/秒,f=3为2000度/秒,除角速度倍率寄存器的地址为0x1B之外,设定加速度倍率的代码与2.1节代码一致。

以GYR_X为例,若当前设定的角速度倍率为1000度/秒,那么将GRY_X读数换算为角速度(顺时针)的公式为:
gx=1000×GYR\_X/32768。

三、运动数据

在读取加速度计和角速度计的数据并换算为物理值后,根据不同的应用,数据有不同的解译方式。本章将以飞行器运动模型为例,根据加速度和角速度来算出当前的飞行姿态。

3.1 加速度计模型

我们可以把加速度计想象为一个正立方体盒子里放着一个球,这个球被弹簧固定在立方体的中心。当盒子运动时,根据假想球的位置即可算出当前加速度的值。想象如果在太空中,盒子没有任何受力时,假想球将处于正中心的位置,三个轴的加速度均为0。见下图:3531d201138042ada0f76ca6596ae080.png

如果我们给盒子施加一个水平向左的力,那么显然盒子就会有一个向左的加速度,此时盒内的假想球会因为惯性作用贴向盒内的右侧面。如下图所示:

a25f3b59f66e49a7a9ae489625988e87.png 

为了保证数据的物理意义,MPU6050的加速度计是以假想球在三轴上座标值的相反数作为三个轴的加速度值。当假想球的位置偏向一个轴的正向时,该轴的加速度读数为负值,当假想球的位置偏向一个轴的负向时,该轴的加速度读数为正值。
根据以上分析,当我们把MPU6050芯片水平放于地方,芯片表面朝向天空,此时由于受到地球重力的作用, 假想球的位置偏向Z轴的负向,因此Z轴的加速度读数应为正,且在理想情况下应为g。注意,此加速度的物理意义并不是重力加速度,而是自身运动的加速度,可以这样理解:正因为其自身运动的加速度与重力加速度大小相等方向相反,芯片才能保持静止。

3.2 Roll-pitch-yaw模型与姿态计算

表示飞行器当前飞行姿态的一个通用模型就是建立下图所示坐标系,并用Roll表示绕X轴的旋转,Pitch表示绕Y轴的旋转,Yaw表示绕Z轴的旋转。

209fc74c9d3b4c5e8a42f592bc57d931.png 

 由于MPU6050可以获取三个轴向上的加速度,而地球重力则是长期存在且永远竖直向下,因此我们可以根据重力加速度相对于芯片的指向为参考算得当前姿态。
为方便起见,我们让芯片正面朝下固定在上图飞机上,且座标系与飞机的坐标系完全重合,以三个轴向上的加速度为分量,可构成加速度向量
a(x,y,z)。假设当前芯片处于匀速直线运动状态,那么a应垂直于地面上向,即指向Z轴负方向,模长为
2bc54c1910774fca844f8ec59cb73c55.png

 

 

 

  • 37
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值