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