最终代码

Dependencies:   mbed

Fork of MPU6050_Driver_Balance by Chen Huan

main.cpp

Committer:
glintligo
Date:
2018-05-20
Revision:
1:db5ac8bf9280
Parent:
0:badebd32bd8b

File content as of revision 1:db5ac8bf9280:

#include "mbed.h"
#include "mpu6050.h" 
#define PWM_PERIOD 1    //pwm波的周期  单位ms
#define RATE 0.01       //定时中断的周期,单位s


struct PID
{
    float Kp;
    float Ki;
    float Kd;
    float error;
    float dif_error;
    float last_error;
    float int_error;
};

                           
float NTMAX=100.0;                          //最大容错
float t =0.0;                               //pid控制的目标
PID PID_Para={0.00008,0.0,-0.00057};        //pid参数,kp,kp,kd
float pitch,roll,yaw;                       //欧拉角
float co;                                   //pid输出结果,作为pwm波的输入


Ticker toggle_time_ticker;                  //时间中断,用来控制转速的变化
DigitalOut myled(PC_13);                    //检测mpu是否正常初始化,正常初始化后不会闪烁
Serial pc(PA_9, PA_10);                     //蓝牙串口
PwmOut mypwm1(PA_7);                        //控制电机的pwm波
PwmOut mypwm2(PA_6);                        //控制电机的pwm波
PwmOut mypwm3(PB_0);                        //控制电机的pwm波
PwmOut mypwm4(PB_1);                        //控制电机的pwm波

/**
 * [calculate 计算pid控制结果]
 * @param  input  [pid的输入]
 * @param  target [pid控制目标]
 * @return        [pid的输出]
 */
float calculate(float input,float target);
/**
 * [make 时间中断函数]
 */
void make();


int main() {
    //设定pwm波的周期 为1ms
    mypwm1.period_ms(PWM_PERIOD);
    mypwm2.period_ms(PWM_PERIOD);
    mypwm3.period_ms(PWM_PERIOD);
    mypwm4.period_ms(PWM_PERIOD);

    //初始化MPU6050,正常初始化后不会闪烁
    MPU_Init();                 
    myled = 0;
    while(mpu_dmp_init())
    {
        wait(0.2);
        myled = !myled;
    }    

    //设置定时中断的周期为100hz,调用中断函数为void make()
    toggle_time_ticker.attach(&make, RATE);

    while(1)
    {
        //获取mpu数据,roll为俯仰角
        mpu_dmp_get_data(&pitch,&roll,&yaw);
    }  

}

/**
 * [make 时间中断函数]
 */
void make() {
    //计算pid控制结果        
    co = calculate(roll, t); 
    //控制电机
    if (co >=0)
    {  
       mypwm1.pulsewidth(co);
       mypwm2.pulsewidth(0);
       mypwm3.pulsewidth(co);
       mypwm4.pulsewidth(0);
    }
    else
    {
       mypwm1.pulsewidth(0);
       mypwm2.pulsewidth(-co);
       mypwm3.pulsewidth(0);
       mypwm4.pulsewidth(-co);
    }
}

/**
 * [calculate 计算pid控制结果]
 * @param  input  [pid的输入]
 * @param  target [pid控制目标]
 * @return        [pid的输出]
 */
float calculate(float input,float target)
{
    //计算输入与目标的偏差
    PID_Para.error=target-input;
    //设置死位
    if(PID_Para.error<1.0 && PID_Para.error >-1.0) PID_Para.error=0.0;
    //计算微分
    PID_Para.dif_error=PID_Para.error-PID_Para.last_error;
    //后一位偏差
    PID_Para.last_error=PID_Para.error;
    //计算积分
    PID_Para.int_error+=PID_Para.error;
    //限制积分范围
    if(PID_Para.int_error >= NTMAX)
        PID_Para.int_error = NTMAX;
    if(PID_Para.int_error <= -NTMAX)
        PID_Para.int_error = -NTMAX;
    
    float output;
    //计算pid结果
    output=PID_Para.Kp*PID_Para.error+PID_Para.Ki*PID_Para.int_error-PID_Para.Kd*PID_Para.dif_error;
    return output;
}