(* Timers: TON vs TOF vs RTO — Control Panel scene X1 = Start (N.O.) X2 = Stop (N.C., TRUE when not pressed) X3 = Jog button, used here as Service Reset Y1 = Motor run IEC 61131-3 has TON and TOF but no retentive timer, so the run-time total is built from a TON that times each run plus a banked total. *) VAR RunRequest : BOOL; StartDelay : TON; // 2 s on-delay before the motor starts RunOn : TOF; // 5 s run-on after the run request drops RunTimer : TON; // times the current run only Banked : TIME; // run time from every earlier run RunTotal : TIME; // retentive total = banked + current run ServiceDue : BOOL; END_VAR (* Run request — Start seals in; Stop or Service Due drops it *) RunRequest := (X1 OR RunRequest) AND X2 AND NOT ServiceDue; (* TON — the run request must be ON for 2 s before the motor starts *) StartDelay(IN := RunRequest, PT := T#2s); (* TOF — Q turns ON with the start delay and holds for 5 s after it drops *) RunOn(IN := StartDelay.Q, PT := T#5s); Y1 := RunOn.Q; (* Retentive total — while running, add this run to the bank; when stopped, the total is kept in Banked *) RunTimer(IN := Y1 AND NOT X3, PT := T#24h); IF Y1 THEN RunTotal := Banked + RunTimer.ET; ELSE Banked := RunTotal; END_IF; (* Service reset — X3 clears the total, like a RES on an RTO *) IF X3 THEN Banked := T#0s; RunTotal := T#0s; END_IF; ServiceDue := RunTotal >= T#20s;