FUNCTION_BLOCK FB_PIDR

VAR_INPUT
    AUTO : BOOL; (* 0-manual,1-automatic *)
    PV : REAL; (* Process variable,0-100 percent *)
    SP : UINT; (* Set Point,0-100 percent *)
    X0 : UINT; (* Manual Output Setting,0-100 percent *)
    KP : REAL; (* Proportionality Constant *)
    DT : TIME := t#1s; (* Sampling Period *)
    TR : TIME; (* Reset Time *)
    TD : TIME; (* Derivative Time Constant *)
END_VAR
VAR_OUTPUT
    XOUT : REAL; (* Manipulated Variable,0-100 percent *)
END_VAR
VAR
    WASAUTO : BOOL; 
      (* State of AUTO input at previous REQ event *)
    WASLIMITED : BOOL;
      (* TRUE if XOUT was limited to max (100)
         or min (0) value at previous REQ event *)
    ERROR : REAL; (* Current value of (PV-SP) *)
    ITERM : REAL; (* Integral Term *)
    DTERM : REAL; (* Derivative Term *)
    X1 : REAL; (* PV value at previous REQ *)
    X2 : REAL; (* PV value at second previous REQ *)
    X3 : REAL; (* PV value at third previous REQ *)
END_VAR

Upon the occurrence of an event at the REQ input, an instance of this function block type performs the REQ algorithm listed below, followed by an event at the CNF output.

The REQ algorithm implements the reverse-acting PID (Proportional+Integral+Derivative) control law

XOUT = -(Kp*e + ITERM/TR + TD*DTERM),
where
e = PV - SP, ITERM = ∫edt, and ETERM = de/dt.

The manipulated variable XOUT, the process variable PV and the proportionality constant KP are of type REAL , as are the internal terms ERROR , ITERM and ETERM . The reset time TR and derivative time TD are of type TIME . The set point SP and initial output value X0 are of type UINT since they are considered to be manually set, e.g., from an instance of the FACEPLATE type.

The inputs PV,SP and X0 are assumed to be limited to the range 0 to 100 per cent of full scale, and the output XOUT is limited to the same range.

Provision is made for anti-reset windup and bumpless transer from MANUAL to AUTO mode through appropriate initialization of the internal ITERM and ETERM variables.

ALGORITHM REQ IN ST :
ERROR:=PV-SP;
IF AUTO THEN
 IF WASAUTO AND NOT WASLIMITED THEN
   ITERM:=ITERM+ERROR*DT/TR;
   DTERM:=(3*(PV-X3)+X1-X2)*TD/DT/10;
 ELSE
   ITERM:=-KP*ERROR-XOUT;
   DTERM:=0;
 END_IF;
 XOUT:=-KP*ERROR-ITERM-DTERM;
ELSE XOUT:=X0;
END_IF
X3:=X2;
X2:=X1;
X1:=PV;
WASLIMITED := FALSE;
IF XOUT<0 THEN
 XOUT:=0;
 WASLIMITED := TRUE;
ELSIF XOUT>100 THEN
 XOUT:=100;
 WASLIMITED := TRUE;
END_IF;
WASAUTO:=AUTO;
END_ALGORITHM