0
0
FreertosProgramBeginner · 2 min read

Ladder Logic Program for Traffic Light Control in PLC

A simple ladder logic program for a traffic light uses three outputs for Red, Yellow, and Green lights controlled by timers cycling through states, for example: 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

InputStart traffic light cycle
OutputRed light ON for 10s, Green light ON for 10s, Yellow light ON for 3s, then cycle repeats
InputTraffic light running
OutputLights change in sequence: Red -> Green -> Yellow -> Red continuously
InputEmergency stop activated
OutputAll lights OFF or Red light blinking depending on implementation
🧠

How to Think About It

To design a traffic light ladder logic, think of each light as an output coil that turns ON or OFF. Use timers to control how long each light stays ON. The program cycles through Red, Green, and Yellow states by enabling one output at a time and using timer done bits to switch to the next state.
📐

Algorithm

1
Turn ON Red light and start Timer1 for Red duration
2
When Timer1 finishes, turn OFF Red and turn ON Green light, start Timer2
3
When Timer2 finishes, turn OFF Green and turn ON Yellow light, start Timer3
4
When Timer3 finishes, turn OFF Yellow and turn ON Red light, start Timer1 again
5
Repeat the cycle indefinitely
💻

Code

plc_programming
(* 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;
Output
Red Light ON (After 10 seconds) Green Light ON (After 10 seconds) Yellow Light ON (After 3 seconds) Red Light ON ... (cycle repeats)
🔍

Dry Run

Let's trace the traffic light cycle starting with Red light ON.

1

Initial State

RedLight=TRUE, GreenLight=FALSE, YellowLight=FALSE, TimerRed running

2

Red Timer Done

TimerRed.Q=TRUE after 10s, switch RedLight=FALSE, GreenLight=TRUE

3

Green Timer Running

TimerGreen running, RedLight=FALSE, GreenLight=TRUE

4

Green Timer Done

TimerGreen.Q=TRUE after 10s, switch GreenLight=FALSE, YellowLight=TRUE

5

Yellow Timer Running

TimerYellow running, YellowLight=TRUE

6

Yellow Timer Done

TimerYellow.Q=TRUE after 3s, switch YellowLight=FALSE, RedLight=TRUE

StepRedLightGreenLightYellowLightTimerRed.QTimerGreen.QTimerYellow.Q
1TRUEFALSEFALSEFALSEFALSEFALSE
2FALSETRUEFALSETRUEFALSEFALSE
3FALSETRUEFALSEFALSEFALSEFALSE
4FALSEFALSETRUEFALSETRUEFALSE
5FALSEFALSETRUEFALSEFALSEFALSE
6TRUEFALSEFALSEFALSEFALSETRUE
💡

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

State Machine with Counters
plc_programming
(* 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)));
Simplifies logic by using a single timer and a state counter but requires modulo operation support.
Using Shift Registers
plc_programming
(* 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)));
Uses bit shifting to cycle lights, efficient but less intuitive for beginners.

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.

ApproachTimeSpaceBest For
Multiple TimersO(1)O(1)Clear step-by-step control, easy to understand
State Machine with CounterO(1)O(1)Simpler code with single timer, good for scalable states
Shift RegisterO(1)O(1)Efficient bit manipulation, compact code
💡
Use timers with done bits to control each light duration and switch states smoothly.
⚠️
Forgetting to reset timers or not properly switching outputs causes lights to stay ON simultaneously.