OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 13859|回复: 5

关于MPU6050 校准问题请教

[复制链接]

15

主题

43

帖子

0

精华

初级会员

Rank: 2

积分
124
金钱
124
注册时间
2013-10-7
在线时间
0 小时
发表于 2013-12-20 23:29:25 | 显示全部楼层 |阅读模式
我的MPU6050用了互补滤波法得到x, y,z轴的角度但是很不准,平放模块时不为x轴角度不为0,程序如下
//*********************************************************
// 倾角计算(卡尔曼融合)
//*********************************************************

void Angle_Calcu(unsigned char A,unsigned char G)    
{
    //------加速度--------------------------

    //范围为2g时,换算关系:16384 LSB/g
    //角度较小时,x=sinx得到角度(弧度), deg = rad*180/3.14
    //因为x>=sinx,故乘以1.3适当放大

    Accel_x  = GetData(A);    //读取X轴加速度
    Angle_ax = (Accel_x - 1100) /16384;   //去除零点偏移,计算得到角度(弧度)
    Angle_ax = Angle_ax*1.2*180/3.14;     //弧度转换为度,


    //-------角速度-------------------------

    //范围为2000deg/s时,换算关系:16.4 LSB/(deg/s)

    Gyro_y = GetData(G);          //静止时角速度Y轴输出为-30左右
    Gyro_y = -(Gyro_y + 30)/16.4;         //去除零点偏移,计算角速度值,负号为方向处理 
    Angle_gy = Angle_gy + Gyro_y*0.01;  //角速度积分得到倾斜角度.        
    
    if(A==ACCEL_XOUT_H)
    ComplementFilterX(Angle_ax,Gyro_y);
    if(A==ACCEL_YOUT_H)
    ComplementFilterY(Angle_ax,Gyro_y);
    if(A==ACCEL_ZOUT_H)
    ComplementFilterZ(Angle_ax,Gyro_y);
}   
    /*//-------卡尔曼滤波融合-----------------------  

    Kalman_Filter(Angle_ax,Gyro_y);       //卡尔曼滤波计算倾角
     

    //-------互补滤波-----------------------

    //补偿原理是取当前倾角和加速度获得倾角差值进行放大,然后与
    //陀螺仪角速度叠加后再积分,从而使倾角最跟踪为加速度获得的角度
    //0.5为放大倍数,可调节补偿度;0.01为系统周期10ms        
            
    Angle = Angle + (((Angle_ax-Angle)*0.5 + Gyro_y)*0.01);
                                                                                                       */
/**
* 互补滤波参数
*/
float tau = 0.065, p = 0.0;         // 用于计算比例
float dtc = 0.01;                   // 抽样时间10ms
static float bias_gx = 0.0,bias_gy = 0.0,bias_gz = 0.0,gy_temp; // 零点漂移误差消除
static float fix_angle,fiy_angle,fiz_angle;
/**
* 互补滤波算法
* angle 为重力感应获得的角度值
* gy_speed 为角速度
*/
float ComplementFilterX(float angle, float gy_sped)
{
    bias_gx = bias_gx*0.998+gy_sped*0.002;  // 消除零点误差
    gy_temp = gy_sped - bias_gx;            // 减去零点误差
    p = tau/(tau+dtc);

    // 对角速度gy_temp进行高通滤波,对重力感应得到的角度angle进行低通滤波
    fix_angle = p*(fix_angle+gy_temp*dtc)+(1-p)*angle;
    return fix_angle;
}
float ComplementFilterY(float angle, float gy_sped)
{
    bias_gz = bias_gz*0.998+gy_sped*0.002;  // 消除零点误差
    gy_temp = gy_sped - bias_gz;            // 减去零点误差
    p = tau/(tau+dtc);

    // 对角速度gy_temp进行高通滤波,对重力感应得到的角度angle进行低通滤波
    fiy_angle = p*(fiy_angle+gy_temp*dtc)+(1-p)*angle;
    return fiy_angle;
}
float ComplementFilterZ(float angle, float gy_sped)
{
    bias_gx = bias_gx*0.998+gy_sped*0.002;  // 消除零点误差
    gy_temp = gy_sped - bias_gx;            // 减去零点误差
    p = tau/(tau+dtc);

    // 对角速度gy_temp进行高通滤波,对重力感应得到的角度angle进行低通滤波
    fiz_angle = p*(fiz_angle+gy_temp*dtc)+(1-p)*angle;
    return fiz_angle;
}
int main(void)
{        
Stm32_Clock_Init(9);//系统时钟设置
/*IIC接口初始化*/
I2C_MPU6050_Init(); 
/*陀螺仪传感器初始化*/
InitMPU6050();
//hw_tick_start();   // 定时器周期性中断,用于提供系统脉搏
while(1)
{
        
                
           Angle_Calcu(ACCEL_XOUT_H,GYRO_YOUT_H);
        //Display10BitData(fix_angle);

       Angle_Calcu(ACCEL_YOUT_H,GYRO_ZOUT_H);
        //Display10BitData(fiy_angle);

        Angle_Calcu(ACCEL_ZOUT_H,GYRO_XOUT_H);
        //Display10BitData(fiz_angle);
}
}
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2013-12-20 23:39:41 | 显示全部楼层
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2014-5-1
在线时间
0 小时
发表于 2014-5-3 22:58:14 | 显示全部楼层
我是用STC12C5A60S2芯片做小车的也遇到同样的问题
回复 支持 反对

使用道具 举报

2

主题

8

帖子

0

精华

新手上路

积分
35
金钱
35
注册时间
2016-4-27
在线时间
5 小时
发表于 2016-5-3 23:41:16 | 显示全部楼层
Angle_ax = (Accel_x - 1100) /16384;   //去除零点偏移,计算得到角度(弧度)
Gyro_y = -(Gyro_y + 30)/16.4;         //去除零点偏移,计算角速度值,负号为方向处理


请问一下,1100和30是怎么来?
回复 支持 反对

使用道具 举报

45

主题

99

帖子

1

精华

高级会员

Rank: 4

积分
539
金钱
539
注册时间
2015-7-24
在线时间
89 小时
发表于 2016-9-29 13:14:02 | 显示全部楼层
gjhlzq 发表于 2016-5-3 23:41
Angle_ax = (Accel_x - 1100) /16384;   //去除零点偏移,计算得到角度(弧度)
Gyro_y = -(Gyro_y + 30) ...

传感器静止状态下读取数据若干次求平均得到的 1100和30,若干次可以是几千次,次数越多,精度越高,
我的淘宝小店 shop113369282.taobao.com
回复 支持 反对

使用道具 举报

45

主题

99

帖子

1

精华

高级会员

Rank: 4

积分
539
金钱
539
注册时间
2015-7-24
在线时间
89 小时
发表于 2016-9-29 13:14:47 | 显示全部楼层
本帖最后由 Embedded 于 2016-9-29 13:33 编辑
Embedded 发表于 2016-9-29 13:14
传感器静止状态下读取数据若干次求平均得到的 1100和30,若干次可以是几千次,次数越多,精度越高,

这里的1100是  +1100,,30是 -30
我的淘宝小店 shop113369282.taobao.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-24 18:31

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表