Learn PLCs free
Programming Examples9 min read1,602 words

Traffic Light PLC Programming: State Machine Example

Build a six-state traffic-light PLC program with timers, all-red clearance, safe transitions, Structured Text, an I/O map and a reproducible test matrix.

PPI
PLC Programming IO Editorial Team
Sourced guidance with documented review and correction standards

How do you program a traffic light with a PLC?

Model each legal signal phase as one state, attach a timer to that state, and permit only a defined transition to the next state. For a two-road training intersection, use six states: north–south green, north–south yellow, all red, east–west green, east–west yellow and all red. Derive all lamp outputs from the active state and add a final conflict check that forces every direction red if incompatible greens are ever requested.

This pattern teaches sequence control, timers, state machines, interlocks and fault recovery. It is an educational simulation, not a deployable public-road signal controller.

Browser PLC traffic-light training scenario showing a two-road intersection, signal lamps, ladder-logic workspace and live sequence state
A simulation makes the signal state, timer and output consequences visible without connecting real traffic-control hardware.

Safety boundary: training logic is not a traffic controller

Public-road signal timing and controller operation are governed by applicable national, state and local requirements. The US Federal Highway Administration’s Traffic Signal Timing Manual explains that timing should be developed with engineering judgment and applicable policy. The Manual on Uniform Traffic Control Devices defines requirements for traffic-control devices.

This example deliberately excludes:

  • certified conflict-monitor hardware;
  • redundant output monitoring;
  • pedestrian timing calculations;
  • local yellow-change and red-clearance requirements;
  • emergency and railroad preemption;
  • flash transfer, cabinet monitoring and communications;
  • accessibility and traffic-engineering approval.

Never connect this tutorial to roadside signals. Use a simulator or a low-voltage training rig with isolated indicator lamps.

Requirements for the training intersection

The example controls two non-overlapping movements:

  • North–south (NS)
  • East–west (EW)

Each movement has red, yellow and green outputs. The simplified sequence is:

State NS lamps EW lamps Example training time Exit condition
NS_GREEN Green Red 10 s State timer done
NS_YELLOW Yellow Red 3 s State timer done
ALL_RED_1 Red Red 2 s State timer done
EW_GREEN Red Green 10 s State timer done
EW_YELLOW Red Yellow 3 s State timer done
ALL_RED_2 Red Red 2 s State timer done

These times are arbitrary simulation values, not recommended road timings. FHWA notes that phase timing includes green, yellow change and red-clearance intervals, and that applicable policies and site geometry matter.

PLC state-sequence diagram illustrating legal transitions, timed dwell states and a fault path for a traffic-light training program
State logic prevents “creative” transitions: every normal phase follows one defined successor, while any invalid state goes to the fault response.

I/O map

Use readable tags rather than hard-coded addresses:

Tag Type Direction Purpose
RunRequest BOOL Input Starts automatic cycling
StopRequest BOOL Input Requests the stopped/all-red state
ResetRequest BOOL Input Acknowledges a cleared training fault
NsRed, NsYellow, NsGreen BOOL Output North–south lamps
EwRed, EwYellow, EwGreen BOOL Output East–west lamps
State ENUM/INT Internal Active legal phase
NextState ENUM/INT Internal Calculated successor state
StateTimer TON Internal Dwell time for active state
ConflictFault BOOL Internal Incompatible green request detected

On a training rig, use momentary pushbuttons for start, stop and reset. Treat an emergency stop as a separate safety function; do not label an ordinary PLC stop input “E-stop.”

Program architecture

Keep the program in five layers:

  1. Input normalization — debounce buttons and establish operating request.
  2. Transition logic — calculate the next state from the current state and timer.
  3. State memory — update the state once per scan.
  4. Output decode — derive lamps from the state.
  5. Final conflict guard — force all red and latch a fault if conflicting greens are requested.

This separation makes the sequence testable. A timer cannot directly energize a lamp in one rung while a second rung changes the state unexpectedly.

PLC timer-driven state-machine architecture separating state memory, dwell timer, transition conditions, decoded outputs and fault handling
The timer reports that a state’s dwell has elapsed; the transition layer decides what state is allowed next.

Complete Structured Text example

The code below uses IEC-style pseudocode. Adapt enum syntax and timer calling conventions to your target PLC.

TYPE TrafficState :
(
    STOPPED,
    NS_GREEN,
    NS_YELLOW,
    ALL_RED_1,
    EW_GREEN,
    EW_YELLOW,
    ALL_RED_2,
    FAULTED
);
END_TYPE

VAR
    State         : TrafficState := STOPPED;
    NextState     : TrafficState := STOPPED;
    StateTimer    : TON;
    StateTime     : TIME;
    ConflictFault : BOOL;
END_VAR

(* 1. Select the dwell for the current state *)
CASE State OF
    NS_GREEN, EW_GREEN:   StateTime := T#10s;
    NS_YELLOW, EW_YELLOW: StateTime := T#3s;
    ALL_RED_1, ALL_RED_2: StateTime := T#2s;
    ELSE                  StateTime := T#0s;
END_CASE;

StateTimer(
    IN := RunRequest
          AND NOT StopRequest
          AND (State <> STOPPED)
          AND (State <> FAULTED),
    PT := StateTime
);

(* 2. Calculate one legal successor *)
NextState := State;

IF StopRequest THEN
    NextState := STOPPED;
ELSIF ConflictFault THEN
    NextState := FAULTED;
ELSE
    CASE State OF
        STOPPED:
            IF RunRequest THEN NextState := ALL_RED_1; END_IF;
        NS_GREEN:
            IF StateTimer.Q THEN NextState := NS_YELLOW; END_IF;
        NS_YELLOW:
            IF StateTimer.Q THEN NextState := ALL_RED_1; END_IF;
        ALL_RED_1:
            IF StateTimer.Q THEN NextState := EW_GREEN; END_IF;
        EW_GREEN:
            IF StateTimer.Q THEN NextState := EW_YELLOW; END_IF;
        EW_YELLOW:
            IF StateTimer.Q THEN NextState := ALL_RED_2; END_IF;
        ALL_RED_2:
            IF StateTimer.Q THEN NextState := NS_GREEN; END_IF;
        FAULTED:
            IF ResetRequest AND NOT ConflictFault THEN
                NextState := STOPPED;
            END_IF;
        ELSE
            NextState := FAULTED;
    END_CASE;
END_IF;

(* 3. Change state; the timer must restart for a new state *)
IF NextState <> State THEN
    State := NextState;
    StateTimer(IN := FALSE, PT := StateTime);
END_IF;

(* 4. Safe defaults, then decode the active state *)
NsRed := TRUE;  NsYellow := FALSE; NsGreen := FALSE;
EwRed := TRUE;  EwYellow := FALSE; EwGreen := FALSE;

CASE State OF
    NS_GREEN:
        NsRed := FALSE; NsGreen := TRUE;
    NS_YELLOW:
        NsRed := FALSE; NsYellow := TRUE;
    EW_GREEN:
        EwRed := FALSE; EwGreen := TRUE;
    EW_YELLOW:
        EwRed := FALSE; EwYellow := TRUE;
END_CASE;

(* 5. Independent conflict guard *)
ConflictFault := NsGreen AND EwGreen;

IF ConflictFault THEN
    NsRed := TRUE;  NsYellow := FALSE; NsGreen := FALSE;
    EwRed := TRUE;  EwYellow := FALSE; EwGreen := FALSE;
END_IF;

Important timer detail

Many PLC TON implementations retain Q for the rest of the scan in which their input is removed. Reset the timer explicitly when the state changes, or use a state-entry pulse and one timer instance per state. Confirm behavior in your target runtime rather than assuming every dialect executes the same way.

Ladder-logic implementation pattern

Use one state bit or integer state register. A clean ladder project has:

  • one rung/network for the timer associated with the active state;
  • one transition rung for each legal edge;
  • one first-scan/default-state rung;
  • output rungs that decode state;
  • a final conflict/fault rung;
  • explicit stop and reset behavior.

Avoid cascading TON.DN bits through lamp output rungs. That design becomes difficult to pause, reset and test because timing, transitions and outputs are coupled.

PLC scan-cycle diagram showing input sampling, traffic-state transition evaluation, lamp-output decoding and physical output update
Understanding the scan explains why a state transition and its decoded lamp outputs may not become physical until the output-update phase.

See PLC scan cycle explained, TON timer programming and the ladder-logic tutorial.

Optional vehicle demand

After the fixed-time sequence passes, add demand without compromising the clearance states:

(* Minimum NS green has elapsed.
   Extend while NS demand exists, but not beyond MaxGreen. *)
LeaveNsGreen :=
    MinGreenTimer.Q
    AND (
        EwVehicleDemand
        OR MaxGreenTimer.Q
    );

Keep minimum green, maximum green and clearance timing separate. A missing detector must have a documented fallback. Do not let a demand input jump directly from one green to the conflicting green.

Stop, power-up and recovery behavior

Define these before programming:

  • On power-up, enter STOPPED with all red.
  • Start request enters an all-red state before the first green.
  • Stop request forces all red.
  • An invalid state enters FAULTED.
  • Reset returns to STOPPED, not directly to green.
  • No automatic restart occurs merely because power or an input returns.

For an educational lamp panel, these choices are conservative and easy to verify.

Structured Text state-machine review showing explicit normal states, fault entry, stopped state and reset path for a sequential PLC program
A complete state model includes power-up, stop, fault and recovery—not only the happy-path sequence.

Reproducible acceptance test

Run the following on a simulator or isolated trainer. Record actual state, timer elapsed time and six output bits for every step.

ID Test Expected result
T01 Power up with RunRequest = FALSE STOPPED; both red lamps on
T02 Apply run request Enters all red before any green
T03 Complete a full cycle States occur in the documented order
T04 Observe every normal state No state requests both greens
T05 Stop during each green/yellow Both directions become red
T06 Force an invalid state in the simulator Program enters FAULTED; both red
T07 Reset while conflict remains Reset is rejected
T08 Clear conflict then reset Returns to STOPPED, not green
T09 Remove and restore run request No state is skipped
T10 Cycle power with run request true Follows documented restart policy

Invariants to monitor

These Boolean assertions should always be true:

NOT (NsGreen AND EwGreen)
NOT (NsGreen AND NsYellow)
NOT (EwGreen AND EwYellow)
NsRed OR EwRed
State is one of the declared enum values

On a real safety-critical application, software assertions are not a substitute for independent certified protection. Here they make the training exercise deterministic.

PLC training lab validating a traffic-light sequence against a written state table, timer values and injected fault tests
The test matrix turns a familiar demonstration into evidence: state order, timing, conflict prevention and recovery are all observable.

Practise this exact scenario

PLC Simulation Software includes a browser-based traffic-light scenario for practising timer, state and output logic without roadside equipment.

Ownership disclosure: PLC Programming and PLC Simulation Software are operated by the same publisher. The product is a training simulator, not an approved traffic-signal controller.

Open the traffic-light PLC simulator and reproduce T01–T10. Save screenshots of the state sequence and fault response as portfolio evidence.

Key takeaways

  • One legal phase should equal one explicit state.
  • Timers control dwell; transition logic controls allowed movement.
  • Decode all outputs from state with safe defaults.
  • Add an independent incompatible-output assertion.
  • Test startup, stop, invalid state and reset—not only normal cycling.
  • Treat all example times as simulation values.
  • Use the applicable traffic-engineering standards and approved hardware for any real intersection.
#TrafficLight Control#PLCExamples#TimingSequences#StateMachine#PLCTraining
Share this article:

Related Articles