Case studies · Irrigation controller
A controller that grows
one board at a time
Four, eight or sixteen zones per board. Up to nineteen nodes on the same installation. Directives are designed to live on the board, not in the cloud: the goal is that switching the PC off does not stop irrigation. A new board announces itself and is added without reworking the software, the wiring of the other zones or the schedules already in service.
Working prototype. Firmware and web interface verified on real hardware: an ESP32-C3 bridge over USB and an ESP32-S3 node with a 16-channel relay board.
The project
Opening a valve is easy.
Running it for years without surprises is not.
An irrigation system works when nobody is watching: at dawn, on holiday, during a storm, with the PC off and the network coming and going. Most “smart” controllers fail exactly there: they put the clock and the logic in an app, a server or a cloud, and when that piece is missing the water does not start — or starts when it should not.
This controller reverses the dependency. Directives — days, start times, duration and programs for each channel — are the board’s own property: it has a battery-backed clock and is designed to irrigate for at least 48 hours without a PC. The PC is the editor and the synchroniser: it writes the configuration, reads events and shows clock drift. In steady state it is not in the critical path; today it still starts the cycles, and moving the scheduling engine onto the board is the next block of work (see What is ready).
The link between the two sides is deliberately simple and repairable: from the web interface to an ESP32-C3 bridge over USB or the local network, from the bridge to the boards over ESP-NOW, a direct radio protocol that needs no Wi-Fi, router, internet or subscription. Each board drives 24 VAC solenoid valves through triacs or relays and enforces its own safety limits.
This is not an off-the-shelf product with a fixed number of zones: it is an architecture built so the installation can grow. You start with one 8-channel board for the garden and end up with several boards for the vegetable plot, greenhouse and orchard, without changing protocol, rewriting the database or touching schedules that already work.
At a glance
- BoardsTR4 · TR8 · TR16 · RE8 · RE16
- Outputstriac or relay, 24 VAC
- RadioESP-NOW 2.4 GHz, broadcast
- BridgeESP32-C3, USB CDC or TCP
- Nodes per bridgeup to 19
- AutonomyRTC + flash, ≥ 48 h
- Interfaceweb, PHP/MySQL, local
- System lockglobal, logged
Architecture
Three layers, one source of truth: the board
The PC configures, the bridge transports, the node executes. No higher layer can leave a valve open if it stops responding, because closing and the limits live on the layer that holds the relay.
Configuration, manual commands, log
Node ↔ MAC map
24 VAC solenoid valves · pump / master valve
| Actor | What it does | What it does not do |
|---|---|---|
| PC (master) | Shows and edits the configuration, synchronises clock and directives, collects events and alarms, forwards manual commands. | In steady state it does not open valves: it is not in the critical path. Today starts still go through it. |
| Bridge ESP32-C3 | Encapsulates frames, broadcasts them, collects ACKs and status, retries, keeps the node map. | It does not interpret schedules and does not decide when to irrigate. |
| Node (board) | Executes directives, keeps time with an RTC, applies limits, records events, reports status and drift. In steady state it does so autonomously. | In steady state it does not depend on the PC for a scheduled start; today the cycle engine is still on the PC. |
| Outputs | Triac or relay to 24 VAC solenoid valves; a dedicated output for the pump or master valve. | 230 V stays in the external transformer, never on the board. |
Why not a cloud. A missed irrigation cannot be recovered: the plant stays dry and the cycle does not come back. That is why the system works on the local network, needs no internet and does not depend on a provider being available. Remote access, when needed, goes through a VPN or a tunnel: it is the installer’s choice, not a requirement for operation.
Simulation
Watch it work without watering anything
The simulation reproduces the controller’s behaviour: three boards, the pump, the channel sequence, the system lock and the loss of the PC. Time runs about 100 times faster than real; the log tells every step. It shows steady-state operation: autonomous execution of schedules on the board is the last block still in development.
Calculating the next start…
Starting up…
The type is a catalogue code: the web interface interprets it, the firmware does not.
Directives live on the board: turn the PC off and the start stays scheduled. Lock the system to see the outputs close immediately.
Click a zone for a 10-minute manual command. The pump opens first and closes last: the hydraulic logic is the same as in automatic cycles.
Manual commands are refused, but the next scheduled start still runs: the board holds the clock and the directives.
The controller integrates it live. The other boards stay configured and in service: no migration, no restart.
Open outputs close at once and every new start is refused. Only the pump test remains, for 60 seconds and logged.
Modularity
Modularity is not an accessory:
it is how the system is built
A traditional controller is chosen once: the number of zones is fixed, and if you add a vegetable plot next year you either replace the unit or live with an undersized system. Here the board is the smallest unit and the system is designed to hold more than one from the start.
One board, 4 to 16 channels
The same scheduling logic runs on a 4, 8 or 16-channel board. The number of outputs changes, not the firmware or the directive format. You buy the capacity you need today, not the one you might need in five years.
One channel per board can be marked P and drive the pump or master valve: it is not a zone, it is not scheduled and it never enters the sequence.
More boards, one system
One bridge addresses up to 19 nodes. Every extra board adds channels without changing the PC, the database or the rest of the configuration: the other boards keep running while the new one is being paired.
Configuration stays per board, with its own days, five start times and programs. There is no “zone limit” to redistribute.
A catalogue, not one firmware per model
A board announces itself with a four-byte code — TR16,
RE8, … — and the catalogue in the database interprets it: channels,
family, pump, RTC, sensors. A new type is added from the interface.
A code outside the catalogue is not accepted: better a board waiting than an interface inventing channels that do not exist. If firmware and catalogue diverge, the divergence is recorded in the events.
It grows after installation too
The “extended” board adds rain, flow and humidity sensors without changing the protocol. OTA updates, the local log and manual commands belong to the same design, not bolted on afterwards.
Replacing a failed board means re-pairing that node: the others keep their number, configuration and history.
From 8 to 24 zones in an afternoon
Existing system: one TR8 board with eight zones and the 06:00 program. The
newly built vegetable plot also needs water. A TR16 is added: the node
announces itself, the operator compares the MAC with the label and approves, the PC
assigns node_id 2. The new board has its sixteen channels; the first one
stays exactly as it was.
Total: 24 channels, two nodes, one bridge and one database. No data migration, no new software, no interruption to starts already in service.
What does not change when you add a board
- The radio protocol and the frame format stay the same.
- The database schema is untouched: one row changes in the node registry.
- Programs, durations and days of existing boards remain valid.
- The web interface is the same: one more board appears in the selector.
- The bridge needs no reconfiguration: it learns the
node_id ↔ MACmap. - Log, backup and maintenance procedure stay as they are.
| Scenario | Boards | Channels |
|---|---|---|
| Home garden | 1 × TR8 | 8 |
| Villa with vegetable plot | 1 × TR16 + 1 × TR8 | 24 |
| Greenhouse and orchard | 2 × TR16 + 1 × RE8 | 40 |
| Park or farm | 4 × TR16 | 64 |
A cycle
Minute by minute, never two valves open together
When a program starts the pump opens first, channels open in sequence and close one at a time; the pump closes after the last one. The program duration is the sum of durations, not the longest one.
| Time | Activity |
|---|---|
| 09:59:57 | Pump ON — waiting for T_pump |
| 10:00:00 – 10:30:00 | Channel 1 open (program 1) |
| 10:30:00 – 10:30:05 | Closing, T_gap pause of 5 s |
| 10:30:05 – 10:50:05 | Channel 2 open (program 1) |
| 10:50:10 – 11:05:10 | Channel 3 open (program 1) |
| 11:05:10 | Pump OFF after T_post |
Channel 2 is also part of program 4 (18:00 start): at 18:00 it opens again, for the second time that day, with the same duration.
-
The pump opens first
The pump must never work against closed valves: it opens, pressure is allowed to settle, and only then does the first zone start.
-
One channel at a time
The sequence follows channel order. The pause between zones prevents water hammer and gives the valve time to close properly.
-
The pump closes last
The pump stays on until the last channel is closed, then switches off. If the next start arrives during a cycle it is queued or skipped: never two zones together.
Days per channel. The same day can be active for one zone and not for another, without duplicating programs. A channel with no programs has no useful days or duration: the interface disables both.
Several programs, one channel. A channel can belong to more than one program: it starts at each program’s start time, with the same duration. That is how different timetables are built without duplicating the row.
Consistent start times. A program used by at least one channel must have a start time, otherwise it would never run: the interface refuses it on save.
The boards
Same protocol, declared capacity
The firmware has no branch per model: it declares a code and a capability bitmask. The database interprets the code, the interface shows the right channels. Adding a model is a catalogue operation, not a rebuild.
| Code | Family | Channels | Output | Notes |
|---|---|---|---|---|
TR4 | Triac | 4 | 24 VAC | Small gardens, planters, terraces |
TR8 | Triac | 8 | 24 VAC | Complete domestic system |
TR16 | Triac | 16 | 24 VAC | Vegetable plot, orchard, more zones |
RE8 | Relay | 8 | 24 VAC | Where mechanical isolation is needed |
RE16 | Relay | 16 | 24 VAC | Large systems with relays |
The board introduces itself
A new node broadcasts a 20-byte announcement in clear, trying the radio channels until it finds the master. The PC records it as a pairing request: it is visible, not yet trusted.
The announcement carries board code, hardware revision, firmware version, channel count, capabilities and three bytes of the factory MAC.
Acquisition is automatic, approval is not
Broadcast cannot be encrypted and the MAC can be changed in software: an announcement identifies an address, not a board. That is why the operator compares the MAC with the physical label and approves.
On approval the node receives node_id and a shared token with which it signs
commands: a command without a valid signature never touches a relay.
The extended board, without changing the installation
The bitmask declares RTC, pump, local log, OTA and sensors. The extended variant adds rain, flow and humidity: the protocol is the same, what the board can measure changes.
The NC rain sensor is wired in series with the solenoid common: it is a hardware interlock, so it shuts the water off even if the firmware hangs.
Safety and autonomy
The worst case is not “not irrigating”.
It is irrigating without noticing.
Every design choice starts here: outputs are closed at boot, limits do not depend on the PC, the lock is visible and logged, and losing the link never opens or leaves a valve open.
Real autonomy
External battery-backed RTC and directives in flash: the board is designed to irrigate
for at least 48 hours without a PC and without a network. After 48 hours without
synchronisation it reports SYNC_STALE and keeps going; it does not shut the
water off for a network problem.
System lock
A global lock, with reason, date and user, closes the outputs at once and refuses every start. Only the pump test remains possible, for 60 seconds and logged. Unlocking reopens nothing: operation resumes at the next scheduled start.
Limits always active
Maximum duration per channel and daily total, one channel open at a time, pump only with at least one zone open, outputs closed at boot. These are board rules, not interface rules: they apply when the PC is not there.
Signed commands
Manual commands carry duration and expiry, are deduplicated by sequence and signed with HMAC. If the link drops, the command expires and the valve closes: the dead-man applies to commands, not to scheduled cycles.
Maintenance without downtime
Adding or replacing a board does not stop the others. The node registry lives in the database, not in the bridge firmware: changing the PC requires no re-pairing.
Everything leaves a trace
Openings, closings, skipped starts, commands, locks and alarms go into the log with cause and time. The board keeps a ring log and hands it to the PC when the link returns.
Declared limits. In this version ESP-NOW frames travel in clear: encryption is an open decision and depends on the physical exposure of the installation. The bridge TCP port should only be used on the local network or behind a tunnel. 230 V stays in the external transformer: the board handles 24 VAC only.
Under the hood
Measured numbers, not promises
Transport is the part that can be verified without waiting for an installation. These are the results from the prototype, with the firmware flashed on real hardware.
| Test | Result |
|---|---|
| Firmware self-test on the device | 6 / 6 passed |
| Frames from 0 to 240 bytes, 20 per size | 120 / 120 replies, no altered payload |
| Average latency at 240 bytes | 7.1 ms (p95 12.2 ms) |
| CRC errors on the bridge | 0 |
| Command to a mapped node | ACK received |
| Command to a missing node | tx_failed + error, as expected |
The hardware test found a defect no test on the PC would have seen: the firmware omitted the frame’s two synchronisation bytes. Fixed, and since then the link test is part of the routine.
Why it matters. A 16-channel configuration — five start times, days, duration and programs per channel, time zone — fits in a single frame. No stable connection or chunked upload is needed to change the schedule: you write it, check the CRC and the board answers “already aligned” if there is nothing to do.
Project status
What is ready, what is coming
The prototype is not a rendering: bridge, pairing, manual commands and transport are implemented and tested. What remains is the scheduling engine directly on the board, today still on the PC.
-
Serial and TCP bridge
Frames with CRC, ACK, deduplication, node map, USB and local network modes. Tested with 120 frames from 0 to 240 bytes.
-
Announcement, pairing and manual commands
A new board announces itself, is approved, receives node_id and token. Manual commands are signed and report the real state of the outputs.
-
Configuration and log
Boards, channels, days, five start times, several programs per channel, pump channel, system lock and the type catalogue.
-
The scheduling engine on the board
Directives in flash with version and CRC, clock synchronisation, autonomous cycle execution. Until that is ready, the PC starts the cycles.
-
OTA, encryption, sensors
Chunked updates with rollback, ESP-NOW encryption when the installation requires it, sensors on the extended board.
Frequently asked questions
The objections we hear most often
How many zones can it really handle?
From 4 to 16 channels per board and up to 19 boards on the same bridge: the practical limit is not the number of zones, it is radio range and how the installation is laid out. You start with one board and add more without changing anything else.
Does it need internet or a subscription?
No. The PC and the bridge sit on the local network, and the boards talk directly over radio. There is no cloud service to renew and irrigation does not depend on mobile coverage. Remote access, if needed, is added with a VPN.
What happens if the PC is switched off or fails?
Today the PC starts the cycles: if it is off, the start is skipped and recorded as missed. The project moves directives and clock onto the board, with a backup battery, so starts continue even with the PC off: that is the next block of work, described in What is ready, what is coming. Replacing the PC does not require re-pairing the boards: configuration and pairing stay in the database and on the board.
Can I add a board years later?
Yes, and that is the point of the project. The board announces itself, is approved by
comparing the MAC with the label, receives a node_id and appears in the
interface. The other boards need no reconfiguration and running starts are not
interrupted.
Which valves can I connect?
24 VAC solenoid valves, driven by triacs or relays depending on the board. 230 V never enters the board: it stays in the external transformer in a closed enclosure. Low-voltage wiring is within an installer’s reach; the mains side is not.
Is it safe to leave the system unattended?
The design combines several layers: outputs closed at boot, duration limits always active, pump only with a zone open, a logged global lock, an NC rain sensor in series with the common as a hardware interlock. There are declared limits — radio encryption in particular — that must be assessed against where the system is installed.
Does it integrate with Home Assistant or a supervisor?
The architecture exposes status and accepts commands from a local interface; integration with a supervisor is a later step, not a requirement for irrigating. The priority remains that cycles run without depending on any external service.
Let’s talk
Do you have an installation that must grow,
or one you would like to make autonomous?
Tell us how many zones you have today, how many you will need and what the site looks like. We can start with one board and size the rest without locking the installation to a fixed number of zones.
A NetSpeak project · hardware, firmware and software design.
