三轴陀螺仪mpu6050测试程序
- 格式:doc
- 大小:455.00 KB
- 文档页数:9
合嵌盘古陀螺仪模块规格书合嵌盘古Gyroscope-601陀螺仪模块,测量运动或震动的三轴全方向的角速度值和加速度值,角速度最大测量范围±2000°/sec,加速度最大测量范围达到±16g。
合嵌盘古陀螺仪模块采集到的物体运动的实际角速度值和加速度值,直接从串口输出。
输出的数据格式有两种形式,分别为16进制数据和根据传感器芯片手册中的数据转换规则转换得到的实际角速度值和加速度值。
另外,本陀螺仪模块可以通过串口设置加速度阀值。
当加速度模块测量到物体运动的加速度达到此阀值时,将通过IO口输出一个高电平或低电平的跳变信号,作为中断信号使用。
合嵌盘古Gyroscope-601陀螺仪模块通过串口输出的加速度值数据如下所示:aX=0X66 +0.0gaY=0Xfff3 -0.0gaZ= 0Xe8b +0.9ggX=0Xffc6 -0.43dpsgY=0X2d +0.34dpsgZ= 0Xff7b -1.01dps其中:aX、aY、aZ分别表示三轴加速度值,gX、gY、gZ分别表示三轴角速度值。
其中 aX=0X66 +0.0g 中的0X66表示传感器测量到的16进制加速度值, +0.0g表示根据加速度传感器芯片的数据转换规则转换成的物体运动的加速度值。
其中 gX=0Xffc6 -0.43dps 中的0X ffc6表示传感器测量到的16进制角速度值,-0.43dps表示根据加速度传感器芯片的数据转换规则转换成的物体运动的角速度值。
陀螺仪模块的电气参数:工作电压: +5V工作电流: ≤50mA陀螺仪模块的技术参数:测量方向:三轴全方向自检测: 支持传感器模块的自检测加速度值测量范围: ≤±16g角速度最大测量范围: ≤±2000°/sec最高灵敏度:≤131 LSB/(º/s)数据输出率:最大8KHz抗震动的最大忍受度:≤1000g联系Q Q: 1094606988加速度模块研发生产商:安徽合嵌电子科技有限公司地址:滁州市花园西路82号1栋302#网址:应用汽车运动及汽车转弯碰撞检测、轮船运动及转弯碰撞检测、运动物体检测、电子稳像、光学稳像、 行人导航器、 “零触控”手势用户接口、 姿势快捷方式 、认证市场智能型手机 平板装置设备 手持型游戏产品 游戏机 3D遥控器 可携式导航设备。
平衡车⼊门---MPU6050陀螺仪学习MPU6050陀螺仪模块⼀、MPU6050简介:MPU6050是⼀款陀螺仪模块,不过这个模块可不简单,它可以测量X、Y、Z三轴的⾓速度和加速度,还带有温度传感器和数字运动处理器(DMP)。
假如我们要制作平衡车、四轴、空中⿏标,那么MPU6050就真的是派上⼤⽤场了。
⼆、学习MPU6050的步骤:1、学习I2C协议,因为MPU6050是通过I2C协议进⾏驱动的,配置寄存器和获取数据都需要通过I2C协议去实现单⽚机与MPU6050之间的通信,所以I2C协议必须学习。
2、了解MPU6050的相关寄存器,可以看中⽂⽂档MPU6050的datasheet,再配合MPU6050的驱动库函数,了解库函数为什么要这样配置MPU6050的寄存器。
3、把获取到的原始数据进⾏各种处理,如通过互补滤波融合得到⾓度。
要知道只有对原始数据进⾏处理才能够使⽤,才能发挥MPU6050的价值。
三、I2C协议简介:I2C协议是⼀种在单⽚机开发中⾮常常⽤的⼀个通信协议,它是通过数据总线SDA和时钟总线SCL去完成单⽚机与⼀些传感器模块的通信。
SCL和SDA线根据I2C的协议的标准进⾏⼀系列⾼低电平的变化(时序)就可以完成信息的传输。
I2C协议还分为硬件I2C和软件I2C,硬件I2C就是通过硬件电路去实现的I2C协议,软件I2C就是通过在单⽚机上找两个IO⼝去充当SCL和SDA线,再通过⼈为编写软件去控制SCL和SDA线的⾼低电平变化去模拟I2C协议。
两者的区别是硬件I2C使⽤起来⽐较简单,执⾏速度⽐较快,耗时短,但是毕竟是硬件电路,稳定性不⼀定好,容易出现⼀些奇怪的问题。
⽽软件I2C虽然是通过软件模拟的,执⾏速度不如硬件I2C快,有⼀定的耗时,不过稳定性就⽐硬件I2C好多了。
智能车我们⾮常注重稳定性,所以推荐⼤家还是⽤软件I2C。
四、MPU6050硬件介绍:我们先来认识下MPU6050的硬件,这是MPU6050模块的图⽚,注意是模块,中间那个才是MPU6050,不过只有MPU6050是不够的,它还需要⼀些外围电路才能正常⼯作,我们可以类⽐⼀下51单⽚机和51单⽚机的最⼩系统的区别。
姿态角解算(MPU6050 加速度计加陀螺仪)本文持续更新…I2C通信AHRS是自动航向基准系统(Automatic Heading Reference System)的简称。
目前,使用四元数来进行AHRS姿态解算的算法被广泛采用于四轴飞行器上。
IMU部分:IMU是惯性测量装置(Inertial Measurement Unit)的简称,通常包含陀螺仪和加速度计。
1.陀螺仪:测量的是角速度,即物体转动的速度,把速度和时间相乘,即可以得到某一时间段内物体转过的角度。
(但是积分运算得来的角度本身就存在误差,随着时间的累加,误差会加剧,此时就需要加速度计辅助计算出姿态角度)2.加速度计:测量的是物体的加速度,我们知道,重力加速度是一个物体受重力作用的情况下所具有的加速度。
当物体处于静止状态时,加速度计测量出来的值就等于重力加速度1g, 约等于9.8米每平方秒。
重力加速度g的方向总是竖直向下的,通过获得重力加速度在其X轴,Y轴上的分量,我们可以计算出物体相对于水平面的倾斜角度。
典型的IMU惯性测量芯片为MPU6050,它被广泛采用在四轴飞行器上。
mpu6050便是这两种传感器结合测出姿态角,通常运用卡尔曼滤波得出最终角度根据加速度计和地磁计的数据,转换到地理坐标系后,与对应参考的重力向量和地磁向量进行求误差,这个误差用来校正陀螺仪的输出,然后用陀螺仪数据进行四元数更新,再转换到欧拉角陀螺仪的角速度测量:如果他的速度是1度不加秒,我们用速度乘以时间就可以知道他从起点走了多少度。
加速度计来测量倾角:一个简单的例子如下: 一个单轴的加速计位于重力水平面上的时候,它在垂直方向上受到的加速度为1g,在水平方向上受到的加速度为0。
当我们把它旋转一个角度的时候,就会在水平轴上产生一个加速度分量。
通过它们的关系,就可以计算出该单轴加速计的倾角。
1.通过陀螺仪的积分来获得四轴的旋转角度2.然后通过加速度计的比例和积分运算来修正陀螺仪的积分结果。
第错误!未定义书签。
页共10页MPU6050教程1.1MPU6050简介如果你想玩四轴,想搞什么空中鼠标,平衡车等待,那么MPU6050真的是太强大了,能做很多东西。
玩MPU6050的步骤:1.学习I2C ,I2C 就是MPU6050传送数据到单片机的一种协议,类似于USB ,当然USB 还是比较有难度的。
2.了解MPU6050相关寄存器,有中文版本的,一边学一边看例程就可以获取数据了。
3.把获取的数据进行各种处理。
1.2IIC 简介IIC 可以去看下我们野火相关的教程,在这里只是简单地介绍下,先看下我们的书或者教程,从EEPROM 里面写入和读取数据,因为EEPROM 写入和读取数据也是根据I2C 协议来的。
I2C 有分软件和硬件,软件就你通过对I2C 的时钟线和数据线,可能你不知道时钟线和数据线,那还是先去学I2C 的基础教程。
软件模拟I2C 就是根据下面的图然后再适当的时候给时钟线和数据线高低,具体可以看I2C 的协议见图1-1。
图1-1IIC 起始字节时序图这部分学习的诀窍就是:先写下I2C通讯的一个环节就好了,比如起始字节,其他的也是大同小异,直接上网找例程就好了,想要用软件模拟出全部的时序当然也可以。
还有一个方式可以用I2C读写数据,就是硬件I2C,硬件I2C就是单片机内部的电路,可以将I2C的时序用硬件电路搞出来,这样子你读写数据就方便很多了。
STM32硬件I2C可以去看我们野火的教程。
1.3读取MPU6050原始数据我们先来认识下MPU6050的硬件,这是MPU6050模块的图片,注意是模块,中间那个才是MPU6050,只有MPU6050是不够的,还要有一些外围电路才行,这就跟51芯片跟最小系统的区别一样。
图1-2MPU6050模块正面图1-3MPU6050模块背面管脚名称说明VCC 3.3-5V(内部有稳压芯片)GND地线SCL MPU6050作为从机时IIC时钟线SDA MPU6050作为从机时IIC数据线XCL MPU6050作为主机时IIC时钟线XDA MPU6050作为主机时IIC数据线AD0地址管脚,该管脚决定了IIC地址的最低一位INT中断引脚这里重点讲解AD0的作用,I2C通讯中从机是要有地址的,以区别多个从机。
mpu6050控制舵机程序Chapter 1: Introduction to MPU6050 and Servo Control1.1 BackgroundThe MPU6050 is a popular motion sensor module that combines a 3-axis accelerometer and 3-axis gyroscope. It provides accurate measurements of motion and orientation, making it ideal for applications such as robotics, drones, and motion-based gaming. Additionally, servo motors are widely used in various fields, including robotics and automation, for precise control of angular position. This paper aims to explore the application of theMPU6050 sensor for controlling a servo motor.1.2 ObjectivesThe main objective of this paper is to develop a program that utilizes the MPU6050 sensor to control a servo motor. Specifically, the program will read the sensor data to detect changes in motion and orientation and correspondingly adjust the position of the servo motor. The program will be implemented using Arduino, a popular open-source electronics platform.Chapter 2: MPU6050 and Servo Motor Interface2.1 MPU6050 SensorThe MPU6050 sensor is a 6-DOF (Degrees of Freedom) module that combines a 3-axis accelerometer and 3-axis gyroscope. It communicates with the Arduino board using the I2C serial interface. The sensor provides motion and orientation data in the form of raw sensor values.2.2 Servo MotorA servo motor is a rotary actuator that allows precise control of angular position. It consists of a motor, a control circuit, and a feedback system. Servo motors are widely used in various applications, including robotics and automation. In this paper, a standard servo motor with a rotation range of 0 to 180 degrees will be used.2.3 Interface DesignThe MPU6050 and servo motor will be interfaced with the Arduino board. The sensor's SDA and SCL pins will be connected to the Arduino's I2C pins, while the servo motor's control pin will be connected to one of the Arduino's PWM pins. The Arduino will act as the bridge between the sensor and the servo motor, processing the sensor data and generating appropriate control signals for the servo motor.Chapter 3: Program Implementation3.1 Sensor CalibrationBefore using the sensor, a calibration process is necessary to obtain accurate readings. The program will include a calibration routine that measures the sensor's zero-g offset and sensitivity. This data will be used to compensate for measurement errors and provide accurate motion and orientation information.3.2 Data Reading and ProcessingThe program will continuously read the sensor's raw data, including accelerometer and gyroscope readings. The accelerometer data will be used to detect changes in motion, whilethe gyroscope data will provide information about the orientation. The program will process this sensor data to calculate the desired servo motor position.3.3 Servo Motor ControlBased on the processed sensor data, the program will generate appropriate control signals for the servo motor. The position of the servo motor will be adjusted proportionally to the detected motion and orientation changes. The servo motor position will be converted to the corresponding pulse width modulation (PWM) signal, which will set the desired position of the servo motor.Chapter 4: Experiment and Results4.1 Experimental SetupAn experimental setup will be created to validate the performance of the program. The MPU6050 sensor and the servo motor will be connected to the Arduino board, and the program will be uploaded to the board. Various motion and orientation changes will be induced to observe the corresponding servo motor movement.4.2 Results and AnalysisThe results of the experiment will be analyzed to evaluate the performance of the program in accurately controlling the servo motor based on the MPU6050 sensor data. The accuracy of the servo motor's position and response time will be assessed. Any limitations or improvements will be discussed.4.3 ConclusionIn conclusion, this paper presented a program for controlling aservo motor using the MPU6050 sensor. The implementation and experimental results demonstrate the effectiveness of the programin accurately adjusting the servo motor position based on motion and orientation changes. Further enhancements for real-time applications and other potential improvements will be discussedfor future work.探索宇宙——人类科学的壮举尽管人类在探索宇宙这一任务上还有很长的路要走,但我们已经取得了一些令人瞩目的成就。
Pcduino很强大,但是我实在驾驭不了此等神器,所以最后还是用我最熟悉的51进行mpu6050的调试。
不用pcduino的原因主要有:看了很多有关pcduino的I2C总线使用教程,但是讲的很不好,我甚至没有在教程里看到任何有关I2C总线的操作函数,虽然pcduino自带I2C总线,但是我根本没法使用。
而51的I2C总线操作函数是我自己写的,我很熟悉,所以就用51进行调试。
mpu6050的相关资料已经上传,请自行查阅。
提示:中文资料虽然看着方便,但是很多地方说的不清楚,还是老老实实啃英文资料吧。
调试的源代码请参阅test1.0.c,这是51的源码,其他平台请自行开发。
简单讲一下匿名上位机的使用方法,匿名上位机的功能非常强大,国内许多飞行器玩家都在使用,它主要有以下几个功能:基本收发串口的基本收发功能,并可以精确到毫秒级别的定时发送,和普通的串口精灵用法一致,可以分别设置HEX格式或者字符串格式的收码或者发码,并优化数据显示处理线程,可以高速显示接收到的串口数据。
是进行串口基本调试必备基础功能。
高级收码高级收码从基本收码升级而来,上位机收到数据后,若高级收码的开关是打开的,那么就会对接收到的数据进行解析,数据的格式由通信协议定义。
分为固定格式和自定义格式两大部分。
自定义格式是留给大家DIY自由发挥用,可以自己设置每帧数据的内容和每个数据的格式(int8,int16,float等)。
固定格式是上位机定义好的,具有特定功能的帧格式,具体见数据协议电子表格,这些固定格式的数据对上位机来说是具有一定意义的,例如传感器数据、姿态数据、GPS数据等等,上位机收到这些固定格式的数据后,就会刷新相应的状态显示。
波形显示波形显示从高级收码升级而来,上位机解析出数据后,不管是自定义格式的数据还是固定格式的数据,都可以画出其相应波形。
调试四轴需要观察各种数据的波形,例如传感器数据、传感器滤波后数据、姿态角数据、控制量、状态量等等,虽然高级收码可以解析出相应数据,但是用来分析还是很不方便的,看不出数据的变化趋势和各个数据间的关系,此时我们可以画出想要观察的数据的波形,几条波形在一起比较,就可以方便的进行数据分析。
这个程序完成的功能为:使用msp430f5529在12864上串行显示GY-521,MPU6050所测量的角度。
在IAR亲测成功。
注意:我只给出了C文件,h文件自己去建立就好了。
////*******主函数******///#include <msp430f5529.h>#include "stdio.h"#include "math.h"#include "6050.h"#include "LCD12864.h"void Delays( uchar i){unsigned int j;while(i--){j=2000;while(j--);}}void main(void){WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗char sum1[10],sum2[10],sum3[10]; // 串口发送缓存float a_x,a_y,a_z;int_port() ;//管脚初始化lcdinit();InitMPU6050(); // 初始化模块display(1,1,"角度X:");display(2,1,"角度Y:");display(3,1,"角度Z:");while(1){// Delays(2);a_x = mpu6050_Angle(2);a_y = mpu6050_Angle(1);a_z = mpu6050_Angle(0);sprintf(sum1,"%.2f",a_x); // 将测量倾角值转换为字符串sprintf(sum2,"%.2f",a_y);sprintf(sum3,"%.2f",a_z);display(1,4,sum1);display(2,4,sum2);display(3,4,sum3);}}////************6050IIC******/////******************************************************************************文件名:Mpu-6050.c**编写者:黄建军**描述:三轴加速度,三轴陀螺仪传感器Mpu-6050的驱动程序,此处用于149系列。
三轴加速度传感器MPU-6050(2013-01-17 16:25:07)转载▼分类:常识积累MPU-60X0 对陀螺仪和加速度计分别用了三个16 位的ADC,将其测量的模拟量转化为可输出的数字量。
为了精确跟踪快速和慢速的运动,传感器的测量范围都是用户可控的,陀螺仪可测范围为±250,±500,±1000,±2000°/秒(dps),加速度计可测范围为±2,±4,±8,±16g。
在网上找了一会,好像MPU-6050没有中文的数据手册,由于本人也处于学习阶段,翻译的可能不太准确,只能表达一下简单的意思,以官方数据手册为准。
引脚说明:VDD 供电电压为2.5V±5%、3.0V±5%、3.3V±5%;VDDIO 为1.8V± 5%内建振荡器在工作温度范围内仅有±1%频率变化。
可选外部时钟输入32.768kHz 或19.2MHz 找出几个重要的寄存器:1)Register 25 – Sample Rate Divider (SMPRT_DIV)1)SMPLRT_DIV 8位无符号值,通过该值将陀螺仪输出分频,得到采样频率该寄存器指定陀螺仪输出率的分频,用来产生MPU-60X0的采样率。
传感器寄存器的输出、FIFO输出、DMP采样和运动检测的都是基于该采样率。
采样率的计算公式采样率= 陀螺仪的输出率/ (1 + SMPLRT_DIV)当数字低通滤波器没有使能的时候,陀螺仪的输出平路等于8KHZ,反之等于1KHZ。
2)Register 26 – Configuration (CONFIG)1)EXT_SYNC_SET 3位无符号值,配置帧同步引脚的采样2)DLPF_CFG 3位无符号值,配置数字低通滤波器该寄存器为陀螺仪和加速度计配置外部帧同步(FSYNC)引脚采样和数字低通滤波器(DLPF)。
名称:MPU-6050模块(三轴陀螺仪+ 三轴加速度) 单价:75.00(未税)使用芯片:MPU-6050供电电源:3-5v(内部低压差稳压)通信方式:标准IIC通信协议芯片内置16bit AD转换器,16位数据输出陀螺仪范围:±250 500 1000 2000 °/s加速度范围:±2±4±8±16g采用沉金PCB,机器焊接工艺保证质量引脚间距2.54mm提供原理图,相关数据手册及参考文档MPU-6000为全球首例整合性6轴运动处理组件,相较于多组件方案,免除了组合陀螺仪与加速器时之轴间差的问题,减少了大量的包装空间。
MPU-6000整合了3轴陀螺仪、3轴加速器,并含可藉由第二个I2C端口连接其他厂牌之加速器、磁力传感器、或其他传感器的数位运动处理(DMP: Digital Motion Processor)硬件加速引擎,由主要I2C端口以单一数据流的形式,向应用端输出完整的9轴融合演算技术InvenSense的运动处理资料库,可处理运动感测的复杂数据,降低了运动处理运算对操作系统的负荷,并为应用开发提供架构化的API。
MPU-6000的角速度全格感测范围为±250、±500、±1000与±2000°/sec (dps),可准确追緃快速与慢速动作,并且,用户可程式控制的加速器全格感测范围为±2g、±4g±8g与±16g。
产品传输可透过最高至400kHz的I2C或最高达20MHz的SPI。
MPU-6000可在不同电压下工作,VDD供电电压介为2.5V±5%、3.0V±5%或3.3V±5%,逻辑接口VVDIO供电为1.8V±5%。
MPU-6000的包装尺寸4x4x0.9mm(QFN),在业界是革命性的尺寸。
其他的特征包含内建的温度感测器、包含在运作环境中仅有±1%变动的振荡器。
MPU6050是一款常用的三轴陀螺仪和三轴加速度计模块,它可以用于测量和解算飞行器的姿态角,是无人机和其他飞行器项目中常用的传感器之一。
在解算飞行器的姿态角时,使用四元数解算是一种常见且有效的方法。
本文将介绍MPU6050四元数姿态解算的结果,包括其原理、算法和实际应用。
一、MPU6050的工作原理1.1 三轴陀螺仪MPU6050的三轴陀螺仪可以测量飞行器围绕X、Y、Z轴的角速度,其工作原理是利用霍尔传感器测量角速度对应的旋转矢量。
通过积分得到飞行器当前的姿态角速度。
1.2 三轴加速度计MPU6050的三轴加速度计可以测量飞行器在X、Y、Z轴的加速度,其工作原理是利用加速度对应的位移变化,计算得到飞行器的加速度。
1.3 传感器融合MPU6050将三轴陀螺仪和三轴加速度计的数据进行融合,通过卡尔曼滤波等算法得到更为准确的姿态角度。
二、四元数解算姿态角2.1 四元数原理四元数是一种数学工具,用来描述旋转和姿态变换。
在飞行器姿态控制中,通常使用四元数来表示飞行器当前的姿态角。
四元数可以简洁地表示旋转,且在插值和积分运算中具有优势。
2.2 四元数解算算法MPU6050使用四元数解算算法,根据三轴陀螺仪的角速度数据来更新四元数,从而得到飞行器当前的姿态角。
四元数解算算法运用了加速度计和磁力计的数据,使得姿态角的计算更为准确和稳定。
2.3 解算结果MPU6050四元数解算的结果是飞行器当前的姿态角,包括俯仰角、横滚角和偏航角。
这些角度是飞行器在空间中的姿态,对于飞行器的稳定飞行和姿态控制具有重要意义。
三、MPU6050四元数姿态解算的实际应用3.1 无人机姿态控制在无人机项目中,MPU6050四元数姿态解算可以用于无人机的姿态控制。
通过实时更新无人机的姿态角,可以使无人机保持稳定飞行和响应操控信号。
3.2 姿态稳定相机MPU6050四元数姿态解算还可以应用在姿态稳定相机上。
通过获取相机的姿态角,可以使相机在运动中保持稳定,获得更加清晰和稳定的图像。
陀螺仪的范围有±250、±500、±2000可选,而对应的精度分别是131LSB/(°/s)、65.5LSB/(°/s)、32.8LSB/(°/s)、16.4 LSB/(°/s)a.那么这个精度和范围的关系是什么?首先MPU6050数据寄存器是一个16位的,由于最高位是符号位,故而数据寄存器的输出范围是-7FFF~7FFF ,也既是-32767~32767;b.如果选择陀螺仪范围是±2000,那么意味着-32767对应的是-2000(°/s),32767对应是2000(°/s),当读取陀螺仪的值是1000的,对应的角速度计算如下:32767/2000 =1000/x; 既x = 1000/16.4(°/s),可以看出32767/2000 = 16.4 ,对应手册中的精度 16.4 LSB/(°/s),其他范围的也是如此。
c.在四轴姿态计算中,我们通常要把角度换算成弧度。
我们知道2Pi代表360度,那么1度换算成弧度就是:2Pi/360=(2*3.1415926)/360=0.0174532=1/57.30。
d.总结:当量程为-2000到+2000的范围,把陀螺仪获取的数据转换为真正的弧度每秒的公式:(gyro_x来代表从陀螺仪读到的数据): gyro_x/(16.40*57.30)=gyro_x*0.001064,单位为弧度每秒。
2、加速度计采用和陀螺仪同样的计算方法,当AFS_SEL=3时,数字-32767对应-16g,32767对应16g。
把32767除以16,就可以得到2048,即我们说的灵敏度。
把从加速度计读出的数字除以2048,就可以换算成加速度的数值。
举个例子,如果我们从加速度计读到的数字是1000,那么对应的加速度数据是1000/2048=0.49g。
g为加速度的单位,重力加速度定义为1g, 等于9.8米每平方秒。
MPU6050数据轻松分析MPU6050是一款集成为了三轴加速度计和三轴陀螺仪的传感器,广泛应用于姿态感知、运动跟踪和智能设备等领域。
本文将介绍如何使用MPU6050传感器获取数据并进行轻松分析。
1. 数据获取首先,我们需要连接MPU6050传感器到我们的目标设备上。
通过I2C接口,我们可以方便地与传感器进行通信。
使用适当的引脚连接,确保传感器与目标设备电源和地线正确连接。
接下来,我们需要编写代码来初始化传感器并获取数据。
以下是一个示例代码:```C++#include <Wire.h>const int MPU_addr=0x68; // I2C地址int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;void setup(){Wire.begin();Wire.beginTransmission(MPU_addr);Wire.write(0x6B); // PWR_MGMT_1寄存器地址Wire.write(0); // 将寄存器设置为0(唤醒传感器)Wire.endTransmission(true);Serial.begin(9600);}void loop(){Wire.beginTransmission(MPU_addr);Wire.write(0x3B); // 从ACCEL_XOUT_H寄存器开始读取数据 Wire.endTransmission(false);Wire.requestFrom(MPU_addr,14,true); // 读取14个字节的数据 AcX=Wire.read()<<8|Wire.read(); // 加速度计X轴数据AcY=Wire.read()<<8|Wire.read(); // 加速度计Y轴数据AcZ=Wire.read()<<8|Wire.read(); // 加速度计Z轴数据Tmp=Wire.read()<<8|Wire.read(); // 温度数据GyX=Wire.read()<<8|Wire.read(); // 陀螺仪X轴数据GyY=Wire.read()<<8|Wire.read(); // 陀螺仪Y轴数据GyZ=Wire.read()<<8|Wire.read(); // 陀螺仪Z轴数据// 在串口监视器中打印数据Serial.print("加速度计:");Serial.print("X = "); Serial.print(AcX);Serial.print(" | Y = "); Serial.print(AcY);Serial.print(" | Z = "); Serial.println(AcZ);Serial.print("温度:");Serial.print(Tmp/340.00+36.53);Serial.println(" °C");Serial.print("陀螺仪:");Serial.print("X = "); Serial.print(GyX);Serial.print(" | Y = "); Serial.print(GyY);Serial.print(" | Z = "); Serial.println(GyZ);delay(500);}```2. 数据分析获取MPU6050传感器的数据后,我们可以进行各种分析和处理。
InvenSense公司的三轴陀螺仪MPU6050测试程序。
IIC接口,51单片机驱动,LCD1602同步显示。
硬件原理图//****************************************// MPU6050 IIC测试程序// 使用单片机STC89C52// 晶振:11.0592M// 显示:LCD1602// 编译环境Keil uVision2// 参考宏晶网站24c04通信程序// 功能: 显示加速度计和陀螺仪的10位原始数据// 时间:2013年3月1日//****************************************#include <REG52.H>#include <math.h> //Keil library#include <stdio.h> //Keil library#include <INTRINS.H>typedef unsigned char uchar;typedef unsigned short ushort;typedef unsigned int uint;//****************************************// 定义51单片机端口//****************************************#define DataPort P0 //LCD1602数据端口sbit SCL=P1^0; //IIC时钟引脚定义sbit SDA=P1^1; //IIC数据引脚定义sbit LCM_RS=P2^0; //LCD1602命令端口sbit LCM_RW=P2^1; //LCD1602命令端口sbit LCM_EN=P2^2; //LCD1602命令端口//****************************************// 定义MPU6050内部地址//****************************************#define SMPLRT_DIV 0x19 //陀螺仪采样率,典型值:0x07(125Hz)#define CONFIG 0x1A //低通滤波频率,典型值:0x06(5Hz)#define GYRO_CONFIG 0x1B //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)#define ACCEL_CONFIG 0x1C //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)#define ACCEL_XOUT_H 0x3B#define ACCEL_XOUT_L 0x3C#define ACCEL_YOUT_H 0x3D#define ACCEL_YOUT_L 0x3E#define ACCEL_ZOUT_H 0x3F#define ACCEL_ZOUT_L 0x40#define TEMP_OUT_H 0x41#define TEMP_OUT_L 0x42#define GYRO_XOUT_H 0x43#define GYRO_XOUT_L 0x44#define GYRO_YOUT_H 0x45#define GYRO_YOUT_L 0x46#define GYRO_ZOUT_H 0x47#define GYRO_ZOUT_L 0x48#define PWR_MGMT_1 0x6B //电源管理,典型值:0x00(正常启用)#define WHO_AM_I 0x75 //IIC地址寄存器(默认数值0x68,只读)#define SlaveAddress 0xD0 //IIC写入时的地址字节数据,+1为读取//****************************************//定义类型及变量//****************************************uchar dis[4]; //显示数字(-511至512)的字符数组int dis_data; //变量//int Temperature,Temp_h,Temp_l; //温度及高低位数据//****************************************//函数声明//****************************************void delay(unsigned int k); //延时//LCD相关函数void InitLcd(); //初始化lcd1602void lcd_printf(uchar *s,int temp_data);void WriteDataLCM(uchar dataW); //LCD数据void WriteCommandLCM(uchar CMD,uchar Attribc); //LCD指令void DisplayOneChar(uchar X,uchar Y,uchar DData); //显示一个字符void DisplayListChar(uchar X,uchar Y,uchar *DData,L); //显示字符串//MPU6050操作函数void InitMPU6050(); //初始化MPU6050void Delay5us();void I2C_Start();void I2C_Stop();void I2C_SendACK(bit ack);bit I2C_RecvACK();void I2C_SendByte(uchar dat);uchar I2C_RecvByte();void I2C_ReadPage();void I2C_WritePage();void display_ACCEL_x();void display_ACCEL_y();void display_ACCEL_z();uchar Single_ReadI2C(uchar REG_Address); //读取I2C数据void Single_WriteI2C(uchar REG_Address,uchar REG_data); //向I2C写入数据//****************************************//整数转字符串//****************************************void lcd_printf(uchar *s, int temp_data){if(temp_data<0){temp_data=-temp_data;*s='-';}else *s=' ';*++s =temp_data/100+0x30;temp_data=temp_data%100; //取余运算*++s =temp_data/10+0x30;temp_data=temp_data%10; //取余运算*++s =temp_data+0x30;}//****************************************//延时//****************************************void delay(unsigned int k){unsigned int i,j;for(i=0;i<k;i++){for(j=0;j<121;j++);}}//****************************************//LCD1602初始化//****************************************void InitLcd(){WriteCommandLCM(0x38,1);WriteCommandLCM(0x08,1);WriteCommandLCM(0x01,1);WriteCommandLCM(0x06,1);WriteCommandLCM(0x0c,1);DisplayOneChar(0,0,'A');DisplayOneChar(0,1,'G');}//****************************************//LCD1602写允许//****************************************void WaitForEnable(void){DataPort=0xff;LCM_RS=0;LCM_RW=1;_nop_();LCM_EN=1;_nop_();_nop_();while(DataPort&0x80);LCM_EN=0;}//****************************************//LCD1602写入命令//****************************************void WriteCommandLCM(uchar CMD,uchar Attribc) {if(Attribc)WaitForEnable();LCM_RS=0;LCM_RW=0;_nop_();DataPort=CMD;_nop_();LCM_EN=1;_nop_();_nop_();LCM_EN=0;}//****************************************//LCD1602写入数据//****************************************void WriteDataLCM(uchar dataW){WaitForEnable();LCM_RS=1;LCM_RW=0;_nop_();DataPort=dataW;_nop_();LCM_EN=1;_nop_();_nop_();LCM_EN=0;}//****************************************//LCD1602写入一个字符//****************************************void DisplayOneChar(uchar X,uchar Y,uchar DData) {Y&=1;X&=15;if(Y)X|=0x40;X|=0x80;WriteCommandLCM(X,0);WriteDataLCM(DData);}//****************************************//LCD1602显示字符串//****************************************void DisplayListChar(uchar X,uchar Y,uchar *DData,L) {uchar ListLength=0;Y&=0x1;X&=0xF;while(L--){DisplayOneChar(X,Y,DData[ListLength]);ListLength++;X++;}}//**************************************//延时5微秒(STC90C52RC@12M)//不同的工作环境,需要调整此函数//当改用1T的MCU时,请调整此延时函数//************************************** void Delay5us(){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}//**************************************//I2C起始信号//************************************** void I2C_Start(){SDA = 1; //拉高数据线SCL = 1; //拉高时钟线Delay5us(); //延时SDA = 0; //产生下降沿Delay5us(); //延时SCL = 0; //拉低时钟线}//**************************************//I2C停止信号//************************************** void I2C_Stop(){SDA = 0; //拉低数据线SCL = 1; //拉高时钟线Delay5us(); //延时SDA = 1; //产生上升沿Delay5us(); //延时}//**************************************//I2C发送应答信号//入口参数:ack (0:ACK 1:NAK)//**************************************void I2C_SendACK(bit ack){SDA = ack; //写应答信号SCL = 1; //拉高时钟线Delay5us(); //延时SCL = 0; //拉低时钟线Delay5us(); //延时}//**************************************//I2C接收应答信号//**************************************bit I2C_RecvACK(){SCL = 1; //拉高时钟线Delay5us(); //延时CY = SDA; //读应答信号SCL = 0; //拉低时钟线Delay5us(); //延时return CY;}//**************************************//向I2C总线发送一个字节数据//**************************************void I2C_SendByte(uchar dat){uchar i;for (i=0; i<8; i++) //8位计数器{dat <<= 1; //移出数据的最高位SDA = CY; //送数据口SCL = 1; //拉高时钟线Delay5us(); //延时SCL = 0; //拉低时钟线Delay5us(); //延时}I2C_RecvACK();}//**************************************//从I2C总线接收一个字节数据//**************************************uchar I2C_RecvByte(){uchar i;uchar dat = 0;SDA = 1; //使能内部上拉,准备读取数据,for (i=0; i<8; i++) //8位计数器{dat <<= 1;SCL = 1; //拉高时钟线Delay5us(); //延时dat |= SDA; //读数据SCL = 0; //拉低时钟线Delay5us(); //延时}return dat;}//**************************************//向I2C设备写入一个字节数据//**************************************void Single_WriteI2C(uchar REG_Address,uchar REG_data){I2C_Start(); //起始信号I2C_SendByte(SlaveAddress); //发送设备地址+写信号I2C_SendByte(REG_Address); //内部寄存器地址,I2C_SendByte(REG_data); //内部寄存器数据,I2C_Stop(); //发送停止信号}//**************************************//从I2C设备读取一个字节数据//**************************************uchar Single_ReadI2C(uchar REG_Address){uchar REG_data;I2C_Start(); //起始信号I2C_SendByte(SlaveAddress); //发送设备地址+写信号I2C_SendByte(REG_Address); //发送存储单元地址,从0开始I2C_Start(); //起始信号I2C_SendByte(SlaveAddress+1); //发送设备地址+读信号REG_data=I2C_RecvByte(); //读出寄存器数据I2C_SendACK(1); //接收应答信号I2C_Stop(); //停止信号return REG_data;//**************************************//初始化MPU6050//**************************************void InitMPU6050(){Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态Single_WriteI2C(SMPLRT_DIV, 0x07);Single_WriteI2C(CONFIG, 0x06);Single_WriteI2C(GYRO_CONFIG, 0x18);Single_WriteI2C(ACCEL_CONFIG, 0x01);}//**************************************//在1602上显示10位数据//**************************************void Display10BitData (int value,uchar x,uchar y){value/=64; //转换为10位数据value=value/64 右移动六位lcd_printf(dis, value); //转换数据显示DisplayListChar(x, y, dis, 4); //启始列,行,显示数组,显示长度}//**************************************//合成数据//**************************************int GetData(uchar REG_Address){char H,L;H=Single_ReadI2C(REG_Address);L=Single_ReadI2C(REG_Address+1);return (H<<8)+L; //合成数据}//**************************************//显示温度//**************************************//void display_temp()//{// Temp_h=Single_ReadI2C(TEMP_OUT_H); //读取温度// Temp_l=Single_ReadI2C(TEMP_OUT_L); //读取温度// Temperature=Temp_h<<8|Temp_l; //合成温度// Temperature = 35+ ( (double) (Temperature + 13200)) / 280; // 计算出温度// lcd_printf(dis,Temperature); //转换数据显示// DisplayListChar(11,1,dis,4); //启始列,行,显示数组,显示位数//}//*********************************************************//主程序//*********************************************************void main(){delay(500); //上电延时InitLcd(); //液晶初始化InitMPU6050(); //初始化MPU6050delay(150);while(1){Display10BitData (GetData(ACCEL_XOUT_H), 2, 0); //显示X轴加速度Display10BitData (GetData(ACCEL_YOUT_H), 7, 0); //显示Y轴加速度Display10BitData (GetData(ACCEL_ZOUT_H) , 12, 0);//显示Z轴加速度Display10BitData (GetData(GYRO_XOUT_H) , 2, 1); //显示X轴角速度Display10BitData (GetData(GYRO_YOUT_H), 7, 1); //显示Y轴角速度Display10BitData (GetData(GYRO_ZOUT_H), 12, 1); //显示Z轴角速度delay(500);}}。
【学习心得】MPU6050数据处理实验一本帖最后由葱拌豆腐于 2013-3-16 09:12 编辑MPU6050模块买了都好几个月了,出来前些日子做一下简单的数据获取,再没做过新的实验,一直在看资料,从自横小车的姿态矫正到四轴飞行器的姿态矫正等给类帖子看了不少,昨天晚上终于动手做了一次实验,这次实验主要是想试一下用陀螺仪来输出传感器的三轴角度(相对于地平面)。
下面是实验的代码:ARDUINO 代码1.#include <I2Cdev.h>2.#include <MPU6050.h>3.#include <Wire.h>//添加必须的库文件4.//====一下三个定义了陀螺仪的偏差===========5.#define Gx_offset -3.066.#define Gy_offset 1.017.#define Gz_offset -0.888.//====================9.MPU6050 accelgyro;10.11.int16_t ax,ay,az;12.int16_t gx,gy,gz;//存储原始数据13.float aax,aay,aaz,ggx,ggy,ggz;//存储量化后的数据14.float Ax,Ay,Az;//单位 g(9.8m/s^2)15.float Gx,Gy,Gz;//单位°/s16.17.float Angel_accX,Angel_accY,Angel_accZ;//存储加速度计算出的角度18.19.long LastTime,NowTime,TimeSpan;//用来对角速度积分的20.21.#define LED_PIN 1322.23.bool blinkState=false;24.25.void setup()//MPU6050的设置都采用了默认值,请参看库文件26.{27.Wire.begin();28.29.Serial.begin(9600);30.31.Serial.println("Initializing I2C device.....");32.accelgyro.initialize();33.34.Serial.println("Testing device connections...");35.Serial.println(accelgyro.testConnection()? "MPU6050 connection successful":"MPU6050 connection failure");36.37.pinMode(LED_PIN,OUTPUT);38.}39.40.void loop()41.{42.accelgyro.getMotion6(&ax,&ay,&az,&gx,&gy,&gz );//获取三个轴的加速度和角速度43.// Serial.print(ax/16384.00);44.// Serial.print(",");45.// Serial.print(ay/16384.00);46.// Serial.print(",");47.// Serial.print(az/16384.00);48.// Serial.print(",");49.// Serial.print(gx/131.00);50.// Serial.print(",");51.// Serial.print(gy/131.00);52.// Serial.print(",");53.// Serial.println(gz/131.00);54.//======一下三行是对加速度进行量化,得出单位为g的加速度值55.Ax=ax/16384.00;56.Ay=ay/16384.00;57.Az=az/16384.00;58.//==========以下三行是用加速度计算三个轴和水平面坐标系之间的夹角59.//请参考:[url]/forum.php?mod=viewthread&tid=2328&page=1#pid2787 6[/url]60.//个人觉得原帖中case0算的不对,应该是z/sqrt (x*x+y*y),估计是江南楼主写错了61.Angel_accX=atan(Ax/sqrt(Az*Az+Ay*Ay))*180/3.1 4;62.Angel_accY=atan(Ay/sqrt(Ax*Ax+Az*Az))*180/3.1 4;63.Angel_accZ=atan(Az/sqrt(Ax*Ax+Ay*Ay))*180/3.1 4;64.//==========以下三行是对角速度做量化==========65.ggx=gx/131.00;66.ggy=gy/131.00;67.ggz=gz/131.00;68.69.//===============以下是对角度进行积分处理================70.NowTime=millis();//获取当前程序运行的毫秒数71.TimeSpan=NowTime-LastTime;//积分时间这样算不是很严谨72.//下面三行就是通过对角速度积分实现各个轴的角度测量,当然假设各轴的起始角度都是073.Gx=Gx+(ggx-Gx_offset)*TimeSpan/1000;74.Gy=Gy+(ggy-Gy_offset)*TimeSpan/1000;75.Gz=Gz+(ggz-Gz_offset)*TimeSpan/1000;76.stTime=NowTime;78.79.//==============================80.Serial.print(Angel_accX);81.Serial.print(",");82.Serial.print(Angel_accY);83.Serial.print(",");84.Serial.print(Angel_accZ);85.Serial.print(",");86.Serial.print(Gx);87.Serial.print(",");88.Serial.print(Gy);89.Serial.print(",");90.Serial.println(Gz);91.// Serial.print(ggx-Gx_offset);92.// Serial.print(",");93.// Serial.print(ggy-Gy_offset);94.// Serial.print(",");95.// Serial.println(ggz-Gz_offset);96.97.blinkState=!blinkState;98.digitalWrite(LED_PIN,blinkState);99.100.delay(100);//这个用来控制采样速度101.}角速度传感器一定要矫正偏移,我采用的方法就是先读取若干数值,然后将数值导入到excel中,取平均值,该平均值就是传感器当前状态下的偏移,在后面的角度积分中一定要先用原始角速度值减掉对应的偏移,下面两个曲线就是进行偏移校正前后的效果:下面的图片是进行了偏移量校正,可以发现三个轴的角速度基本都在0坐标轴附近上下波动:下图是对角速度进行积分输出的三个轴的角度变化曲线,没做滤波处理,基本上能反应出传感器的姿态。
仅翻译了有用部分——By LeeDy.Li2013.1.7《MPU-6000/MPU-6050产品说明书》1.版本更新2.应用范围3.产品简介MPU-60X0是全球首例9轴运动处理传感器。
它集成了3轴MEMS陀螺仪,3轴MEMS 加速度计,以及一个可扩展的数字运动处理器DMP(Digital Motion 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。
陀螺仪的范围有±250、±500、±2000可选,而对应的精度分别是131LSB/(°/s)、65.5LSB/(°/s)、32.8LSB/(°/s)、16.4 LSB/(°/s)a.那么这个精度和范围的关系是什么?首先MPU6050数据寄存器是一个16位的,由于最高位是符号位,故而数据寄存器的输出范围是-7FFF~7FFF ,也既是-32767~32767;b.如果选择陀螺仪范围是±2000,那么意味着-32767对应的是-2000(°/s),32767对应是2000(°/s),当读取陀螺仪的值是1000的,对应的角速度计算如下:32767/2000 =1000/x; 既x = 1000/16.4(°/s),可以看出32767/2000 = 16.4 ,对应手册中的精度 16.4 LSB/(°/s),其他范围的也是如此。
c.在四轴姿态计算中,我们通常要把角度换算成弧度。
我们知道2Pi代表360度,那么1度换算成弧度就是:2Pi/360=(2*3.1415926)/360=0.0174532=1/57.30。
d.总结:当量程为-2000到+2000的范围,把陀螺仪获取的数据转换为真正的弧度每秒的公式:(gyro_x来代表从陀螺仪读到的数据): gyro_x/(16.40*57.30)=gyro_x*0.001064,单位为弧度每秒。
2、加速度计采用和陀螺仪同样的计算方法,当AFS_SEL=3时,数字-32767对应-16g,32767对应16g。
把32767除以16,就可以得到2048,即我们说的灵敏度。
把从加速度计读出的数字除以2048,就可以换算成加速度的数值。
举个例子,如果我们从加速度计读到的数字是1000,那么对应的加速度数据是1000/2048=0.49g。
g为加速度的单位,重力加速度定义为1g, 等于9.8米每平方秒。