小伙伴们大家好,好久不更新RT-Thread实战笔记啦,今天来搞一搞MPU6050,话不多说,淦!

本章源码获取

欢迎文末留言区或者公众号后台回复“MPU6050”即可获取本教程源码

MPU6050简介

某宝买的,吃灰许久了...

有钱,不想受那鸟气的,看这个,自己画一个,对比价格,我劝你买个吧,知道自己行就行了...

典型用法:

可在官网下载最新的芯片手册和寄存器映射和描述,参看:MPU6050 官网

基本功能:

MPU-60X0是世界上第一款集成 6 轴MotionTracking设备。它集成了3轴MEMS陀螺仪,3轴MEMS加速度计,以及一个可扩展的数字运动处理器 DMP( DigitalMotion Processor),可用I2C接口连接一个第三方的数字传感器,比如磁力计。扩展之后就可以通过其 I2C或SPI接口输出一个9轴的信号( SPI接口仅在MPU-6000可用)。 MPU-60X0也可以通过其I2C接口连接非惯性的数字传感器,比如压力传感器。

MPU-60X0对陀螺仪和加速度计分别用了三个16位的ADC,将其测量的模拟量转化为可输出的数字量。为了精确跟踪快速和慢速的运动,传感器的测量范围都是用户可控的,陀螺仪可测范围为±250, ±500, ±1000, ±2000°/秒( dps),加速度计可测范围为±2, ±4,±8, ±16g。

一个片上1024字节的FIFO,有助于降低系统功耗。和所有设备寄存器之间的通信采用 400kHz的 I2C接口或 1MHz的 SPI接口( SPI仅MPU-6000可用)。 对于需要高速传输的应用, 对寄存器的读取和中断可用 20MHz的SPI。另外,片上还内嵌了一个温度传感器和在工作环境下仅有±1%变动的振荡器。芯片尺寸4×4×0.9mm,采用QFN封装(无引线方形封装),可承受最大 10000g的冲击,并有可编程的低通滤波器。

关于电源, MPU-60X0可支持 VDD范围 2.5V±5%, 3.0V±5%,或 3.3V±5%。另外MPU-6050还有一个 VLOGIC引脚,用来为 I2C输出提供逻辑电平。 VLOGIC电压可取1.8±5%或者VDD。

系统结构图:

通信接口:

MPU-60X0使用 SPI(仅MPU-6000)或 I2C 串行通信至系统处理器接口。 与系统处理器通信时,MPU-60X0始终充当从属设备。 LSB的 I2C 从地址的地址由引脚9(AD0)设置(一般接地),本次采用的是IIC的通讯方式,顺便学习一下rt-thread的IIC设备驱动。

六轴,代表的是它内置了一个三轴 MEMS 陀螺仪、一个三轴 MEMS 加速度计,一个数字运动处理引擎(DMP)。它还有用于第三方的数字传感器接口的辅助 I2C 串行接口,比如当辅助 I2C 串行接口连接到一个三轴磁力计,MPU6050 能提供一个完整的九轴融合输出到其主 I2C 端口。

下图标明了传感器的参考坐标系( XYZ组成右手系)以及 3个测量轴和旋转方向。

旋转的正向可用右手螺旋定则判断

数字运动处理器(DMP):

DMP就是MPU6050内部的运动引擎,全称Digital Motion Processor,直接输出四元数,可以减轻外围微处理器的工作负担且避免了繁琐的滤波和数据融合。Motion Driver是Invensense针对其运动传感器的软件包,并非全部开源,核心的算法部分是针对ARM处理器和MSP430处理器编译成了静态链接库,适用于MPU6050、MPU6500、MPU9150、MPU9250等传感器。

FIFO

MPU-60X0包含一个可通过串行接口访问的1024字节FIFO寄存器。 FIFO配置寄存器决定哪个数据写入FIFO。 可能的选择包括陀螺仪数据,加速计数据,温度读数,辅助传感器读数和 FSYNC 输入。 FIFO 计数器跟踪 FIFO 中包含的有效数据字节数。 FIFO寄存器支持突发读取。 中断功能可用于确定新数据何时可用。

MPU6050的涉及的东西还是很多的,小飞哥也只是简单了解了一些,小伙伴们可以查看手册或者百度,很多优秀的介绍,就不再啰嗦啦

rt-thread软件包使用

硬件连接

小飞哥使用的是ART-PI及ART-PI扩展板(12月份即将开源发布)

使用到的引脚为:

MCU MPU6050
3.3V VCC
GND GND
PI2 SDA
PI1 SCL

小伙伴们可以还根据自己的MCU及使用到的引脚,模拟的IIC,自己看着选就可以啦

硬件连接OK

软件编写

介绍2两种方式,一种是使用rt-thread平台软件包获取MPU6050的数据,自己解算,另一种就是移植DMP库进行解算,小飞哥用的是移植的DMP库来解算的。

  • rtt软件包使用

选择MPU6050软件包

然后选择模拟IIC,可以使用IIC3,也可以使用其他的,和软件包选用的统一就OK了

设置完成之后,ctrl+S保存即可,软件包自动就下载添加进来了

接下来编写读取函数,直接调用已经封装好的接口即可

先注册设备,初始化

    i2c_bus = (struct mpu6xxx_device *)mpu6xxx_init(MPU6050_I2C_BUS_NAME, MPU6050_ADDR);   //初始化MPU6050,测量单位为角速度,加速度    while(count++)mpu6xxx_set_param(i2c_bus, MPU6XXX_ACCEL_RANGE, MPU6XXX_GYRO_RANGE_2000DPS);  //陀螺仪范围配置mpu6xxx_set_param(i2c_bus, MPU6XXX_ACCEL_RANGE, MPU6XXX_ACCEL_RANGE_2G);     //加速度计,一般设置为±2Gmpu6xxx_set_param(i2c_bus, MPU6XXX_SAMPLE_RATE, 50);                       //采样频率mpu6xxx_set_param(i2c_bus, MPU6XXX_DLPF_CONFIG, 25);                       //数字低通滤波器设置,一般为1/2采样率

然后调用接口:

      mpu6xxx_get_gyro(i2c_bus, &gyro);sprintf(str,"gyro.x=%d\r\n",gyro.x);rt_kprintf(str);sprintf(str,"gyro.y=%d\r\n",gyro.y);rt_kprintf(str);sprintf(str,"gyro.z=%d\r\n",gyro.z);rt_kprintf(str);mpu6xxx_get_accel(i2c_bus,&accel);sprintf(str,"accel.x=%d\r\n",accel.x);rt_kprintf(str);sprintf(str,"accel.y=%d\r\n",accel.y);rt_kprintf(str);sprintf(str,"accel.z=%d\r\n",accel.z);rt_kprintf(str);

运行结果:

来看一下,这两个函数的内部封装:

/*** This function gets the data of the gyroscope, unit: deg/10s* Here deg/10s means 10 times higher precision than deg/s. ** @param dev the pointer of device driver structure* @param gyro the pointer of 3axes structure for receive data** @return the reading status, RT_EOK reprensents  reading the data successfully.*/
rt_err_t mpu6xxx_get_gyro(struct mpu6xxx_device *dev, struct mpu6xxx_3axes *gyro)
{struct mpu6xxx_3axes tmp;rt_uint16_t sen;rt_err_t res;res = mpu6xxx_get_gyro_raw(dev, &tmp);if (res != RT_EOK){return res;}sen = MPU6XXX_GYRO_SEN >> dev->config.gyro_range;gyro->x = (rt_int32_t)tmp.x * 100 / sen;gyro->y = (rt_int32_t)tmp.y * 100 / sen;gyro->z = (rt_int32_t)tmp.z * 100 / sen;return RT_EOK;
}
/*** This function gets the data of the accelerometer, unit: mg** @param dev the pointer of device driver structure* @param accel the pointer of 3axes structure for receive data** @return the reading status, RT_EOK reprensents  reading the data successfully.*/
rt_err_t mpu6xxx_get_accel(struct mpu6xxx_device *dev, struct mpu6xxx_3axes *accel)
{struct mpu6xxx_3axes tmp;rt_uint16_t sen;rt_err_t res;res = mpu6xxx_get_accel_raw(dev, &tmp);if (res != RT_EOK){return res;}sen = MPU6XXX_ACCEL_SEN >> dev->config.accel_range;accel->x = (rt_int32_t)tmp.x * 1000 / sen;accel->y = (rt_int32_t)tmp.y * 1000 / sen;accel->z = (rt_int32_t)tmp.z * 1000 / sen;return RT_EOK;
}

还有获取磁力计、温度的接口,就不再一一列举了,拿到的数据我们可以进行手动解算。

  • 移植DMP解算

使用DMP包的话跟rtt的MPU6050的软件包就没有很大关系了,只需要IIC接口就可以了

首先把DMP库文件放到我们的工程中,包含路径到我们的工程中

然后就需要编写与DMP库对接的接口了,下面几个是需要我们实现的

rt_uint8_t MPU_Write_Len(rt_uint8_t addr,rt_uint8_t reg,rt_uint8_t len,rt_uint8_t *databuf)
{rt_int8_t res = 0;
#ifdef RT_USING_I2Cstruct rt_i2c_msg msgs;rt_uint8_t buf[50] = {0};
#endifbuf[0] = reg;for(int i = 0;i<len;i++){buf[i+1]=databuf[i];}if (i2c_bus->bus->type == RT_Device_Class_I2CBUS){msgs.addr  = i2c_bus->i2c_addr;    /* slave address */msgs.flags = RT_I2C_WR;        /* write flag */msgs.buf   = buf;              /* Send data pointer */msgs.len   = len+1;if (rt_i2c_transfer((struct rt_i2c_bus_device *)i2c_bus->bus, &msgs, 1) == 1){res = RT_EOK;}else{res = -RT_ERROR;}}
}
rt_uint8_t MPU_Read_Len(rt_uint8_t addr,rt_uint8_t reg,rt_uint8_t len,rt_uint8_t *buf)
{rt_int8_t res = 0;
#ifdef RT_USING_I2Cstruct rt_i2c_msg msgs[2];
#endif
#ifdef RT_USING_SPIrt_uint8_t tmp;
#endifif (i2c_bus->bus->type == RT_Device_Class_I2CBUS){msgs[0].addr  = i2c_bus->i2c_addr;    /* Slave address */msgs[0].flags = RT_I2C_WR;        /* Write flag */msgs[0].buf   = &reg;             /* Slave register address */msgs[0].len   = 1;                /* Number of bytes sent */msgs[1].addr  = i2c_bus->i2c_addr;    /* Slave address */msgs[1].flags = RT_I2C_RD;        /* Read flag */msgs[1].buf   = buf;              /* Read data pointer */msgs[1].len   = len;              /* Number of bytes read */if (rt_i2c_transfer((struct rt_i2c_bus_device *)i2c_bus->bus, msgs, 2) == 2){res = RT_EOK;}else{res = -RT_ERROR;}}return res;
}

初始化部分我们改为下面这样,只注册IIC设备就行了,其他的配置在DMP中完成:

    i2c_bus = (struct mpu6xxx_device *)mpu6xxx_init(MPU6050_I2C_BUS_NAME, MPU6050_ADDR);   //初始化MPU6050,测量单位为角速度,加速度    while(count++)/*mpu6xxx_set_param(i2c_bus, MPU6XXX_ACCEL_RANGE, MPU6XXX_GYRO_RANGE_2000DPS);  //陀螺仪范围配置mpu6xxx_set_param(i2c_bus, MPU6XXX_ACCEL_RANGE, MPU6XXX_ACCEL_RANGE_2G);     //加速度计,一般设置为±2Gmpu6xxx_set_param(i2c_bus, MPU6XXX_SAMPLE_RATE, 50);                       //采样频率mpu6xxx_set_param(i2c_bus, MPU6XXX_DLPF_CONFIG, 25);                       //数字低通滤波器设置,一般为1/2采样率
*/while(mpu_dmp_init()){rt_thread_mdelay(500);rt_kprintf("\r\nMPU6050 Error\r\n");}rt_kprintf("\r\nMPU6050 OK\r\n");

DMP初始化成功

获取结算后的数据:

    float pitch,roll,yaw;           //欧拉角if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0){sprintf(str,"pitch=%.1f\r\n",pitch);rt_kprintf(str);sprintf(str,"roll=%.1f\r\n",roll);rt_kprintf(str);sprintf(str,"yaw=%.1f\r\n",yaw);rt_kprintf(str);/*temp=MPU_Get_Temperature();          //得到温度值sprintf(str,"temp=%.1f\r\n",temp);rt_kprintf(str);MPU_Get_Accelerometer(&aacx,&aacy,&aacz);   //得到加速度传感器数据MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz);    //得到陀螺仪数据
*/}

至此就结束了,使用库的解算是挺方便的,自己解算其中涉及的计算还是挺麻烦的,本章就不再介绍啦,欢迎做过的小伙伴投稿给我哦

资料获取

欢迎添加小飞哥好友,一起交流问题与经验,回复加群即可加入“高质量开发者”群

RT-Thread实战笔记|MPU6050使用详解及DMP姿态解算相关推荐

  1. STM32入门笔记(02):MPU6050、MPU9250、ICM20948及姿态解算(SPL库函数版)

    目录 MPU6050 什么是MPU6050? MPU6050的特点 MPU6050框图 MPU6050初始化 MPU6050寄存器 电源管理寄存器1(0X6B) 陀螺仪配置寄存器(0X1B) 加速度传 ...

  2. 【ESP32Arduino+MPU6050 dmp姿态解算】学习笔记 PlatformIO 复制即可使用

    0.引入 esp32,国产之光,拥有先进的网络功能和强大的双核处理器:mpu6050,经典的六轴陀螺仪,体积小价格低廉但是功能强大. 二者的优点相结合,可实现对机体高效的姿态测算以及以此进行远程控制. ...

  3. 学习四旋翼(三):DMP姿态解算和串级PID控制姿态

    暑假期间,对于四旋翼有一点兴趣,没有亲手做,但是看了一些资料.这个系列文章只是对自己看的东西的记录,对于想要学习了解相关知识的同学没有任何参考价值! 本篇是系列第三篇,介绍了我对于MPU9250 DM ...

  4. ESP-12F驱动MPU6050使用DMP库姿态解算

    一.准备工作 主芯片采用是安信可科技的ESF-12F模组(内置ESP8266芯片),使用GPIO模拟I2C驱动MPU6050,i2c驱动部分可直接参考官方例程中的i2c_master.c文件,(附件提 ...

  5. ELK学习笔记之Logstash详解

    0x00 Logstash概述 官方介绍:Logstash is an open source data collection engine with real-time pipelining cap ...

  6. expect学习笔记及实例详解【转】

    1. expect是基于tcl演变而来的,所以很多语法和tcl类似,基本的语法如下所示: 1.1 首行加上/usr/bin/expect 1.2 spawn: 后面加上需要执行的shell命令,比如说 ...

  7. Java中大数据数组,Java基础学习笔记之数组详解

    摘要:这篇Java开发技术栏目下的"Java基础学习笔记之数组详解",介绍的技术点是"java基础学习笔记.基础学习笔记.Java基础.数组详解.学习笔记.Java&qu ...

  8. OpenCV-Python实战(10)——详解 OpenCV 轮廓检测

    OpenCV-Python实战(10)--详解 OpenCV 轮廓检测 0. 前言 1. 轮廓介绍 2. 轮廓检测 3. 轮廓压缩 4. 图像矩 4. 1 一些基于矩的对象特征 4.2 Hu 不变矩 ...

  9. ext4数据恢复实战及文件系统结构详解

    ext4数据恢复实战及文件系统结构详解 一.前言 二.ext4数据恢复实战 三.ext4文件系统结构详解 四.ext4分区结构 五.ext4目录结构 六.目录项的删除特性 七.ext4文件结构 八.最 ...

最新文章

  1. java一天一次_做JAVA两年,月薪18k,这些自学心得你绝对值得借鉴
  2. 斯隆奖获得者李婧翌:AI+X并非总是有效,生物数据量小、噪音大,可解释性是关键...
  3. 数列分块入门3(查询前驱)
  4. Oracle 服务器 进程中的 LOCAL=NO 和 LOCAL=YES
  5. 198. House Robber
  6. cocos2d-x游戏开发(十四)用shader使图片背景透明
  7. (Python+Tensorflow)编程踩坑集锦
  8. CLR via C# 3 读书笔记(4):第1章 CLR执行模型 — 1.4 执行程序集代码
  9. C语言实现控制台中光标随意移动
  10. 关于职场的6个深刻道理,每个都是血泪教训换来的,你一定要懂
  11. 【体系结构】Oracle体系结构的独特理解
  12. 网络安全以及常见的网络攻击
  13. Android 离线文字转语音功能-TTS(Text To Speech)
  14. xshell修改服务器登录密码
  15. “美国人工智能计划The American AI In”启动
  16. python-opencv第三期:cvtColor函数详解
  17. 2014年美国大学生数学建模竞赛翻译及建模思路
  18. CDN百科 | APP崩了和CDN有关系吗?
  19. 阿里云搭建自己的anki服务器
  20. python高级应用_Python高级应用程序设计任务

热门文章

  1. 标签打印软件如何设置打印区域
  2. 如何带团队,怎么带团队。
  3. 计算机最低配置有哪些,win10对电脑配置有哪些要求?win10最低配置要求
  4. 阿里云国际站代理商:阿里云国际版香港轻量ECS服务器怎么样?
  5. 一文搞懂go并发编程设计原理
  6. 魅族android不兼容Android,魅族17系列彻底跟上时代,搭载基于Android 10的Flyme 8.1系统...
  7. 【实用】Java对象与JSON字符串的互转,实用操作!
  8. 【干货书】分布式算法
  9. 【H5】 h5运行在手机浏览器查看控制台信息
  10. MTCNN配置及训练详细步骤