Ladder Logic Program for Traffic Light Control in PLC
TON Timer1 10s; Red ON; Timer1.DN -> Green ON; TON Timer2 10s; Green OFF; Yellow ON; TON Timer3 3s; Yellow OFF; Red ON; repeating in a loop.Examples
How to Think About It
Algorithm
Code
(* Traffic Light Ladder Logic Example *) (* Define timers *) TON TimerRed(IN:=RedTimerStart, PT:=T#10s); TON TimerGreen(IN:=GreenTimerStart, PT:=T#10s); TON TimerYellow(IN:=YellowTimerStart, PT:=T#3s); (* State bits *) VAR RedLight: BOOL := TRUE; GreenLight: BOOL := FALSE; YellowLight: BOOL := FALSE; RedTimerStart: BOOL := TRUE; GreenTimerStart: BOOL := FALSE; YellowTimerStart: BOOL := FALSE; END_VAR (* Logic *) IF RedLight THEN RedTimerStart := TRUE; GreenTimerStart := FALSE; YellowTimerStart := FALSE; IF TimerRed.Q THEN RedLight := FALSE; GreenLight := TRUE; END_IF ELSIF GreenLight THEN RedTimerStart := FALSE; GreenTimerStart := TRUE; YellowTimerStart := FALSE; IF TimerGreen.Q THEN GreenLight := FALSE; YellowLight := TRUE; END_IF ELSIF YellowLight THEN RedTimerStart := FALSE; GreenTimerStart := FALSE; YellowTimerStart := TRUE; IF TimerYellow.Q THEN YellowLight := FALSE; RedLight := TRUE; END_IF END_IF; (* Outputs *) OutputRed := RedLight; OutputGreen := GreenLight; OutputYellow := YellowLight; (* Print current light status *) IF RedLight THEN Print("Red Light ON") ELSIF GreenLight THEN Print("Green Light ON") ELSIF YellowLight THEN Print("Yellow Light ON") END_IF;
Dry Run
Let's trace the traffic light cycle starting with Red light ON.
Initial State
RedLight=TRUE, GreenLight=FALSE, YellowLight=FALSE, TimerRed running
Red Timer Done
TimerRed.Q=TRUE after 10s, switch RedLight=FALSE, GreenLight=TRUE
Green Timer Running
TimerGreen running, RedLight=FALSE, GreenLight=TRUE
Green Timer Done
TimerGreen.Q=TRUE after 10s, switch GreenLight=FALSE, YellowLight=TRUE
Yellow Timer Running
TimerYellow running, YellowLight=TRUE
Yellow Timer Done
TimerYellow.Q=TRUE after 3s, switch YellowLight=FALSE, RedLight=TRUE
| Step | RedLight | GreenLight | YellowLight | TimerRed.Q | TimerGreen.Q | TimerYellow.Q |
|---|---|---|---|---|---|---|
| 1 | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE |
| 2 | FALSE | TRUE | FALSE | TRUE | FALSE | FALSE |
| 3 | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE |
| 4 | FALSE | FALSE | TRUE | FALSE | TRUE | FALSE |
| 5 | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE |
| 6 | TRUE | FALSE | FALSE | FALSE | FALSE | TRUE |
Why This Works
Step 1: Using Timers to Control Light Duration
Each light stays ON for a set time controlled by a timer with TON instruction and its done bit .Q.
Step 2: Switching Lights Based on Timer Completion
When a timer finishes (.Q = TRUE), the program switches the active light to the next one in sequence.
Step 3: Looping the Cycle
After Yellow light timer finishes, the program loops back to Red light, creating a continuous traffic light cycle.
Alternative Approaches
(* Use a counter to cycle states 0=Red,1=Green,2=Yellow *) VAR State: INT := 0; Timer: TON; END_VAR Timer(IN:=TRUE, PT:=T#10s); IF Timer.Q THEN Timer(IN:=FALSE); State := (State + 1) MOD 3; Timer(IN:=TRUE); END_IF OutputRed := (State = 0); OutputGreen := (State = 1); OutputYellow := (State = 2); Print(CONCAT('State: ', INT_TO_STRING(State)));
(* Shift a bit through outputs to represent lights *) VAR Lights: BYTE := 1; (* 001 for Red *) Timer: TON; END_VAR Timer(IN:=TRUE, PT:=T#10s); IF Timer.Q THEN Timer(IN:=FALSE); Lights := (Lights << 1) OR (Lights >> 2); (* rotate bits *) Timer(IN:=TRUE); END_IF OutputRed := (Lights AND 1) <> 0; OutputGreen := (Lights AND 2) <> 0; OutputYellow := (Lights AND 4) <> 0; Print(CONCAT('Lights: ', BYTE_TO_STRING(Lights)));
Complexity: O(1) time, O(1) space
Time Complexity
The program runs in constant time per cycle since it only checks timers and switches outputs without loops over data.
Space Complexity
Uses a fixed number of timers and boolean variables, so space usage is constant.
Which Approach is Fastest?
All approaches run in constant time; using a state machine or shift register can simplify code but does not affect speed significantly.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Multiple Timers | O(1) | O(1) | Clear step-by-step control, easy to understand |
| State Machine with Counter | O(1) | O(1) | Simpler code with single timer, good for scalable states |
| Shift Register | O(1) | O(1) | Efficient bit manipulation, compact code |