概述
MPU6050是一款六轴(三轴加速度+三轴角速度(陀螺仪))传感器,该传感器广泛用于四轴、平衡车和空中鼠标等设计,具有非常广泛的应用范围。但在实践中,如制作平衡车,四旋翼时,我们需要得到横滚角(roll ),俯仰角(yaw )和偏航角(pitch)等姿态信息。但是,使用MPU6050时从中只能得到各方向的加速度和角速度,并不能直接得到角度信息。就得利用我们的原始数据,进行姿态融合解算如卡尔曼滤波算法,这个比较复杂,知识点比较多,初学者不易掌握。而 MPU6050 自带了数字运动处理器,即 DMP( Digital Motion Processor),并且,InvenSense提供了一个 MPU6050 的嵌入式运动驱动库,结合 MPU6050 的 DMP,可以将我们的原始数据直接转换成四元数输出。而得到四元数之后,就可以很方便的计算出欧拉角,从而得到 yaw、roll 和 pitch。使用MPU6050内置的 DMP,大大简化了四轴和平衡车的代码设计,且 MCU 不用进行姿态解算过程,可以减少软件的开发周期,大大降低了 MCU 的负担,从而有更多的时间去处理其他事件,提高系统实时性。
本文是基于恩智浦的MCU,RT1064,使用逐飞RT1064开源库,对InvenSense 提供的 MPU6050 运动驱动库进行移植,其中还借鉴了正点原子STM32的MPU6050例程。经过这次移植,我得出学会了一种芯片的DMP移植就可以一以贯之地将DMP方便地移植到其他芯片上去。从而使DMP硬件解算的方法成为MPU6050姿态解算除了软件解算外的另一种选择。
准备阶段
- 关于MPU6050,因为对实际的应用不甚了解,我之前搜集了大量关于MPU6050的信息。然而一旦有了实际需要,相信大家都会有的放矢地去了解有效的信息。关于MPU6050的信息网上有很多,在这里不再赘述,本文假设读者基本掌握对MPU6050的使用。
- 芯片使用RT1064,使用逐飞的开源库。更改前后的工程代码将附于资源处方便比较。
- MPU6050一块,杜邦线四根。
- InvenSense的运动解算库,我又借鉴了STM32对于四元数合成姿态角的函数。
移植过程
- 上面就是运动解算库的六个文件,我们需要将他添加进自己的工程文件路径中
- 并将inv_mpu.c和inv_mpu_dmp_motion_driver.c添加进工程,如图
- 运动解算库是根据msp430来编写的,我们需要更改库中的几个函数,这几个函数主要是和iic的读取和延时有关的,如图
- 上面就是添加进工程的两个文件中需要改动的地方,其中使用宏定义的方式进行了函数的替换,比如使用i2c_write函数的地方实际上是使用了mpu_write_regs.
- i2c_write,i2c_read,delay_ms,get_ms处的宏定义都需要替换成自己使用的i2c库函数还有延时函数库中对应的函数,其中mpu_write_regs和mpu_read_regs是因为库函数中没有对应的函数,我自己对库函数进行改造而成的函数,大家在移植的过程中要注意不一定能找到合适的函数来替代,这时候就需要对已有的库函数进行改造。
- 上面就是我对库函数改造而成的函数,要注意找替代函数的时候要看define上面的注释,上面标明了函数的参数和顺序,如果发现库函数没有合适的,那就需要自己来改了。
- 改完之后就可以进行编译,然而事情并没有那么顺利,肯定会报一堆错误,不过这些都是小错误,大家只需要按照编译器给出的提示来改就可以了,最重要的还是我刚刚提到的函数的替换
- 最后别忘了在main.c中包含运动解算库的头文件
-
#include "inv_mpu.h" #include "inv_mpu_dmp_motion_driver.h"
这样我们的运动解算库就算移植好了,接下来进入使用阶段
使用解算库得到姿态角实验
贴出main的代码,删去了一些和mpu无关的东西,并可以将角度显示在屏幕上
/*********************************************************************************************************************
* COPYRIGHT NOTICE
* Copyright (c) 2019,逐飞科技
* All rights reserved.
* 技术讨论QQ群:一群:179029047(已满) 二群:244861897
*
* 以下所有内容版权均属逐飞科技所有,未经允许不得用于商业用途,
* 欢迎各位使用并传播本程序,修改内容时必须保留逐飞科技的版权声明。
*
* @file main
* @company 成都逐飞科技有限公司
* @author 逐飞科技(QQ3184284598)
* @version 查看doc内version文件 版本说明
* @Software IAR 8.3 or MDK 5.24
* @Target core NXP RT1064DVL6A
* @Taobao https://seekfree.taobao.com/
* @date 2019-04-30
********************************************************************************************************************/
//整套推荐IO查看Projecct文件夹下的TXT文本
//打开新的工程或者工程移动了位置务必执行以下操作
//第一步 关闭上面所有打开的文件
//第二步 project clean 等待下方进度条走完
#include "SEEKFREE_FONT.h"
#include "headfile.h"
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"
float pitch,roll,yaw; //?·à-??
short aacx,aacy,aacz; //?ó?ù?è′??D?÷?-ê?êy?Y
short gyrox,gyroy,gyroz;
uint32 t;
short temp;
int main(void)
{
DisableGlobalIRQ();
board_init(); //务必保留,本函数用于初始化MPU 时钟 调试串口
systick_delay_ms(100); //延时100ms,等待主板其他外设上电成功
lcd_init();
lcd_clear(WHITE);
simiic_init();
//引脚链接查看SEEKFREE_IIC h文件的引脚定义
mpu6050_init();
lcd_showstr(0,0,"test");
EnableGlobalIRQ(0);
while(mpu_dmp_init())
{
lcd_showstr(0,1,"error");
systick_delay_ms(200);
lcd_showstr(0,1," ");
systick_delay_ms(200);
}
lcd_showstr(0,1,"Pitch");
lcd_showstr(0,2,"Roll");
lcd_showstr(0,3,"Yaw");
while(1)
{
if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0)
{
if((t%10)==0)
{
temp=pitch*10;
lcd_showint8(40,1,temp/10);
temp=roll*10;
lcd_showint8(40,2,temp/10);
temp=yaw*10;
lcd_showint8(40,3,temp/10);
}
t++;
}
}
}
要注意上面的mpu_dmp_init()初始化函数要不停地检测,因为刚开始上电时dmp需要初始化一段时间,这时候有可能读不出来会报错,但不要担心,等一秒基本就恢复成正常了
总结
虽然只是rt1064上mpu6050运动解算库的移植,但是熟悉了这套过程后大家在其他MCU上移植dmp也不再话下,我认为多去尝试新技术是十分有必要的。dmp输出有200Hz,已经可以满足大部分需求,但是据说采样频率还是不够快,如果是做竞速平衡车的话会影响速度上限。文章有不足之处,还请多交流。