打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
四旋翼飞行器之——MPU6050 六轴姿态传感器 | 轩辕

MPU-6000(6050)为全球首例整合性6轴运动处理组件,相较于多组件方案,免除了组合陀螺仪与加速器时之轴间差的问题,减少了大量的包装空间。MPU-6000(6050)整合了3轴陀螺仪、3轴加速器,并含可藉由第二个I2C端口连接其他厂牌之加速器、磁力传感器、或其他传感器的数位运动处理(DMP: Digital Motion Processor)硬件加速引擎,由主要I2C端口以单一数据流的形式,向应用端输出完整的9轴融合演算技术。

InvenSense的运动处理资料库,可处理运动感测的复杂数据,降低了运动处理运算对操作系统的负荷,并为应用开发提供架构化的API。

MPU-6000(6050)的角速度全格感测范围为±250、±500、±1000与±2000°/sec (dps),可准确追緃快速与慢速动作,并且,用户可程式控制的加速器全格感测范围为±2g、±4g±8g与±16g。产品传输可透过最高至400kHz的IC或最高达20MHz的SPI(MPU-6050没有SPI)。

以上摘自百度百科

芯片本身体积较小,规格为4*4*0.9mm,与Arduino板子连接,使用I2C端口。我使用的是Arduino senser 扩展板, 上面自带有SCL和SDA接口。如果没有扩展板的,可以将A4接SDA,A5接SCL。详见arduino学习笔记37 – Arduino Uno + MPU6050首例整合性6轴演示实验

连接好电路就可以烧代码进去了

1#include "Wire.h"
2 
3// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
4// for both classes must be in the include path of your project
5#include "I2Cdev.h"
6#include "MPU6050.h"
7 
8// class default I2C address is 0x68
9// specific I2C addresses may be passed as a parameter here
10// AD0 low = 0x68 (default for InvenSense evaluation board)
11// AD0 high = 0x69
12MPU6050 accelgyro;
13 
14int16_t ax, ay, az;
15int16_t gx, gy, gz;
16 
17#define LED_PIN 13
18bool blinkState = false;
19 
20void setup() {
21    // join I2C bus (I2Cdev library doesn't do this automatically)
22    Wire.begin();
23 
24    // initialize serial communication
25    // (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
26    // it's really up to you depending on your project)
27    Serial.begin(38400);
28 
29    // initialize device
30    Serial.println("Initializing I2C devices...");
31    accelgyro.initialize();
32 
33    // verify connection
34    Serial.println("Testing device connections...");
35    Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
36 
37    // configure Arduino LED for
38    pinMode(LED_PIN, OUTPUT);
39}
40 
41void loop() {
42    // read raw accel/gyro measurements from device
43    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
44 
45    // these methods (and a few others) are also available
46    //accelgyro.getAcceleration(&ax, &ay, &az);
47    //accelgyro.getRotation(&gx, &gy, &gz);
48 
49    // display tab-separated accel/gyro x/y/z values
50    Serial.print("a/g:\t");
51    Serial.print(ax/16384.0); Serial.print("\t");
52    Serial.print(ay/16384.0); Serial.print("\t");
53    Serial.print(az/16384.0); Serial.print("\t");
54    Serial.print(gx/131.0); Serial.print("\t");
55    Serial.print(gy/131.0); Serial.print("\t");
56    Serial.println(gz/131.0);
57 
58    // blink LED to indicate activity
59    blinkState = !blinkState;
60    digitalWrite(LED_PIN, blinkState);
61}

上面ax,ay,az 除以一个浮点数16384并且gx,gy,gz除以了131. 在MPU寄存器中每个分量加速度和角速度都是用16bits来储存,也就是存储范围可以达0~65535。上面提到MPU提供了几个不同的精度标准:MPU-6000(6050)的角速度全格感测范围为±250、±500、±1000与±2000°/sec (dps),可准确追緃快速与慢速动作,并且,用户可程式控制的加速器全格感测范围为±2g、±4g、±8g与±16g。并且默认情况下,MPU的initialize 函数是这样的:

1void MPU6050::initialize()
2{
3    setClockSource(MPU6050_CLOCK_PLL_XGYRO);
4    setFullScaleGyroRange(MPU6050_GYRO_FS_250);
5    setFullScaleAccelRange(MPU6050_ACCEL_FS_2);
6    setSleepEnabled(false); // thanks to Jack Elston for pointing this one out!
7}

所以可见加速度默认的range是±2g,角速度默认的range是±250°/sec (dps)。那么用16位来覆盖这样的range,就用65536分别除以4和500,就得到上述的两个数字了。

这样就得到了传感器的输出结果

1a/g:    0.01    0.01    1.06    4.77    -0.62   -6.92
2a/g:    0.02    0.00    1.07    5.05    -0.50   -6.66
3a/g:    0.01    0.01    1.07    5.04    -0.46   -6.53
4a/g:    0.01    0.01    1.07    4.81    -0.55   -6.39
5a/g:    0.01    0.01    1.07    4.96    -0.53   -6.37
6a/g:    0.01    0.01    1.07    4.93    -0.65   -6.21
7a/g:    0.01    0.00    1.06    4.94    -0.66   -6.18
8a/g:    0.01    0.01    1.06    4.91    -0.55   -6.13
9a/g:    0.01    0.01    1.07    4.89    -0.52   -6.16
10a/g:    0.02    0.01    1.07    5.11    -0.56   -6.16
11a/g:    0.02    0.01    1.06    4.99    -0.66   -6.09
12a/g:    0.01    0.02    1.07    4.99    -0.60   -6.08
13a/g:    0.01    0.01    1.06    4.76    -0.55   -6.12
14a/g:    0.01    0.00    1.07    5.12    -0.63   -6.14
15a/g:    0.01    0.00    1.07    4.93    -0.44   -6.44
16a/g:    0.01    0.01    1.07    4.93    -0.37   -6.39
17a/g:    0.02    0.01    1.06    4.85    -0.60   -6.40
18a/g:    0.02    0.01    1.07    4.73    -0.44   -6.61
19a/g:    0.02    0.01    1.07    5.08    -0.63   -6.42
20a/g:    0.01    0.01    1.07    4.69    -0.49   -6.65
21a/g:    0.02    0.01    1.05    5.01    -0.66   -6.67
22a/g:    0.01    0.01    1.07    5.04    -0.57   -6.76
23a/g:    0.02    0.01    1.07    4.71    -0.66   -6.69
24a/g:    0.02    0.01    1.07    4.94    -0.54   -6.81
25a/g:    0.01    0.01    1.07    5.08    -0.63   -6.71
26a/g:    0.01    0.01    1.06    4.92    -0.63   -6.69
27a/g:    0.01    0.00    1.06    4.87    -0.66   -6.69
28a/g:    0.01    0.01    1.07    4.80    -0.60   -6.49

这个状态是水平放置的结果,前三列代码代表加速度,后三列表示角速度,分别都是x,y,z的顺序。加速度好理解前两个接近于0,后一列接近于1代表1g。z轴受到地面一个mg大小的反作用力,所以有一个大小为g的加速度。至于后面三个不等零的数字,我之前一直想不通,直到后来采集了大量数据放到matlab观测得到,无聊传感器以任何角度静止摆放,这个几个数字基本不动,所以基本确定下来这个几个数字是偏移量,只要用一个常数将他校准就可以了。

这个图是我通过matlab画出的观测到的数据,总共有三千多组数据,其中三个短的线是加速度,分别为以三种不同角度摆放的加速度测量结果,又粗又大的是角速度偏移量,另一个细线是噪音,在这里将次忽略。画这个图的目的就是为了说明一个问题:无论传感器怎么摆放,在静止状态下的输出数据都是一个固定的点(会有波动),我们将此大量数据取平均,再在计算的时候将其减去,就可以达到矫正的效果了。

以上是x,y,z 轴矫正后的误差分布图,都控制在了1以内。代码插入时,就在刚读取出角速度时候矫正就行:

1accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
2//reset gx gy gz
3gx = gx - 630;
4gy = gy + 62;
5gz = gz + 862;

以上是我测得的偏移量,不过对于每一个不同的传感器的偏移量应该都不一样,但是矫正的方法是一至的。
另外,目前对于加速度的教程的必要性还不明确,有待进一步探讨。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
MPU6050数据采集及其意义和滤波(一阶互补滤波、二阶互补滤波、卡尔曼滤波)
mpu6050姿态融合原理及程序代码
关于MPU6050 校准问题请教
mpu-6050 加速度、陀螺仪传感器的调试
唐诗精选(138首)
“陀螺仪”和“加速度计”工作原理
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服