exercises · South Africa
PLC pump alternation logic for duty-standby
PLC pump alternation logic done properly: lead pump toggles on the stop edge, standby takes over on a trip, both run on high-high. Ladder and ST shown.
Difficulty: intermediate · 45–75 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 stormwater sump at a vehicle workshop in Boksburg has two identical 4 kW submersible pumps on a common discharge. Pump 1 does all the work because the changeover switch has been left on '1' since installation, and it is now on its third set of seals while pump 2 sits seized from standing. Program proper duty-standby: floats at low, high and high-high; the lead pump starts at high and runs until low; the lead role swaps after every completed cycle so wear shares evenly; if the duty pump's MCC reports a fault the standby must take over immediately; and at high-high both pumps run regardless of whose turn it is.
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 |
|---|---|---|---|
SumpLow | DI | %I0.0 | Low float switch, TRUE while water is above the low level (stop point). |
SumpHigh | DI | %I0.1 | High float switch, TRUE while water is above the start level. |
SumpHighHigh | DI | %I0.2 | High-high float, TRUE when the level needs both pumps. |
Pump1OK | DI | %I0.3 | Pump 1 MCC healthy signal, normally closed chain (overload, isolator), fail-safe. TRUE = available. |
Pump2OK | DI | %I0.4 | Pump 2 MCC healthy signal, normally closed chain, fail-safe. TRUE = available. |
Pump1Run | DO | %Q0.0 | Pump 1 contactor coil. |
Pump2Run | DO | %Q0.1 | Pump 2 contactor coil. |
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.
- Toggle the lead bit on the falling edge of demand — the moment a pumping cycle completes — not on the start edge. Toggling at the start means a power blip mid-cycle can re-toggle and hand the same pump two cycles in a row; the stop edge is the one clean 'cycle finished' event.
- Demand itself is a float hysteresis seal-in, exactly like the tank exercise: start at the high float, hold until the low float drops. The alternation logic should sit beside the demand logic, never inside it.
- Make the lead bit retentive. If it resets to pump 1 on every power cycle, load-shedding quietly recreates the original problem — pump 1 doing nearly all the work — while the logic looks correct in every test.
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: demand from the floats
Seal-in: Demand starts when SumpHigh comes true, holds through its own contact, and drops when SumpLow goes false (water below the stop float). The band between the floats sets cycle length, same hysteresis idea as the two-probe tank.
// ──┬──[ ]SumpHigh──┬──[ ]SumpLow──( )Demand
// └──[ ]Demand────┘
Rung 2: toggle the lead on the stop edge
A falling-edge contact on Demand toggles the Lead2 bit (FALSE = pump 1 leads, TRUE = pump 2 leads). One XOR-style rung or a flip-flop does it. Declare Lead2 retentive so the rotation survives power cuts.
// fDemand(CLK := Demand) // F_TRIG
// fDemand.Q ── Lead2 := NOT Lead2
Rungs 3-4: pump outputs with failover and high-high
Each pump runs when there is demand, it is healthy, and any of three reasons apply: it is the lead, the level has reached high-high, or the other pump is unavailable. The structure puts failover and assist in the same OR group, so a tripped duty pump hands over within one scan.
// Demand AND Pump1OK AND (NOT Lead2 OR SumpHighHigh OR NOT Pump2OK) ──( )Pump1Run
// Demand AND Pump2OK AND (Lead2 OR SumpHighHigh OR NOT Pump1OK) ──( )Pump2Run
Test the rotation, the failover and the flood
Run four demand cycles in the simulator and confirm strict alternation: 1, 2, 1, 2. Mid-cycle, force the running pump's OK signal FALSE and watch the standby pick up without the level rising further. Force SumpHighHigh and confirm both pumps run, then drop it and confirm the non-lead pump stops. Finally kill both OK signals: both pumps must stop and this is where you notice the exercise needs a common-fault alarm output — add one.
The structured text version
The same logic in IEC 61131-3 structured text — each output written as a boolean equation you can read aloud.
(* Duty-standby pump alternation, IEC 61131-3 ST *)
Demand := (SumpHigh OR Demand) AND SumpLow;
fDemand(CLK := Demand); (* F_TRIG *)
IF fDemand.Q THEN
Lead2 := NOT Lead2; (* retentive: swap lead after each completed cycle *)
END_IF;
Pump1Run := Demand AND Pump1OK AND ((NOT Lead2) OR SumpHighHigh OR NOT Pump2OK);
Pump2Run := Demand AND Pump2OK AND (Lead2 OR SumpHighHigh OR NOT Pump1OK);
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.
- Toggling the lead bit on a level instead of an edge. Lead2 := NOT Lead2 evaluated every scan while a condition is true flips thousands of times a second, and which pump runs becomes a function of scan timing — maddening to fault-find because every snapshot looks plausible.
- Alternating on the start edge. A brownout that drops and restores demand mid-cycle re-toggles the lead, and over a wet season the wear split drifts far from 50/50 without anyone seeing a fault.
- Leaving the lead bit non-retentive, so every load-shedding slot resets the rotation to pump 1. The logic passes every bench test and still wears pump 1 out first in production — exactly the failure this job card started from.
- No failover path, only alternation. The duty pump trips at 02:00, the standby waits politely for its turn, and the workshop floor is under 100 mm of water by morning. Availability is the reason there are two pumps; alternation is just the bonus.
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 per-pump hour meters (a TON-and-counter pattern or a retained REAL accumulating run seconds) and alternate on accumulated hours instead of strict rotation — better wear sharing when cycles vary in length.
- Add a common-fault output and a delayed high-high alarm (high-high standing for more than 30 s with both pumps commanded) for the panel beacon, using the flasher pattern from the timer exercise.
- Scale up to three pumps with a lead/lag/standby rotation — the jump from a toggle bit to a rotating index is bigger than it looks and is a genuine interview question.
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
The sandbox on the free tier lets you build the core rungs of this intermediate exercise yourself — 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. To be straight about what's paid: the guided version of this exercise — graded checkpoints, feedback on every submission — sits in the curriculum on the Basic tier at USD 12 per month and Pro at USD 29 per month, alongside the wiring track, sensor school and cert packs. 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, prove the core rungs in the free sandbox first and decide whether the graded track is worth the money. And once this one runs clean, line up the next exercise a notch harder — the step up is where the skill gets built.
Start in the free sandbox →Reference
plcprogramming.io simulator 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.