FUNCTION_BLOCK PID_control VAR_INPUT ProcesVal :INT; (*proceswaarde*) SetVal :LREAL; (*wenswaarde*) Auto :BOOL; (*als true dan automatisch regelen*) Direct :BOOL; (*als true dan direct acting, oftewel: verwarmen of koelen *) TimeBase :LREAL; (*moet 1000 of groter zijn*) Gain :LREAL; (* Kp *) ResetRate :LREAL; (* Tr *) Derivative :LREAL; (* Td *) END_VAR VAR_OUTPUT ControllerOut :LREAL; (* output *) END_VAR VAR testbit : BOOL; TON_pulstijd : TON; TON_pauzetijd : TON; Puls : R_TRIG; Err : LREAL; ErrLast : LREAL; ErrlastLast : LREAL; ControllerOutTemp : LREAL; END_VAR testbit := TRUE; (* cyclustijd PID regeling*) TON_pulstijd (in := NOT ton_pauzetijd.Q, PT := LREAL_TO_TIME(Timebase - 500)); TON_pauzetijd (in := ton_pulstijd.Q, PT := t#500ms); Puls (clk := TON_pulstijd.Q); (* PID regeling*) IF Puls.Q THEN IF (*---------------------------------------------------------------------auto mode*) auto THEN Err := SetVal - ProcesVal; IF (*------------------------direct mode*) NOT direct THEN Err := 0 - Err; END_IF (*-----------------------------------------*) (*de PID zelf: *) ControllerOutTemp := ControllerOut + (Gain * ( Err - ErrLast + (ResetRate * Err) + (Derivative * ( Err -(ErrLast *2) + errlastLast)))); ControllerOut := ControllerOutTemp; (*alleen voor controle, verder is het niet nodig dit via een kladvariabele te doen*) ErrLastLast := ErrLast; ErrLast := Err; ELSE ControllerOut := 0; ErrLastLast := Err; ErrLast := Err; END_IF (*-------------------------------------------------------------------------------*) END_IF IF ControllerOut > 100 AND auto THEN ControllerOut := 100; END_IF IF ControllerOut < 0 OR NOT auto THEN ControllerOut := 0; END_IF