MPU6050传感芯片简介.doc

上传人:一*** 文档编号:809318 上传时间:2019-07-16 格式:DOC 页数:16 大小:209.50KB
返回 下载 相关 举报
MPU6050传感芯片简介.doc_第1页
第1页 / 共16页
MPU6050传感芯片简介.doc_第2页
第2页 / 共16页
点击查看更多>>
资源描述

《MPU6050传感芯片简介.doc》由会员分享,可在线阅读,更多相关《MPU6050传感芯片简介.doc(16页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、摘要MPU6050 是一种非常流行的空间运动传感器芯片,可以获取器件当前的三个加速度分量和三个旋转角速度。由于其体积小巧,功能强大,精度较高,不仅被广泛应用于工业,同时也是航模爱好者的神器,被安装在各类飞行器上驰骋蓝天。随着 Arduino 开发板的普及,许多朋友希望能够自己制作基于 MPU6050 的控制系统,但由于缺乏专业知识而难以上手。此外,MPU6050 的数据是有较大噪音的,若不进行滤波会对整个控制系统的精准确带来严重影响。MPU6050 芯片内自带了一个数据处理子模块 DMP,已经内置了滤波算法,在许多应用中使用 DMP 输出的数据已经能够很好的满足要求。本文将直接面对原始测量数据

2、,从连线、芯片通信开始一步一步教你如何利用 Arduino 获取 MPU6050 的数据并进行卡尔曼滤波,最终获得稳定的系统运动状态。一、Arduino 与 MPU-6050 的通信为避免纠缠于电路细节,我们直接使用集成的 MPU6050 模块。MPU6050 的数据接口用的是 I2C 总线协议,因此我们需要 Wire 程序库的帮助来实现 Arduino 与 MPU6050 之间的通信。请先确认你的 Arduino 编程环境中已安装 Wire 库。Wire 库的官方文档(arduino.cc/en/Reference)中指出:在 UNO 板子上,SDA 接口对应的是 A4 引脚,SCL 对应的

3、是 A5 引脚。MPU6050 需要 5V 的电源,可由 UNO 板直接供电。按照下图连线。 (紫色线是中断线,这里用不到,可以不接) MPU6050 的数据写入和读出均通过其芯片内部的寄存器实现,这些寄存器的地址都是 1个字节,也就是 8 位的寻址空间,其寄存器的详细列表说明书请点击下载: 将数据写入 MPU-6050在每次向器件写入数据前要先打开 Wire 的传输模式,并指定器件的总线地址,MPU6050的总线地址是 0x68(AD0 引脚为高电平时地址为 0x69)。然后写入一个字节的寄存器起始地址,再写入任意长度的数据。这些数据将被连续地写入到指定的起始地址中,超过当前寄存器长度的将写

4、入到后面地址的寄存器中。写入完成后关闭 Wire 的传输模式。下面的示例代码是向 MPU6050 的 0x6B 寄存器写入一个字节 0。Wire.beginTransmission(0x68); /开启 MPU6050 的传输Wire.write(0x6B); /指定寄存器地址 Wire.write(0); /写入一个字节的数据 Wire.endTransmission(true); /结束传输,true 表示释放总线1.2 从 MPU-6050 读出数据读出和写入一样,要先打开 Wire 的传输模式,然后写一个字节的寄存器起始地址。接下来将指定地址的数据读到 Wire 库的缓存中,并关闭传输

5、模式。最后从缓存中读取数据。下面的示例代码是从 MPU6050 的 0x3B 寄存器开始读取 2 个字节的数据:Wire.beginTransmission(0x68); /开启 MPU6050 的传输 Wire.write(0x3B); /指定寄存器地址 Wire.requestFrom(0x68, 2, true); /将输据读出到缓存 Wire.endTransmission(true); /关闭传输模式 int val = Wire.read() #include #include float fRad2Deg = 57.295779513f; /将弧度转为角度的乘数 const in

6、t MPU = 0x68; /MPU-6050的I2C地址 const int nValCnt = 7; /一次读取寄存器的数量const int nCalibTimes = 1000; /校准时读数的次数 int calibDatanValCnt; /校准数据unsigned long nLastTime = 0; /上一次读数的时间 float fLastRoll = 0.0f; /上一次滤波得到的Roll角 float fLastPitch = 0.0f; /上一次滤波得到的Pitch角 Kalman kalmanRoll; /Roll角滤波器 Kalman kalmanPitch; /

7、Pitch角滤波器void setup() Serial.begin(9600); /初始化串口,指定波特率Wire.begin(); /初始化Wire库WriteMPUReg(0x6B, 0); /启动MPU6050设备Calibration(); /执行校准nLastTime = micros(); /记录当前时间 void loop() int readoutsnValCnt;ReadAccGyr(readouts); /读出测量值float realVals7;Rectify(readouts, realVals); /根据校准的偏移量进行纠正/计算加速度向量的模长,均以g为单位flo

8、at fNorm = sqrt(realVals0 * realVals0 + realVals1 * realVals1 + realVals2 * realVals2);float fRoll = GetRoll(realVals, fNorm); /计算Roll角if (realVals1 0) fRoll = -fRoll;float fPitch = GetPitch(realVals, fNorm); /计算Pitch角if (realVals0 0) fPitch = -fPitch;/计算两次测量的时间间隔dt,以秒为单位unsigned long nCurTime = mic

9、ros();float dt = (double)(nCurTime - nLastTime) / 1000000.0;/对Roll角和Pitch角进行卡尔曼滤波float fNewRoll = kalmanRoll.getAngle(fRoll, realVals4, dt);float fNewPitch = kalmanPitch.getAngle(fPitch, realVals 5, dt);/跟据滤波值计算角度速float fRollRate = (fNewRoll - fLastRoll) / dt;float fPitchRate = (fNewPitch - fLastPit

10、ch) / dt;/更新Roll角和Pitch角fLastRoll = fNewRoll;fLastPitch = fNewPitch;/更新本次测的时间nLastTime = nCurTime;/向串口打印输出Roll角和Pitch角,运行时在Arduino的串口监 视器中查看Serial.print(“Roll:“);Serial.print(fNewRoll); Serial.print();Serial.print(fRollRate); Serial.print(“),tPitch:“);Serial.print(fNewPitch); Serial.print();Serial.p

11、rint(fPitchRate); Serial.print(“)n“);delay(10); /向MPU6050写入一个字节的数据 /指定寄存器地址与一个字节的值 void WriteMPUReg(int nReg, unsigned char nVal) Wire.beginTransmission(MPU);Wire.write(nReg);Wire.write(nVal);Wire.endTransmission(true); /从MPU6050读出一个字节的数据 /指定寄存器地址,返回读出的值 unsigned char ReadMPUReg(int nReg) Wire.begin

12、Transmission(MPU);Wire.write(nReg);Wire.requestFrom(MPU, 1, true);Wire.endTransmission(true);return Wire.read(); /从MPU6050读出加速度计三个分量、温度和三个角速度计 /保存在指定的数组中 void ReadAccGyr(int *pVals) Wire.beginTransmission(MPU);Wire.write(0x3B);Wire.requestFrom(MPU, nValCnt * 2, true);Wire.endTransmission(true);for (

13、long i = 0; i nValCnt; +i) pValsi = Wire.read() 8 | Wire.read(); /对大量读数进行统计,校准平均偏移量 void Calibration() float valSums7 = 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0 .0;/先求和for (int i = 0; i nCalibTimes; +i) int mpuValsnValCnt;ReadAccGyr(mpuVals);for (int j = 0; j nValCnt; +j) valSumsj += mpuValsj;/再求平均for

14、(int i = 0; i nValCnt; +i) calibDatai = int(valSumsi / nCalibTimes);calibData2 += 16384; /设芯片Z轴竖直向下,设定静态工作点 。 /算得Roll角。算法见文档。 float GetRoll(float *pRealVals, float fNorm) float fNormXZ = sqrt(pRealVals0 * pRealVals0 + pRealV als2 * pRealVals2);float fCos = fNormXZ / fNorm;return acos(fCos) * fRad2De

15、g; /算得Pitch角。算法见文档。 float GetPitch(float *pRealVals, float fNorm) float fNormYZ = sqrt(pRealVals1 * pRealVals1 + pRealV als2 * pRealVals2);float fCos = fNormYZ / fNorm;return acos(fCos) * fRad2Deg; /对读数进行纠正,消除偏移,并转换为物理量。公式见文档。 void Rectify(int *pReadout, float *pRealVals) for (int i = 0; i 3; +i) pRealValsi = (float)(pReadouti - calibDatai) / 16 384.0f;pRealVals3 = pReadout3 / 340.0f + 36.53;for (int i = 4; i 7; +i) pRealValsi = (float)(pReadouti - calibDatai) / 13 1.0f;5. 参考:https:/

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com