Edouard@400: (****************************************************************
Edouard@400: 
Edouard@400:               RTC - Real-time clock
Edouard@400: 
Edouard@400: Q is a copy of IN.
Edouard@400: 
Edouard@400: When IN = FALSE, CDT is the current date and time as set by the
Edouard@400: PLC driver.
Edouard@400: 
Edouard@400: When IN changes from FALSE to TRUE, PDT is stored. As long as IN is
Edouard@400: TRUE, CDT is equal to PDT + the amount of time since PDT was loaded.
Edouard@400: 
Edouard@400: ****************************************************************)
Edouard@400: 
Edouard@400: FUNCTION_BLOCK RTC
Edouard@400:    VAR_INPUT
Edouard@400:      IN : BOOL;                  (* 0 - current time, 1 - load time from 
Edouard@400: PDT *)
Edouard@400:      PDT : DT;                   (* Preset datetime *)
Edouard@400:    END_VAR
Edouard@400:    VAR_OUTPUT
Edouard@400:      Q : BOOL := FALSE;          (* Copy of IN *)
Edouard@400:      CDT : DT;                   (* Datetime, current or relative to PDT *)
Edouard@400:    END_VAR
Edouard@400: 
Edouard@400:    VAR
Edouard@400:      PREV_IN : BOOL := FALSE;
Edouard@400:      OFFSET : TIME;
Edouard@400:      CURRENT_TIME : DT;
Edouard@400:    END_VAR
Edouard@400: 
Edouard@400:    {__SET_VAR(data__->,CURRENT_TIME,__CURRENT_TIME)}
Edouard@400: 
Edouard@400:    IF IN
Edouard@400:    THEN
Edouard@400:      IF NOT PREV_IN
Edouard@400:      THEN
Edouard@400:          OFFSET := PDT - CURRENT_TIME;
Edouard@400:      END_IF;
Edouard@400: 
Edouard@400:      (* PDT + time since PDT was loaded *)
Edouard@400:      CDT := CURRENT_TIME + OFFSET;
Edouard@400:    ELSE
Edouard@400:      CDT := CURRENT_TIME;
Edouard@400:    END_IF;
Edouard@400: 
Edouard@400:    Q := IN;
Edouard@400:    PREV_IN := IN;
Edouard@400: 
Edouard@400: END_FUNCTION_BLOCK
Edouard@400: