恭喜,你发布的帖子
发布于 2020-09-24 09:49:17
33楼
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
楼主, 我有另外一个思路。 可以探讨一下。
不用另外实现一个PID,手动到自动切换时, 完全可以将Pid_out叠加一个衰减项, 让PID逐渐接管。
衰减项可以用一节惯性滤波来实现。时间常数根据负载状况酌情设定。
而且, 你这理想微分环节, 虽然做了限幅处理,但是对阶跃响应只能响应一个周期, 我认为应该实现串联一个小的惯性环节比较好使,搞成使用微分环节。传递函数: K.Td*s/(1 + Ts), 实际上, 就是对你说上述的微分项进行惯性滤波。通过比例系数和惯性时间常数的配合, 可以保证微分不过度跳跃,还可以持续若干周期。
请填写推广理由:
分享
只看
楼主