基于stm32的位置和速度双闭环PID直流电机控制
为什么要用双闭环PID算法?
在PID算法中,我们如果只是使用单个闭环PID控制会出现很多的不足。例如我们在单独使用位置环时,在电机未能达到预设位置时,电机的运行状态是100%PWM满偏运行的,这样在我们实际运用时,如果我们使用的电机功率很高就会造成速度过快的现象。所以在电机的控制过程中,最好是多环控制。
如何将位置环和速度环一起使用?
在设计过程中,我是不断地尝试得出的结果。最终得出将位置环和速度环的输出叠加的方法,在位置没有到达预设位置时虽然位置环的输出会是满偏,但满偏会让速度出现偏差,速度环就会输出负值反过来抑制总的输出,这样我们就可以在实现位置环的同时也有了速度环的控制。但注意的是在快达到预设位置时需要将速度环关闭。
程序部分代码
位置式PID用于位置环
int PID_output ()
{
float PIDOUT;
pid.Ek=pid.Sv-pid.Pv;
PIDOUT=pid.Kp*pid.Ek+pid.Ki*(pid.Ek+pid.Ek_1+pid.Ek_2)+pid.Kd*(pid.Ek-pid.Ek_1)+pid.OUT0;
pid.Ek_2=pid.Ek_1;
pid.Ek_1=pid.Ek;
pid.PIDOUT=PIDOUT;
pid.PIDOUT=(pid.PIDOUT<pid.lowlimit) ? pid.lowlimit:(pid.PIDOUT>pid.uplimit) ? pid.uplimit : pid.PIDOUT;
return pid.PIDOUT;
}
增量式PID用于速度环
int PID1_output ()
{
float PIDOUT;
pid1.Ek=pid1.Sv-pid1.Pv;
PIDOUT=pid1.Kp*(pid1.Ek-pid1.Ek_1)+pid1.Ki*pid1.Ek+pid1.Kd*(pid1.Ek_2*pid1.Ek_1+pid1.Ek_2)+pid1.OUT0;
pid1.Ek_2=pid1.Ek_1;
pid1.Ek_1=pid1.Ek;
pid1.PIDOUT+=PIDOUT;
pid1.PIDOUT=(pid1.PIDOUT<pid1.lowlimit) ? pid1.lowlimit:(pid1.PIDOUT>pid1.uplimit) ? pid1.uplimit : pid1.PIDOUT;
return pid1.PIDOUT;
}
结合
float myabs(float a)
{
int temp;
if(a<0) temp=-a;
else temp=a;
return temp;
}
float Set_Pwm(float moto1)
{
float OUT;
if(moto1>0) AIN2=0, AIN1=1;
else AIN2=1, AIN1=0;
OUT=myabs(moto1);
return OUT;
}
if(pid.Ek>-100&&pid.Ek <100) OUT=0;
else OUT=PID1_output();
pwm=Set_Pwm(PID_output())+OUT;
程序源码:https://download.csdn.net/download/qq_41327460/11393949?spm=1001.2014.3001.5501