为什么自己做的mpu6050模块接线一直显示004

请教stm8连接加速度传感器MPU6050测量静止时加速度问题
[问题点数:40分,结帖人u]
请教stm8连接加速度传感器MPU6050测量静止时加速度问题
[问题点数:40分,结帖人u]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2014年7月 硬件/嵌入开发大版内专家分月排行榜第二
2013年10月 硬件/嵌入开发大版内专家分月排行榜第三2013年6月 硬件/嵌入开发大版内专家分月排行榜第三2013年3月 硬件/嵌入开发大版内专家分月排行榜第三
2014年7月 硬件/嵌入开发大版内专家分月排行榜第二
2013年10月 硬件/嵌入开发大版内专家分月排行榜第三2013年6月 硬件/嵌入开发大版内专家分月排行榜第三2013年3月 硬件/嵌入开发大版内专家分月排行榜第三
2015年9月 VC/MFC大版内专家分月排行榜第二2015年7月 硬件/嵌入开发大版内专家分月排行榜第二2014年5月 VC/MFC大版内专家分月排行榜第二2014年3月 VC/MFC大版内专家分月排行榜第二2013年10月 VB大版内专家分月排行榜第二2013年7月 VB大版内专家分月排行榜第二2012年5月 VB大版内专家分月排行榜第二2012年4月 VB大版内专家分月排行榜第二2012年2月 VB大版内专家分月排行榜第二2011年11月 VB大版内专家分月排行榜第二
2015年11月 VC/MFC大版内专家分月排行榜第三2015年6月 VC/MFC大版内专家分月排行榜第三2015年2月 VC/MFC大版内专家分月排行榜第三2014年1月 VC/MFC大版内专家分月排行榜第三2012年3月 VB大版内专家分月排行榜第三2011年12月 VB大版内专家分月排行榜第三2011年10月 VB大版内专家分月排行榜第三
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。&最近在研究体感,到目前为止实现了基于51单片机的MPU6050数据采集、利用蓝牙模块将数据传输到上位机,并利用C#自制串口数据高速采集,并且将数据通过自制的折线图绘制模块可视化地展示出来等功能。本文将主要对实现这意见单系统中遇到的问题做一个小结&&其中包括:1、基于51的MPU6050模块通信简介(入门级)2、陀螺仪数据采集与传输及帧格式介绍(小)3、基于C#的串口接收函数(C#基本)4、数据池解决高速串口实时性问题(难点)5、折线图可视化模块(员基本功)关键词:MPU6050 蓝牙 C#串口 多线程 高速串口 折线图绘制&1、基于51的MPU6050模块通信简介(入门级)因为是入门级,就先最简单的介绍如何利用51从MPU6050中读取数据吧(对于想知道卡尔曼滤波、俯角仰角、距离测量、摔倒检测、记步等算法的可能要在接下来介绍)。既然要和MPU6050通信,那么必不可少的是阅读芯片手册,如果您觉得亲自去看又长又多而且都是英文的手册很费时,不仿看看我找的简要版:MPU-60X0是全球首例9轴运动。它集成了3轴MEMS陀螺仪,3轴MEMS加速计,以及1个可扩展的数字运动处理器DMP(Digital Motion Processor),可用I2C连接一个第三方的数字传感器,比如磁力计。扩展之后就可以通过其I2C或SPI接口输出一个9轴的信号。MPU-60X0也可以通过其I2C接口连接非惯性的数字传感器,比如压力传感器。&&& MPU-60X0对陀螺仪和加速计分别用了三个16位的ADC,将其测量的模拟量转化为可输出的数字量。为了精确跟踪快速和慢速运动,传感器的测量范围是可控的,陀螺仪可测范围为&250,&500,&1000,&2000&/秒(dps),加速计可测范围为&2,&4,&8,&16g(重力加速度)。注:下图是采用串口助手将MPU6050采集的数据显示在上位机上,其中前三列输出为三维的加速度(这里的加速度包括地球本身的重力加速度),后三列为三维的角速度。但是这里的输出值并不是真正的加速度和角速度的值,上面说过,MPU是一个16位AD量程可程控的设备,这里设置的加速度传感器的测量量程为正负2g(这里的g为重力加速度),陀螺仪的量程为正负2000&/s。所以要用下面的公式进行转化:好了,有了上面的之后咱们就能尝试用51的I2C总线从MPU6050读取实时的3轴加速度和3轴角速度了。由于51本身不带有I2C总线通信协议,所以我们要自己实现一个I2C通信协议,下面是我从网上找的并稍加修改的一个I2C总线通信的代码: 1 #include &REG52.H& 2 #include &INTRINS.H& 3
4 typedef unsigned char 5 typedef unsigned short ushort; 6 typedef unsigned int
8 //----------------------------------------- 9 // 定义MPU6050内部地址10 //-----------------------------------------11 #define
SMPLRT_DIV
//陀螺仪采样率,典型值:0x07(125Hz)12 #define
//低通滤波频率,典型值:0x06(5Hz)13 #define
GYRO_CONFIG
//陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)14 #define
ACCEL_CONFIG
//加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)15 #define
ACCEL_XOUT_H
0x3B16 #define
ACCEL_XOUT_L
0x3C17 #define
ACCEL_YOUT_H
0x3D18 #define
ACCEL_YOUT_L
0x3E19 #define
ACCEL_ZOUT_H
0x3F20 #define
ACCEL_ZOUT_L
0x4021 #define
TEMP_OUT_H
0x4122 #define
TEMP_OUT_L
0x4223 #define
GYRO_XOUT_H
0x4324 #define
GYRO_XOUT_L
25 #define
GYRO_YOUT_H
0x4526 #define
GYRO_YOUT_L
0x4627 #define
GYRO_ZOUT_H
0x4728 #define
GYRO_ZOUT_L
0x4829 #define
PWR_MGMT_1
//电源管理,典型值:0x00(正常启用)30 #define
//IIC地址寄存器(默认数值0x68,只读)31 #define
SlaveAddress
//IIC写入时的地址字节数据,+1为读取32 33 //-----------------------------------------34 // I2C总线通信函数35 //-----------------------------------------36 void
I2C_Start();
//I2C起始信号37 void
I2C_Stop();
//I2C停止信号38 void
I2C_SendACK(bit ack);
//I2C发送应答信号[入口参数:ack (0:ACK 1:NAK)]39 bit
I2C_RecvACK();
//I2C接收应答信号40 void
I2C_SendByte(uchar dat);
//向I2C总线发送一个字节数据41 uchar I2C_RecvByte();
//从I2C总线接收一个字节数据42 void
Single_WriteI2C(uchar REG_Address,uchar REG_data);//向I2C设备写入一个字节数据43 uchar Single_ReadI2C(uchar REG_Address);
//从I2C设备读取一个字节数据44 45 //-----------------------------------------46 // 通过I2C和MPU6050通信的函数47 //-----------------------------------------48 void InitMPU6050();
//初始化MPU605049 int GetData(uchar REG_Address);
//合成数据如果你没搞过硬件又从未听说过I2C,那么想想socket的握手再看看上面36~43行的有关ACK、Send、Write的函数大概能明白I2C的功能。当我们实现I2C的通信函数之后就可以与带有I2C通信接口的芯片进行通信,那么怎样通信呢?其实很简单&&你可以把每个芯片比做为一个巨大的储物柜,储物柜里每个抽屉里存着相应的东西,你想让佣人帮你去拿个东西,只要告诉佣人对应的抽屉号就行了。这里I2C总线相当于这个佣人,每个抽屉相当于芯片中的寄存器,抽屉号相当于寄存器地址。当你想设置芯片的某些属性时是向对应的寄存器内写数据,当想从芯片内获取相关数据时,就要通过I2C向对应的地址写数据然后接收芯片返回的数据。这里的8~31行为MPU-6050芯片内几个常用的寄存器地址,前四个常用来作为设置芯片工作属性,15~28共14个寄存器地址用来获取传感器的3轴加速度、3轴角速度和温度的数据(这里每一种信息都包括H和L两位,是由于8位表示不完该数据,于是分高低两部分)这样我们便不难理解InitMPU6050()和GetData(uchar REG_Address)函数:初始化函数是向相应的地址写初始化配置数据(关于0x00\0x07等意思请参看MPU6050寄存器版说明书),而GetData则是传入想获得数据项的低地址,然后连续读取当前地址数据和下一地址数据合成为想要的数据(上面讲了数据分高低部分)。 1 //----------------------------------------- 2 //初始化MPU6050 3 //----------------------------------------- 4 void InitMPU6050() 5 { 6
Single_WriteI2C(PWR_MGMT_1, 0x00);
//解除休眠状态 7
Single_WriteI2C(SMPLRT_DIV, 0x07); 8
Single_WriteI2C(CONFIG, 0x06); 9
Single_WriteI2C(GYRO_CONFIG, 0x18);10
Single_WriteI2C(ACCEL_CONFIG, 0x01);11 }12 //-----------------------------------------13 //合成数据14 //-----------------------------------------15 int GetData(uchar REG_Address)16 {17
uchar H,L;18
H=Single_ReadI2C(REG_Address);19
L=Single_ReadI2C(REG_Address+1);20
return (H&&8)+L;
//合成数据21 }&2、陀螺仪数据采集与传输及帧格式介绍()上面我们已经知道单片机如何利用I2C设置MPU6050的工作属性,以及从MPU6050获得3轴加速度和3轴角速度的数据。那么接下来将介绍单片机是如何将数据通过蓝牙发送给上位机的。如下图左半部分,下位机部分包括一个MPU6050、一个单片机、一个电源模块,以及一个蓝牙模块。对于蓝牙模块我不想做过多的讲解(我记得我已经写了不下于3次关于、PC等和下位机通信的教程了:(如果是想用安卓手机和蓝牙模块通信来实现遥控功能的话,可以参考:/zjutlitao/p/4231635.html;想用和蓝牙模块通信来实现遥控功能的话可以参考:/zjutlitao/p/3886826.html)&其实,利用串口蓝牙模块单片机要做的工作和对串口进行的操作一样,对串口写数据则送至蓝牙模块将数据发出,当外部有数据传送过来时,单片机可以用相应的中断捕获该事件,然后接收消息。因此主函数中初始化串口和MPU6050之后就进入循环数据发送状态,在循环中GetData是上面介绍的获得3轴加速度、3轴角速度或温度的值的函数,SendData则是将int类型的值转换为然后一位一位的发送出去,而最开始和最后分别发送一个#和$作为该帧的开始和结束标志位,具体格式如下:#&& 12354-21332-21125$&&注:符号位要么为'-',要么为空。 1 //----------------------------------------- 2 //主程序 3 //----------------------------------------- 4 void main() 5 {
delay(500);
//上电延时
init_uart(); 8
InitMPU6050();
//初始化MPU6050 9
delay(150);10
while(1)11
SeriPushSend('#');//13
SendData(GetData(0x3B));
//X轴加速度14
SendData(GetData(0x3D));
//Y轴加速度15
SendData(GetData(0x3F));
//Z轴加速度16
SeriPushSend('$'); //结束17
delay(20);18
}19 }&3、基于C#的串口接收函数(C#基本知识)上面讲到下位机通过串口蓝牙将数据发送给上位机,那么上位机如何接收蓝牙信号呢?其实以我的笔记本为例,因为笔记本内置蓝牙模块,所以无需在上位机上独立安装一个USB-蓝牙模块。而上位机操作蓝牙模块和操作串口几乎一模一样。如下面的C#程序,当点击连接按钮时实例化SerialPort,设置端口号、读超时、然后实例化一个串口数据接收事件句柄(这里PortDataReceived作为数据接收的回调函数)。 1 //Create a serial port for Connection 2 SerialPort Connection = new SerialPort(); 3 private void btn_link_Click(object sender, EventArgs e) 4 { 5
if (!Connection.IsOpen) 6
//Status = "正在连接..."; 9
Connection = new SerialPort();10
btn_link.Enabled = false;11
Connection.PortName = PortList.SelectedItem.ToString();12
Connection.Open();13
Connection.ReadTimeout = 10000;14
Connection.DataReceived += new SerialDataReceivedEventHandler(PortDataReceived);15
//Status = "连接成功";16
timer1.Start();17
}18 }在PortDataReceived中,只要简单调用Connection.Read(data, 0, length);就能从串口缓冲区读取数据到data中。1 private void PortDataReceived(object o, SerialDataReceivedEventArgs e)2 {3
byte[] data = /zjutlitao/p/new byte[length];4
int num=Connection.Read(data, 0, length);5
datepool.push_back(data,num);//实际接收的不一定是length,之前一直错6
Connection.DiscardInBuffer();7
Connection.DiscardOutBuffer();8 }注:本来是每次读取1byte放入数据池,结果出现程序运行速度越来越慢,本以为是上面的数据池设计的有问题,结果把数据池里的线程注释掉改为ask函数来每次需要数据时才获得,但是问题并不在于此;于是想到可能是绘制折线图的函数有问题,但是重查了一遍发现问题不在于此;于是仔细测量每个过程耗时,发现每个模块耗时正常,最后发现是由于串口缓冲区数据积累造成程序变慢,(因为下位机每20ms发送一次20byte的数据给上位机,上位机若一次不接收完所有数据,将会造成每次都有剩余而逐渐变慢),于是直接改成每次接收20byte,问题得到解决。&4、多线程数据池解决高速串口实时性问题(难点)由于下位机10ms发送一次20byte的数据,上位机一方面要做好接收工作,保证数据不拥挤在串口接收缓冲区;另一方面也要实时获取当前从串口读到的最新数据。如果采用传统多线程+锁的机制是可以的,但是当多线程中加入锁势必会影响程序执行效率,通过综合分析该问题最终抽象出一个特殊的数据&&自动更新的环形栈:这样,当采用多线程时,用一个类似于栈的环状栈结构体(实时从串口读数据放入数据池,数据池用p_write标记最新数据位置,当外部程序想得到最新数据时,调用ask程序,ask程序从当前p_write向前取40个数据(因为有效数据长度为20,一次取40保证至少有一个有效数据),然后从这40个数据中找出有效信息,赋值给X,Y,Z;然后外部程序可以直接用对象访问X,Y,Z),通过适当调节环的容量达到自我覆盖的效果,同时根据p_write指针可以实时取得最新数据。 1 /// &summary& 2 /// 询问当前值 3 /// &/summary& 4 /// &returns&如果解析到则返回真&/returns& 5 public bool ask() 6 { 7
i = 0;//立刻将相应的40个字符复制出来 8
p_read_from = p_write - 40; 9
while (i & 40)10
str[i] = pool[(p_read_from + pool_size) % pool_size];12
p_read_from++;14
while (i & 18 && str[i] != '$') i--;17
if (i == 18) return false;18
data_Z = 0;20
for (int j = 4; j & -1; j--)21
data_Z *= 10;23
data_Z += (str[i - j] - '0');24
if (str[i - 5] == '-') data_Z = -data_Z;26
i -= 6;27 28
data_Y = 0;29
for (int j = 4; j & -1; j--)30
data_Y *= 10;32
data_Y += (str[i - j] - '0');33
if (str[i - 5] == '-') data_Y = -data_Y;35
i -= 6;36 37
data_X = 0;38
for (int j = 4; j & -1; j--)39
data_X *= 10;41
data_X += (str[i - j] - '0');42
if (str[i - 5] == '-') data_X = -data_X;44 45
X = data_X;46
Y = data_Y;47
Z = data_Z;48
return true;49 }50 51 /// &summary&52 /// 将数据输入数据池53 /// &/summary&54 /// &param name="date"&数据&/param&55 /// &param name="length"&长度&/param&56 internal void push_back(byte[] date, int length)57 {58
for (int i = 0; i & i++)59
pool[p_write++] = date[i];61
if (p_write == pool_size) p_write = 0;62
}63 }&5、折线图可视化模块(基本功)通过上面几步我们已经可以将下位机的陀螺仪3轴的加速度收集过来了,但是如果先将数据收集好,然后再用matlab绘制,我们很难知道哪个动作对应哪个数据,不利于我们观察效果(虽然matlab上自带串口接口,但是LZ就是任性!有一张好看的脸,还是想着靠实力赢得地位,哈哈哈~)。如本节小标题括号内所示,在C#里写一个绘制折线图的程序应该属于我们的基本功(我可不是调用相应的绘图接口哦!),其大致思想就是用一个List存储num个数据,当list中的数据少于num个时则不断添加,当list内的数据大于num个时,则从尾部进来一个的同时从头部删除一个(这样才能实现perfect的效果)。注:其实中间还出现了一个逻辑错误性小插曲:原初写好之后,本以为能够实现高效数据采集显示,但是仔细观察发现还是有很大延时,但是旁边的数据显示却非常实时。这是为什么呢?查找了一会最终发现问题出在折线图绘制上&&本来采用固定的模式(一张图能存放多少数据点就用vector&int&P/Q/R在初始化的时候存放这么多点,然后每次有一个新的数据过来时就会将新数据加到vector后面,同时删除最前面的一个数据,这样做是为了方便初始vector里没有数据绘制折线图错误的问题),可是问题就出在这!咋一看这种思路很好,初始化vector中放num个点,每次新的来到将最前面一个数据冲掉,这样这个vector始终保持着num个点,且最新的在最后面,整个折线图能反应实时情况。但是由于我为了&&起见,在vector初始化时多Add几个数据,这样导致vector中的数据量N&折线图一次能呈现的数据量num,所以最新的数据总会在之后出现!当时没有想到是这个原因,就直接改了下DateLineChar函数,实现根据vector大小自动绘制的算法(这样就不用预先在vector中装入一定量的值了)&6、预告与小结(预知后事如何,请听下回分解)上面我只是简单收集了MPU6050的3轴加速度数值,当MPU6050位置固定好之后,我们就能根据数据推测其具体的姿态。例如:绿色的z轴方向的加速度先高后低,红色y轴方向加速度先低后高,蓝色x轴方向加速度和y轴类似,但是比y轴幅度变化小,而后半周期数值正负正好相反。那么MPU6050运动过程大致为:在y轴方向上做往返运动,同时在x轴和z轴方向有稍微的偏转。(水平静止放置时z轴为重力加速度,x,y为0)绿色的z轴变化不大,红色的y和蓝色的x同步类正弦变化。呵呵,这个运动状态分析起来就不太容易了~不过没关系,接下来我们要进一步获取并计算MPU6050的倾角,甚至是利用卡尔曼滤波计算MPU6050的运动距离,最终达到perfect的运动跟踪效果~&&&链接51MPU6050采集代码:/s/1c0yE7Ws4月2号总工程:/s/1hqzSt7Y (我用)4月7号总工程:/s/1hqGNqNM (我用)github:/beautifulzzzz/C4plus/tree/master/体感游戏预习用1:[芯片][MPU6050] MPU60X0的DMP相关链接预习用2:[stm32] MPU6050 HMC5883 Kalman 融合算法移植&&&&&& Mpu6050为全球首例整合3轴陀螺仪、3轴加速器、含9轴融合演;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%变动的振荡器。
应用:运动感测游戏;现实增强;电子稳像 (EIS: Electronic Image Stabilization)      光学稳像(OIS: Optical Image Stabilization);行人导航器;&零触控&手势用户接口;姿势快捷方式认证市场:智能型手机;平板装置设备;手持型游戏产品;游戏机;3D遥控器;可携式导航设备特征  1、以数字输出6轴或9轴的旋转矩阵、四元数(quaternion)、欧拉角格式(Euler Angle forma)的融合演算数据。  2、具有131 LSBs/&/sec 敏感度与全格感测范围为&250、&500、&1000与&2000&/sec 的3轴角速度感测器(陀螺仪)。  3、可程式控制,且程式控制范围为&2g、&4g、&8g和&16g的3轴加速器。  4、移除加速器与陀螺仪轴间敏感度,降低设定给予的影响与感测器的飘移。  5、数字运动处理(DMP: Digital Motion Processing)引擎可减少复杂的融合演算数据、感测器同步化、姿势感应等的负荷。  6、运动处理数据库支持Android、Linux与Windows  7、内建之运作时间偏差与磁力感测器校正演算技术,免除了客户须另外进行校正的需求。  8、以数位输出的温度传感器  9、以数位输入的同步引脚(Sync pin)支援视频电子影相稳定技术与GPS  10、可程式控制的中断(interrupt)支援姿势识别、摇摄、画面放大缩小、滚动、快速下降中断、high-G中断、零动作感应、触击感应、摇动感应功能。  11、VDD供电电压为2.5V&5%、3.0V&5%、3.3V&5%;VDDIO为1.8V& 5%  12、陀螺仪运作电流:5mA,陀螺仪待命电流:8A;加速器运作电流:8A,加速器省电模式电流: 8A@10Hz  13、高达400kHz快速模式的I2C,或最高至20MHz的SPI串行主机接口(serial host interface)  14、内建频率产生器在所有温度范围(full temperature range)仅有&1%频率变化。  15、使用者亲自测试  16、10,000 g 碰撞容忍度  17、为可携式产品量身订作的最小最薄包装 (4x4x0.9mm QFN)  18、符合RoHS及环境标准MPU-6000为全球首例整合性6轴运动处理组件,相较于多组件方案,免除了组合陀螺仪与加速器时之轴间差的问题,减少了大量的包装空间。MPU-6000整合了3轴陀螺仪、3轴加速器,并含可藉由第二个I2C端口连接其他厂牌之加速器、磁力传感器、或其他传感器的数位运动处理(DMP: Digital Motion Processor)硬件加速引擎,由主要I2C端口以单一数据流的形式,向应用端输出完整的9轴融合
  演算技术:InvenSense的运动处理资料库,可处理运动感测的复杂数据,降低了运动处理运算对操作系统的负荷,并为应用开发提供架构化的API。 从MPU6050的技术文档里我们可以看得出来一些重要参数出来!如果比例数是多少,芯片的特性都是可以看得出来的!
  第一张是MPU6000与MPU6050芯片的比较!
第二张是MPU6000与MPU6050芯片的最小驱动电路的连接!
&第三张是陀螺仪的设计规范表格!&
&第四张是加速度的设计规范表格!
下面是arduino与MPU6050的小模块的连线图:  A4接SDA& &&&A5接SCL& &vcc接3v3商家说可以接5v但是保守起见还是接了3.3v& &GND接GND不过mpu受温度的影响精度相差比较大!  注意:本模块采用的是IIC通信方式,所以我们只需要连接四跟线就可以完成电路的连接,简单方便!1.关于6050 陀螺仪和加速度计 的角速度和角度计算。  A.陀螺仪角度计算,很多帖子中都提到了用的是积分,但是我这里还是重新讲下。      angle_n = angle_n-1 + (Gyro-C_Gyro)*R_G        (1)angle_n&&当前角度值,它的单位是度(&)        (2)angle_n-1 上一次计算出的角度值        (3)Gyro 陀螺仪敏感轴偏转值,也就是当前敏感轴读数        (4)C_Gyro 陀螺仪零点偏移值,这个值的测量方法是:将陀螺仪敏感轴水平放置静止时的读数,我的零点偏移值是水平、垂直、倒置,分别取1024次,作平均值得出的,读数是-177.8865041,但是最后在程序实践中,调整到-99.90。或许还有别的办法,自己看着办吧。        (5)R_Gyro 是陀螺仪比例。飞思卡尔的参考中提到这个值是可以计算出来的,下面我会提供下载,大家自己去看看怎么算的,但是在其论坛和调试手册中都提到,这个比例值还是实验法测量出来的比较准确。&&&& B.加速度仪 角度计算。   加速度仪的角度计算有很多方法,论坛里就有2中。但是都用到了三角函数,数学没学好,照抄了也不行。参考了飞思卡尔的计算方法后大概是这样的。&&&&&&&&&&&&&&&&& Angle_Z = (az-C_Z)*R_Z;         (1)angle_z 加速度计敏感轴Z轴产生倾角计算出的角度,单位度(&)         (2)az 是加速度仪 Z轴读数         (3)C_Z Z轴零点偏移量 测量方法和陀螺仪的一样。         (4)R_Z 加速度计Z轴比例  C.反复试验,MPU6050加速度计Z轴对应的是陀螺仪的X轴。不知道是不是我的有问题,还是就这么设计的?&&
阅读(...) 评论()}

我要回帖

更多关于 gy521 mpu6050模块 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信