exercises · South Africa
PLC float switch pump control for a borehole
PLC float switch pump control for a borehole and storage tank: two floats, dry-run cutout with latch, and a restart delay for when load-shedding ends.
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: a guest lodge in the Waterberg runs its water off a borehole pumping into a 5000-litre storage tank on a stand. The current setup is a single float switch wired straight to the pump contactor, and it has killed two pumps in eighteen months: one from chattering at the switch point, one from running dry when the borehole level dropped in September. Fit two floats in the tank (start and stop), use the borehole's low-level probe as a dry-run cutout that latches out and needs a manual reset, and add a 30-second delay after power returns so the pump does not slam in together with every geyser and freezer on the property when load-shedding ends.
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 |
|---|---|---|---|
TankLow | DI | %I0.0 | Lower float in the storage tank, TRUE while water holds the float up (above the start level). |
TankHigh | DI | %I0.1 | Upper float in the storage tank, TRUE while water is above the stop level. |
BoreholeOK | DI | %I0.2 | Borehole low-level probe relay, normally closed, wired fail-safe. TRUE = enough water over the pump; a dry hole or a broken probe cable both read FALSE. |
ResetPB | DI | %I0.3 | Dry-run reset pushbutton at the pump panel, normally open, momentary. |
PumpRun | DO | %Q0.0 | Borehole pump contactor coil, 1.5 kW submersible. |
DryRunLamp | DO | %Q0.1 | Red dry-run trip lamp at the panel, on while the trip latch is in. |
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.
- Two floats, one band: start when the low float drops, stop when the high float rises. The metre or so between them is your hysteresis, and it is why this pump cycles a handful of times a day instead of chattering at a single switch point until the contactor welds.
- The dry-run trip must latch. A borehole that uncovered the probe will cover it again as it recovers, and an unlatched cutout would short-cycle the pump against a recovering hole all afternoon — the exact slow-death the second dead pump died. Someone walks to the panel, checks, and presses reset.
- The restart delay times from PLC power-up, not from the trip. Its job is grid-return etiquette: when load-shedding ends, every motor on the property wants the first second of supply. Thirty seconds of patience costs nothing and spares the pump the worst of the voltage sag.
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: power-up settling timer
A TON driven by a permanently-TRUE contact, PT of T#30s. It starts timing the moment the PLC boots — which after load-shedding is the moment power returns — and its done bit is a permission in the pump rung. Simple, and it removes the lodge's pump from the grid-return inrush pile-up.
// AlwaysOn ──[TON tSettle, PT := T#30s]
Rung 2: the dry-run trip latch
Seal-in: (NOT BoreholeOK OR DryRunTrip) AND NOT ResetPB. The trip sets the instant the probe uncovers, holds itself, and only the reset button clears it. The lamp follows the latch so the trip is visible from across the yard.
// ──┬──[/]BoreholeOK───┬──[/]ResetPB──( )DryRunTrip
// └──[ ]DryRunTrip───┘
// DryRunTrip ──( )DryRunLamp
Rung 3: the pump rung
Float hysteresis seal-in with all the permissions in series: start when TankLow drops, hold through the pump's own contact, stop at TankHigh, and the whole rung gated by NOT DryRunTrip and tSettle.Q. Note BoreholeOK itself is not in this rung — the latch already represents it, with memory.
// ──┬──[/]TankLow────┬──[/]TankHigh──[/]DryRunTrip──[ ]tSettle.Q──( )PumpRun
// └──[ ]PumpRun────┘
Test the September scenario
Walk the tank level down and up and confirm the band works: start only when the low float drops, stop only at the high float. Then the dry September test: with the pump running, force BoreholeOK FALSE — pump stops, lamp on. Force BoreholeOK TRUE again — pump must stay locked out until ResetPB is pressed. Finally the load-shedding test: cycle PLC power with the tank low; the pump must wait out the full 30 seconds before starting, every time.
The structured text version
The same logic in IEC 61131-3 structured text — each output written as a boolean equation you can read aloud.
(* Borehole pump with floats, dry-run latch, restart delay *)
tSettle(IN := TRUE, PT := T#30s); (* times from PLC power-up *)
DryRunTrip := (NOT BoreholeOK OR DryRunTrip) AND NOT ResetPB;
DryRunLamp := DryRunTrip;
PumpRun := (NOT TankLow OR PumpRun)
AND NOT TankHigh
AND NOT DryRunTrip
AND tSettle.Q;
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.
- One float doing both start and stop. Waves from the inlet rock the float at the switch point and the contactor chatters — this is the first dead pump on this job card, and the two-float band is the whole cure.
- An unlatched dry-run cutout. The borehole recovers a few centimetres, the pump restarts, draws the hole down, trips, recovers, restarts — dozens of dry starts a day, and the pump dies slowly enough that nobody connects cause and effect.
- Getting a float's sense backwards. 'TRUE when up' versus 'TRUE when down' depends on which contact you landed; program one assumption against the other wiring and the pump runs with the tank full and rests with it empty. Check each float with a multimeter while lifting it by hand.
- Putting the restart delay on the trip latch instead of on power-up. The trip needs a human, not a timer — an automatic 30-second 'reset' on a dry borehole is just the unlatched-cutout bug wearing a timer as a disguise.
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 weekly anti-seize run: if the pump has not started for 7 days (a retentive timer), run it for 30 seconds when the borehole is healthy — standing seizure killed many a standby pump, as the alternation exercise's pump 2 shows.
- Add a tank-overflow alarm float above the high float, and ask yourself why it must be a separate physical float rather than logic on TankHigh (answer: the failure you are guarding against is TankHigh itself failing).
- Replace the floats with a submersible 4-20 mA level transmitter, recreate the band in comparisons, and keep the floats wired as hard backup limits — the standard belt-and-braces upgrade path.
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
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.