直流电机闭环PID控制
作者:神秘网友
发布时间:2020-08-28 23:12:38
直流电机闭环PID控制
直流电机闭环PID控制PID
P—比例控制系统的响应快速性,快速作用于输出,好比"现在"(现在就起作用,快),I—积分控制系统的准确性,消除过去的累积误差,好比"过去"(清除过去积怨,回到准确轨道),D—微分控制系统的稳定性,具有超前控制作用,好比"未来"(放眼未来,未雨绸缪,稳定才能发展)。当然这个结论也不可一概而论,只是想让初学者更加快速的理解PID的作用。(注1)
资料有很多,可参考
1,https://blog.csdn.net/tingfenghanlei/article/details/85028677
2,https://zh.wikipedia.org/wiki/PID%E6%8E%A7%E5%88%B6%E5%99%A8
理论看着很晦涩,敲写代码发现很常规。积分微分只是出来吓人的。注意Kp等参数根据负载特性调节。此代码示例为基础实现,也可增加滤波器优化。
int32_t sp=0,pv=0,pv_1=0,e=0,e_i=0,e_d = 0,out=0; /* tune according to load characteristics */ float Kp = 20.0; float Ki = 0.01; float Kd = 10.0; sp = 10000; while (1) { //error pv=TIM2->CNT; e = sp - pv; //derivative = e - e_i,in case sp changes,use pv e_d = pv_1 - pv; //Integral when error within threshold if(e < Integral_TH && e > (-1 * Integral_TH)){ e_i += e; } if(e_i > Integral_HIGH ){ e_i = Integral_HIGH; } else if(e_i < (-1 * Integral_HIGH)){ e_i = -1 * Integral_HIGH; } if(e == 0){ e_i = 0; } //PID out = (int32_t)(Kp * e + Ki * e_i + Kd * e_d); pv_1 = pv; if(out > PWM_PERIOD ){ out = PWM_PERIOD + 1; } else if(out < PWM_LOW && out > 0){ out = PWM_LOW; } else if(out < (-1 * PWM_PERIOD)){ out = -1 * PWM_PERIOD - 1; } else if(out >(-1 * PWM_LOW) && out < 0){ out = -1 * PWM_LOW; } //out to pwm if(out >= 0){ TIM3->CCR1 = 0; TIM3->CCR2 = out; } else{ TIM3->CCR1 = -1 * out; TIM3->CCR2 = 0; } // printf("OUT:%d|PV:%d|e:%d|e_i:%d\r\n",out,pv,e,e_i); HAL_Delay(1); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
此篇是基于直流电机增加编码器实现闭环控制,类似的场景还有闭环步进电机(mechaduino),参见https://github.com/jcchurch13/Mechaduino-Firmware。