etisserant@0:  FUNCTION_BLOCK PID
etisserant@0:    VAR_INPUT
etisserant@0:      AUTO : BOOL ;        (* 0 - manual , 1 - automatic *)
etisserant@0:      PV : REAL ;          (* Process variable *)
etisserant@0:      SP : REAL ;          (* Set point *)
etisserant@0:      X0 : REAL ;          (* Manual output adjustment - *)
etisserant@0:                           (* Typically from transfer station *)
etisserant@0:      KP : REAL ;          (* Proportionality constant *)
etisserant@0:      TR : REAL ;          (* Reset time *)
etisserant@0:      TD : REAL ;          (* Derivative time constant *)
etisserant@0:      CYCLE : TIME ;       (* Sampling period *)
etisserant@0:    END_VAR
etisserant@0:    VAR_OUTPUT XOUT : REAL; END_VAR
etisserant@0:    VAR ERROR : REAL ;        (* PV - SP *)
etisserant@0:        ITERM : INTEGRAL ;    (* FB for integral term  *)
etisserant@0:        DTERM : DERIVATIVE ;  (* FB for derivative term *)
etisserant@0:    END_VAR
etisserant@0:    ERROR := PV - SP ;
etisserant@0:    (*** Adjust ITERM so that XOUT := X0 when AUTO = 0 ***)
etisserant@0:    ITERM (RUN := AUTO, R1 := NOT AUTO, XIN := ERROR,
etisserant@0:           X0 := TR * (X0 - ERROR), CYCLE := CYCLE) ;
etisserant@0:    DTERM (RUN := AUTO, XIN := ERROR, CYCLE := CYCLE) ;
etisserant@0:    XOUT := KP * (ERROR + ITERM.XOUT/TR + DTERM.XOUT*TD) ;
etisserant@0:  END_FUNCTION_BLOCK
etisserant@0: