基于stm32的位置和速度双闭环PID直流电机控制

基于stm32的位置和速度双闭环PID直流电机控制

  • 为什么要用双闭环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;

你可能感兴趣的:(算法研究,PID,stm32,双闭环控制)