The handful of building blocks every real machine leans on: a timer that waits, a state machine that decides, and the IEC languages you'll write them in. Let's make them tick.
A TON waits. Hold its input IN true and its elapsed time ET climbs toward the preset PT; when it gets there, the output Q snaps true. Let go and it resets. Press and hold the button.
tmr : TON; // call it every cycle tmr(IN := btnHeld, PT := T#3s); lampOn := tmr.Q; elapsed := tmr.ET;
π‘ TOF delays the turn-off; TP fires a fixed-length pulse. Same shape, different waiting game.
A machine should always be in exactly one known state. A CASE on a state variable is the cleanest way to guarantee that. Step this little start/run/stop cycle.
CASE state OF 0: // IDLE IF startCmd THEN state := 1; END_IF; 1: // STARTING motor := TRUE; state := 2; 2: // RUNNING IF stopCmd THEN state := 3; END_IF; 3: // STOPPING motor := FALSE; state := 0; END_CASE;
A TON with PT := T#3s has had IN true for 1.2 s. What is Q?