温度PID控制

介绍

采用PID控制方法,我先采用位置式输出方式,公式原型:u(t) = kp * e(t) + ki * [e(1) + e(2) +
…+ e(t)] + kd * [e(t) -
e(t-1)],这里先做基本的PID算法,达到控制目标后再来优化算法提高恒温精度,考虑到实验温度过高实验时间会过长,所以我先定目标控制温度为110度,等控制好了再看其他温度会达到多少精度,为了提高加热速度提前20度开始PID控温

下面是调节参数的过程及数据:
参照网上一些方法,先确定Kp,即令Ki,Kd=0,只用比例调节,得到一个稳定的越接近控制目标的震荡参数,然后根据这个Kp和震荡周期来计算Ti,Td
接下来根据下面典型参数计算表:
Ziegler-Nichols参数

控制器 Kp Ti Td
P 0.50Kc / /
PD 0.65
Kc / 0.12Pc
PI 0.45
Kc 0.85Pc /
PID 0.65
Kc 0.5Pc 0.12Pc

我先做PD实验: 根据临界增益KC=9.2
震荡周期Pc=225秒,计算出Kp=5.98,Td=27秒,公式Kd=Kp*(Td/T)=5.9827/5=32.392
Ki = Kp
(T/Ti)

##PID参数整定流程
第3次:Kp=8。5,这次的测试时间比较长,因为比较接近稳定震荡了,图片如下:
温度PID控制_第1张图片

现在整理了一下Kp=9和Kp=9.3的震荡周期,图片分析如下
温度PID控制_第2张图片

从数据看震荡周期基本都是48~43个点,每个点是5秒,所以震荡周期为225秒

typedef struct pid_t
{
		int et_sum;
		int et_before;          //此次的误差
		int et_now;             //上次的误差
		float kp;
		float ki;
		float kd;
}tempctrl_pid;
L_Non_temp_pid.kp = 10.27;
	L_Non_temp_pid.ki = 0;
	L_Non_temp_pid.kd = 27.11;
	
	L_Non_temp_pid.et_before = L_Non_temp_pid.et_now;
	L_Non_temp_pid.et_now = nowAD - Temp_AD;
	
	if(L_Non_temp_pid.et_now > 0 && L_Non_temp_pid.et_now < 6)                   //采用积分分离法,当误差范围在0-6之间时才使用积分消除稳态误差
	{
		L_Non_temp_pid.ki = 1;
	}
	else
	{
		L_Non_temp_pid.et_sum = 0;
		L_Non_temp_pid.ki = 0;
	}
	
	L_Non_temp_pid.et_sum = L_Non_temp_pid.et_sum + L_Non_temp_pid.et_now;
	
	Percentage = (L_Non_temp_pid.kp * L_Non_temp_pid.et_now) \
								+ (L_Non_temp_pid.ki * L_Non_temp_pid.et_sum)\
								+ (L_Non_temp_pid.kd * (L_Non_temp_pid.et_now - L_Non_temp_pid.et_before));
	
	if(Percentage > 100)
	{
		Percentage = 100;
	}
	else if(Percentage < 0)
	{
		Percentage = 0;
	}
	
	if(Alarm6 || Alarm7 || Alarm8 || Alarm9)
	{
		Percentage = 0;
		HTBD_PWM_OFF;
		BD_ON = 0;
	}
	//printf("%d %.1f %d\r\n", nowAD, get_boardTemp(HTBD_AD0), Percentage);
	if(CurPercentage != Percentage)
	{
			ChangeFlag = 1;
	}

注:借鉴某位大佬的调节过程参考链接**https://www.amobbs.com/thread-936512-1-1.html**

你可能感兴趣的:(单片机)