exercises · South Africa
PLC traffic light program in ladder logic
Write a PLC traffic light program with three chained timers: state bits, ladder rungs, a structured text version, and the timing bugs you must test for.
Difficulty: beginner · 20–40 minutes
This is a build-along exercise, not a reading page. You get a short job card of the kind a contractor actually receives, an I/O table to wire against, and a worked solution to check yourself with once your own version runs — plus the test sequence that proves it, because a program you haven't tried to break is a program you haven't tested. Sketch first, build second, test third. Same order as on site.
Open the simulator and build along →The job card
Job card: the access road into a quarry weighbridge is single-lane for 80 metres, and the portable robot that controlled it was stolen over the weekend. Stores has a small PLC and three 24 V LED lamp heads. Management wants one signal face running a fixed cycle on the plant side while the contractor's flagman covers the other end: red for 12 seconds, green for 10, amber for 3, repeating whenever the auto selector on the panel is on. On power-up or when the selector is switched on, the sequence must start at red — never green.
Read it the way a foreman hands it to you. Every requirement on that card is a test case: when you think the program is done, walk the card line by line and force each condition in the watch table. Any line without a matching test you actually ran means you're not done yet. That habit — card in one hand, watch table in the other — is what separates a programmer who commissions clean from one who gets the call-back at month end.
I/O assignment
Wire your simulator project to this table exactly. Half the value of an exercise like this is tag discipline: name the points the same way the table does and the solution steps further down will read straight onto your rungs without translation.
| Tag | Type | Address | Purpose |
|---|---|---|---|
AutoOn | DI | %I0.0 | Panel selector switch, maintained. TRUE runs the light sequence; FALSE blanks all lamps. |
RedLamp | DO | %Q0.0 | Red lamp head, 24 V DC LED, 12-second phase. |
GreenLamp | DO | %Q0.1 | Green lamp head, 24 V DC LED, 10-second phase. |
AmberLamp | DO | %Q0.2 | Amber lamp head, 24 V DC LED, 3-second phase before the return to red. |
A note on the Type column: DI is a digital input, DO a digital output, AI and AO are analogue in and out, and M is an internal memory bit that never leaves the CPU. The addresses use IEC notation (%I, %Q, %M). If your head is in Allen-Bradley land, map %I0.0 to I:0/0 and carry on — the logic doesn't change, only the spelling of the addresses.
Think before you build
Don't open the ladder editor yet. The notes below are the design decisions that determine whether your program works first time or fights you for an hour. Read them, then sketch the rung shapes on paper. Pencil and the back of a delivery note is fine — most working programs start exactly there.
- Drive each lamp from a state bit, not directly from a timer done bit. One step number (0 = red, 1 = green, 2 = amber) with one timer per transition keeps the sequence readable and makes adding a fourth state trivial later.
- Exactly one lamp may be on at any instant. Deriving each lamp from a comparison on the same step variable guarantees this; three independent latches do not, and the first time two latches overlap you have green and red showing together on a single-lane road.
- Decide the power-up state deliberately. An uninitialised step variable could be anything after a power cycle; initialise it to the red step on first scan so the fail state is the safe state.
Step-by-step solution
Build one rung at a time and test after every rung. Never write the whole program and then test the lot — when five rungs go in untested and the machine misbehaves, you're debugging five suspects instead of one. The steps below follow that order. In the pseudo-rungs, ] [ is a normally-open examine, ]/[ is normally-closed, and ( ) is the output coil.
Rung 1-3: decode the step into lamps
Hold the current phase in an integer Step. Three compare rungs decode it: Step equal 0 drives RedLamp, 1 drives GreenLamp, 2 drives AmberLamp, each ANDed with AutoOn so the selector blanks everything. Because each lamp comes from one comparison, two lamps can never be on together.
// Rung 1: AutoOn AND (Step = 0) ──( )RedLamp
// Rung 2: AutoOn AND (Step = 1) ──( )GreenLamp
// Rung 3: AutoOn AND (Step = 2) ──( )AmberLamp
Rung 4: pick the phase time
Use MOVE instructions gated on the step comparisons to load a StepTime variable: T#12s when Step is 0, T#10s for 1, T#3s for 2. One timer then serves all three phases instead of three separate TONs holding three copies of nearly identical logic.
// (Step = 0) ── MOVE T#12s -> StepTime
// (Step = 1) ── MOVE T#10s -> StepTime
// (Step = 2) ── MOVE T#3s -> StepTime
Rung 5: the phase timer and the advance
A single TON runs whenever AutoOn is true and its own done bit is false — the done bit feeding back into the IN leg resets the timer for one scan each time it completes, which is the standard self-resetting cycle timer. On the done bit, add 1 to Step and wrap back to 0 after 2.
// Rung 5: AutoOn AND NOT tPhase.Q ──[TON tPhase, PT := StepTime]
// Rung 6: tPhase.Q ── ADD Step,1 -> Step; IF Step > 2 THEN Step := 0
Rung 7: force red on startup
On the PLC first-scan bit, or on the rising edge of AutoOn, move 0 into Step. Without this rung the light resumes wherever it was before the power cut, and a 9-second-old green phase coming back as green is exactly the wrong surprise on a single-lane road.
Test the full cycle with a stopwatch
Run it in the simulator and time a complete cycle: it must come to 25 seconds, red-green-amber, with no flicker at the transitions. Then toggle AutoOn off mid-green and back on — the sequence must restart at red, not resume at green. Finally watch one full transition in slow motion or single-scan mode to confirm no scan shows two lamps.
The structured text version
The same logic in IEC 61131-3 structured text — each output written as a boolean equation you can read aloud.
(* Traffic light sequence, IEC 61131-3 ST *)
rAuto(CLK := AutoOn); (* R_TRIG: restart at red when switched on *)
IF FirstScan OR rAuto.Q THEN Step := 0; END_IF;
CASE Step OF
0: StepTime := T#12s;
1: StepTime := T#10s;
2: StepTime := T#3s;
END_CASE;
tPhase(IN := AutoOn AND NOT tPhase.Q, PT := StepTime);
IF tPhase.Q THEN
Step := (Step + 1) MOD 3;
END_IF;
RedLamp := AutoOn AND (Step = 0);
GreenLamp := AutoOn AND (Step = 1);
AmberLamp := AutoOn AND (Step = 2);
Ladder wins this argument when an electrician has to fault-find your program at 02:00 with a multimeter mindset — the rung looks like the circuit diagram it replaced, and that familiarity is worth real money on a breakdown. ST starts winning when the pattern repeats: ten pumps with the same interlock shape is one ST function called ten times, where ladder hands you ten near-identical rungs to keep in sync by hand forever. Learn both. Build the exercise in ladder first, then write the ST version and confirm the two behave identically in the simulator. That translation skill — same logic, two languages — is exactly what technical interviews and commissioning work both test.
Common mistakes
Every mistake below comes from a real program: either one of ours from years back, or one we were called in to fix. Check your build against the list before you call the exercise done.
- Chaining three free-running TONs off each other's done bits without a reset path. The chain runs the first cycle perfectly and then jams, because the first timer's done bit never drops to release the others.
- Driving lamps from latched coils set in one phase and reset in another. Miss one reset rung and two lamps show at once — the comparison-decode approach makes that state impossible by construction.
- Forgetting the first-scan initialisation. The step variable holds its last retentive value through a power cut, so the light wakes up mid-cycle in whatever phase the load-shedding caught it in.
- Testing only with the simulator's default fast-forward. Time the real cycle with a stopwatch at least once; a timer accidentally set to T#12ms instead of T#12s passes a casual glance and fails on the road.
Most of these share one root cause: the rung shape doesn't match the intent, so the program passes the obvious test and fails the edge case. That's why the solution steps force the edge cases deliberately instead of stopping at "it starts and it stops". Steal that habit for every program you write from here on.
Take it further
Got it working first time? Good — now make it earn its keep. Each extension below changes the spec the way a real client does: after you've finished. Treat each one as a fresh job card, and re-test the whole program afterwards, not just the new part. Regressions hide in the rungs you didn't touch.
- Add a second signal face for the far end of the lane, running the opposite phases with a 4-second all-red clearance interval between direction changes — that clearance gap is where the real engineering is.
- Add a flashing-amber night mode on a second selector position, reusing the two-timer flasher from the beacon exercise.
- Move on to the pedestrian crossing exercise, which adds a request button and a minimum-green hold-off to this same state-machine pattern.
If you build even one extension, screenshot the finished rungs and keep them somewhere organised. A folder of working, tested exercise solutions is the start of a portfolio — and hiring engineers ask candidates to explain a rung far more often than they ask to see certificates.
Run this in the simulator
Every beginner exercise on this site, this one included, runs on the simulator's free tier — no card details, no install, signed up and on a rung inside two minutes. The watch table is the part that matters here: force the inputs, watch the outputs, and run the test sequence from the solution steps against a live scan cycle instead of imagining it. The full curriculum — the structured version of these exercises with feedback on every submission — plus the wiring track, sensor school and cert packs sit in the Basic tier at USD 12 per month and Pro at USD 29 per month. Training centres and engineering departments wanting this in a lab should look at the Teams tier (USD 199 per seat per year, minimum 5 seats); the training-centres page carries the institutional details and the contact form. If you're an individual learning the trade, start on the free tier, finish the beginner set, and decide from there.
Run this exercise on the free tier →Reference
Programmable logic controller on Wikipedia covers the background theory behind this exercise, and it's worth twenty minutes of your time after the build — theory sticks better once your hands have done the work. The languages used here are defined by the IEC 61131-3 standard from iec.ch, and your CPU vendor's manual remains the canonical source for how a specific controller executes them.
What we don't claim
This site is not SAQA-registered, not MerSETA-accredited, and not an NQF-registered qualification provider. Our completion certificates are course-level only — they describe what you covered, not an NQF Level X qualification. The CCST cert from ISA is the portable industry credential we recommend; we are not an ISA cert delivery partner either, but our cert packs are CCST-aligned. The exercise on this page is practice material written by working programmers: finishing it proves the skill to yourself and to the simulator's progress tracking, not to a regulator.