你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【Nucleo】基于stm32F072的双轮自平衡车(减速电机PID/MPU6050) 精华  

[复制链接]
xyc2690 提问时间:2015-1-10 16:53 /
本帖最后由 xyc2690 于 2015-2-9 00:43 编辑

平衡车初步完成~~https://v.youku.com/v_show/id_XODgyOTI4OTU2.html


硬件资料:

控制板:         NucleoF072RB
传感器:         MPU6050
电源:             聚合物锂电池12V 4000mAh
电机:             直流减速电机+编码器
电机驱动:      TB6612
DC-DC降压:  LM2596S 、AMS1117-5
电机参数.pdf (15.67 KB, 下载次数: 218)
收藏 13 评论99 发布时间:2015-1-10 16:53

举报

99个回答
xyc2690 最优答案 回答时间:2015-1-29 15:34:40
本帖最后由 xyc2690 于 2015-1-29 16:18 编辑

1422516698921.jpg

DMP读取四元数,转化成欧拉角~~

Nocleo_soft_i2c_test1 - 移植失败1失败2失败3成功4.zip (4.07 MB, 下载次数: 352)
MouseCat 回答时间:2015-1-10 20:41:54
烧多了经验就来了,哈哈
孤独的文艺青年 回答时间:2016-8-9 18:37:11
我用printf("%0.2f    %0.2f    %0.2f\r\n",Angle,Angle_ax,Gyro_y);函数分别读取的加速度,角速度和倾角,我发现当我快速的改变板子的倾角的时候,比如快速变化10度,Angle(卡尔曼滤波后的倾角)瞬时变化非常快,可能会瞬间变化几十度然后回到正常角度,而当我缓慢变化10度的时候,Angle变化是正常线性变化到10度,在这两种变化中,Angle_ax(从MPU6050读取的值经过处理后的陀螺仪的Y轴数据)的变化一直都是线性正常的,并且Angle的值特别接近Angle_ax的值
问题:1,我快速改变板子倾角时Angle的变化正常吗?
      2,Angle正常变化的时候是应该与Angle_ax的值相近吗?

现在情况就是,就算我是在减小倾角,只要我快速地改变,它显示的倾角都会先增大再减小,而如果我慢速改变的话,倾角就会缓慢减小而不会出现中间的角度增大


*************读取数据********************
//定义MPU6050内部地址
#define        SMPLRT_DIV                0x19        //陀螺仪采样率 典型值 0X07 125Hz
#define        CONFIG                          0x1A        //低通滤波频率 典型值 0x00
#define        GYRO_CONFIG                0x1B        //陀螺仪自检及测量范围                 典型值 0x18 不自检 2000deg/s
#define        ACCEL_CONFIG        0x1C        //加速度计自检及测量范围及高通滤波频率 典型值 0x01 不自检 2G 5Hz
#define INT_PIN_CFG     0x37
#define INT_ENABLE      0x38
#define INT_STATUS      0x3A    //只读
#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

//读取寄存器原生数据
           
        MPU6050_Raw_Data.Accel_X = (buf[0]<<8 | buf[1]);
        MPU6050_Raw_Data.Accel_Y = (buf[2]<<8 | buf[3]);
        MPU6050_Raw_Data.Accel_Z = (buf[4]<<8 | buf[5]);
        MPU6050_Raw_Data.Temp =    (buf[6]<<8 | buf[7]);  
        MPU6050_Raw_Data.Gyro_X = (buf[8]<<8 | buf[9]);
        MPU6050_Raw_Data.Gyro_Y = (buf[10]<<8 | buf[11]);
        MPU6050_Raw_Data.Gyro_Z = (buf[12]<<8 | buf[13]);
      
      
        //将原生数据转换为实际值,计算公式跟寄存器的配置有关
        MPU6050_Real_Data.Accel_X = -(float)(MPU6050_Raw_Data.Accel_X)/8192.0;
        MPU6050_Real_Data.Accel_Y = -(float)(MPU6050_Raw_Data.Accel_Y)/8192.0;
        MPU6050_Real_Data.Accel_Z = (float)(MPU6050_Raw_Data.Accel_Z)/8192.0;
              MPU6050_Real_Data.Gyro_X=-(float)(MPU6050_Raw_Data.Gyro_X - gyroADC_X_offset)/65.5;   
        MPU6050_Real_Data.Gyro_Y=-(float)(MPU6050_Raw_Data.Gyro_Y - gyroADC_Y_offset)/65.5;   
        MPU6050_Real_Data.Gyro_Z=(float)(MPU6050_Raw_Data.Gyro_Z - gyroADC_Z_offset)/65.5;   
    }
   


//******卡尔曼参数************
               
const float Q_angle=0.001;  
const float Q_gyro=0.003;
const float R_angle=0.5;
const float dt=0.01;                          //dt为kalman滤波器采样时间;
const char  C_0 = 1;
float Q_bias, Angle_err;
float PCt_0, PCt_1, E;
float K_0, K_1, t_0, t_1;
float Pdot[4] ={0,0,0,0};
float PP[2][2] = { { 1, 0 },{ 0, 1 } };

/*****************卡尔曼滤波**************************************************/
void Kalman_Filter(float Accel,float Gyro)               
{
        Angle+=(Gyro - Q_bias) * dt; //先验估计
       
        Pdot[0]=Q_angle - PP[0][1] - PP[1][0]; // Pk-先验估计误差协方差的微分

        Pdot[1]= -PP[1][1];
        Pdot[2]= -PP[1][1];
        Pdot[3]=Q_gyro;
       
        PP[0][0] += Pdot[0] * dt;   // Pk-先验估计误差协方差微分的积分
        PP[0][1] += Pdot[1] * dt;   // =先验估计误差协方差
        PP[1][0] += Pdot[2] * dt;
        PP[1][1] += Pdot[3] * dt;
               
        Angle_err = Accel - Angle;        //zk-先验估计
       
        PCt_0 = C_0 * PP[0][0];
        PCt_1 = C_0 * PP[1][0];
       
        E = R_angle + C_0 * PCt_0;
       
        K_0 = PCt_0 / E;
        K_1 = PCt_1 / E;
       
        t_0 = PCt_0;
        t_1 = C_0 * PP[0][1];

        PP[0][0] -= K_0 * t_0;                 //后验估计误差协方差
        PP[0][1] -= K_0 * t_1;
        PP[1][0] -= K_1 * t_0;
        PP[1][1] -= K_1 * t_1;
               
        Angle        += K_0 * Angle_err;         //后验估计
        Q_bias        += K_1 * Angle_err;         //后验估计
        Gyro_y   = Gyro - Q_bias;         //输出值(后验估计)的微分=角速度

}

******************倾角计算*****************
void Angle_Calculate(void)
{

/****************************加速度****************************************/
       
        Accel_x  =  MPU6050_Real_Data.Accel_X;          //读取X轴加速度
        Angle_ax = Accel_x*1.2*180/3.14;     //弧度转换为度

/****************************角速度****************************************/
       
         Gyro_y = MPU6050_Real_Data.Gyro_Y;             
时间dt,所以此处不用积分
/***************************卡尔曼融合*************************************/
        Kalman_Filter(Angle_ax,Gyro_y);       //卡尔曼滤波计算倾角
       

harvardx 回答时间:2015-1-10 17:18:59
简单 去淘宝或者代理商那 弄几篇072RBT6就解决了
xyc2690 回答时间:2015-1-10 17:26:37
harvardx 发表于 2015-1-10 17:18
简单 去淘宝或者代理商那 弄几篇072RBT6就解决了

主要是某觉得电源管理芯片也可能挂掉了。。
harvardx 回答时间:2015-1-10 18:02:22
本帖最后由 harvardx 于 2015-1-10 18:04 编辑

那个应该不怕, 主要是看看U4 那个要是坏掉了 焊接有麻烦.
770781327 回答时间:2015-1-10 19:34:03
先把电源部分检查下看有没问题,芯片未必有问题
xyc2690 回答时间:2015-1-10 19:47:11
770781327 发表于 2015-1-10 19:34
先把电源部分检查下看有没问题,芯片未必有问题

检查过了芯片肯定是坏了,电表测了下,GND 和VDD短路了。
电机和板子没有光耦隔离,就知道会这样。。。
芯片这边估计还买不到,淘宝10块钱一片,快递10块钱,伤心,,,
U4那块电源芯片很难焊,希望是好的吧,,,
Veiko 回答时间:2015-1-10 20:10:29
平衡车是个好东西啊,又是个考算法的题目
770781327 回答时间:2015-1-10 20:15:12
xyc2690 发表于 2015-1-10 19:47
检查过了芯片肯定是坏了,电表测了下,GND 和VDD短路了。
电机和板子没有光耦隔离,就知道会这样。。。
...

恩,芯片智能买了,u4确实不大好焊,可以考虑这部分自己搭电路替换
博根 回答时间:2015-1-10 20:37:19
GND和VCC短路不一定就说明芯片坏了 也有可能是电源保护了 仔细检测一下
xyc2690 回答时间:2015-1-10 20:48:47
z00 发表于 2015-1-10 20:37
GND和VCC短路不一定就说明芯片坏了 也有可能是电源保护了 仔细检测一下

哦?请教下,电源是怎么保护的啊?
板子的所有的3.3和地都通了,万用表测试过的。。上电就发烫,感觉是没有救了。。
Dylan疾风闪电 回答时间:2015-1-10 21:24:51
从电源开始排查吧,运气好的话芯片不会坏。只要找到坏掉的器件。
以我烧芯片的心得,看到芯片冒青烟了,那才是真的坏,其他的情况大多是某些外围挂了。
一般都是迷迷糊糊的接错电源,就烧了:前面许多板子使用12V,后来忘记把稳压电源调到5V了。
Dylan疾风闪电 回答时间:2015-1-10 21:26:22
短路的话,也可能是挂LDO啊、电路保护啊。走背字的才会挂的没救。
博根 回答时间:2015-1-10 21:49:49
xyc2690 发表于 2015-1-10 20:48
哦?请教下,电源是怎么保护的啊?
板子的所有的3.3和地都通了,万用表测试过的。。上电就发烫,感觉是没 ...

先不要拆LDO 先把稳压管 TVS 等之类的外部元件拆除 再进行测试
xyc2690 回答时间:2015-1-10 22:17:34
Dylan疾风闪电 发表于 2015-1-10 21:24
从电源开始排查吧,运气好的话芯片不会坏。只要找到坏掉的器件。
以我烧芯片的心得,看到芯片冒青烟了,那 ...

谢啦!!我去慢慢查。。
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版