PID的无扰动切换,简而言之就是手动调节切换到自动调节时,自动调节积分项从当前手动输出开始,就是将当前输出给积分初始化。
手上有个倍福PLC项目,用变频风机调节管道气体温度,我在调用系统PID库指令时,发现积分项被定义成静态变量,从库指令外部根本没法对积分项操作,如此简单的需求,居然不能实现,只好用自己动手写一段PID程序:
1,先定义PID接口
FUNCTION_BLOCK PID
VAR_INPUT
Man_Auto:BOOL; (*手动自动切换,手动:=1,自动:=0*)
Man_Value:REAL; (*手动给定输入值*)
PVn : REAL; (*过程值输入,或反馈值、测量值*)
SPn :REAL; (*自动调节时的设定值、目标值*)
Kc :REAL; (*P参数0.01-99.99*)
Ts :REAL; (*PID的扫描执行周期,单位秒;比如100ms执行一次,则为0.1s*)
Ti :REAL; (*积分时间,单位秒;0.1-99.99*,不允许为0,可在外部限制*)
Td :REAL; (*微分时间,单位秒;0.01-99.99*)
END_VAR
VAR_OUTPUT
Mn :REAL; (*PID输出*)
END_VAR
VAR
ManAutoLast:BOOL; (*手动自动切换的上次状态*)
AutoEdge:BOOL; (*自动状态上升沿*)
Mx:REAL; (*PID计算的积分项*)
EVn:REAL; (*本次周期目标值与过程值的偏差,error value的首字母*)
EVn0:REAL; (*上一次计算周期的偏差值*)
MPn:REAL; (*PID计算的比例项*)
MDn:REAL; (*PID计算的微分项*)
END_VAR
(********)
2,PID程序:
AutoEdge:= ManAutoLast AND (NOT Man_Auto ); (***手动转自动上升沿**)
ManAutoLast:=Man_Auto;
IF AutoEdge THEN
Mx:= LIMIT(20.0,Man_Value,60.0); (*自动调节时,积分初始化*)
END_IF
IF Man_Auto THEN
Mn:= LIMIT(20.0,Man_Value, 60.0); (*手动调节时给定值*)
ELSE
EVn:=(SPn - PVn ) ; (*自动调节PID计算*)
MPn := LIMIT(-60.0,(Kc * EVn),60.0) ; (*设置比例项的边界*)
IF Mn>0.0 AND Mn<100.0 THEN (*为防止积分饱和,设置冻结积分计算的条件*)
Mx:=LIMIT(18.0,( Kc*Ts/Ti*EVn+Mx), 100.0); (*积分项计算公式,并设置边界*)
END_IF
MDn := Kc * Td / Ts * (EVn - EVn0);
Mn:=LIMIT(18.0,(MPn+Mx+MDn),60.0); (*PID计算:= 比例项+积分项+微分项;积分项是主干*)
EVn0:=EVn;
END_IF