有关PID的理论相关的内容,网上有很多介绍很全很专业,然而看完后并不能应用于项目落地,本文描述一个真实的PID控制混水中心出水温度的案例。

关于PID控制,借用一下网上的图片:

混龄班班务工作总结_混龄经验心得_混龄教育的探索与实践

本案例目的是混水中心输出温度基本恒定的水温,在一定误差范围内。故Setpoint为出水设定温度(该数据保留1位小数,并乘以10,按照整数形式计算);实际出水温度通过PT100采样,并经过A/D转换相关计算后得到(该数据保留1位小数,并乘以10,按照整数形式计算);执行机构是混水比例调节阀,控制方式是通过固定时间的脉冲形式,令阀向左或向右调节固定的步数,从而调节混水中心的出水温度。

PID调节的代码如下:

#ifndef __Z_UTIL_PID_H
#define __Z_UTIL_PID_H
#include "z_util_pid.h"
#endif
Obj_pid obj_pid;
void init_pid(float sv, float fv)
{
	obj_pid.set_target = sv;
	obj_pid.actual_value = fv;
	obj_pid.err = 0;
	obj_pid.err_next = 0;
	obj_pid.err_last = 0;
	obj_pid.kp = 2;
	obj_pid.ki = 2;
	obj_pid.kd = 0.2;
}
float func_pid_acting(float sv, float fv)
{
	float incr;
	obj_pid.set_target = sv;
	obj_pid.err = obj_pid.set_target - fv;
	incr = obj_pid.kp*(obj_pid.err - obj_pid.err_next) + obj_pid.ki*obj_pid.err + 
		obj_pid.kd*(obj_pid.err - 2*obj_pid.err_next + obj_pid.err_last);
	obj_pid.actual_value += incr;
	obj_pid.err_last = obj_pid.err_next;
	obj_pid.err_next = obj_pid.err;
	return incr;
}

该PID调节方式为增量型的。

在主函数中,如何使用PID的计算结果,控制阀的向左和向右的动作,是我们关心的,以及如何调节PID的系数。控制阀的向左和向右,可以这样:

pred_v = func_pid_acting(C_TARGET, temp);
//mprintf((s16)pred_v);
				
if(pred_v <= -5)
{
	if(step_cur < MIXED_VALVE_DEFAULT_STEP)
	{
		func_turn_right_steps((u8)(-pred_v/5));
		step_cur += (u8)(-pred_v/5);
	}					
}
else if(pred_v >= 5)
{
	if(step_cur > MIXED_VALVE_MIN_STEP)
	{
		func_turn_left_steps((int)pred_v/5);
		step_cur -= (int)pred_v/5;
	}					
}

通过PID计算出的增量值,与系统设计要求的误差做比较来控制向左调阀还是向右调阀。当然阀所在位置是有极限位置的。

关于PID系数的选择,P在PID调节公式中,当I和D均为0时,公式为 obj_pid.kp*(obj_pid.err - obj_pid.err_next),解释为误差的误差,当实际值下降时,该值总为负数;当实际值平稳时,该值总为0;当实际值上升时,该值为正数。

I在PID调节公式中,当P和D均为0时,公式为obj_pid.ki*obj_pid.err,表示了当前的实际值和设定值相差有多远,值越大相差越远,值越小相差越近。

D在PID调节公式中,当P和I均为0时,公式为obj_pid.kd*(obj_pid.err - 2*obj_pid.err_next + obj_pid.err_last), 表示了实际值的变化程度有多剧烈。当测量值稳定不变时,该值总为0;当实际值平稳上升或平稳下降时,该值总为0。当实际值逐渐快速增长时,该值总为正;当实际值逐渐快速减小时,该值总为负。


本文由转载于互联网,如有侵权请联系删除!