A pump controller is not a toy project once water, pressure, and unattended operation are involved. The goal is not just controlling a relay. The goal is to guarantee safe behavior when sensors fail, wiring degrades, or power quality drops.
1. Safety assumptions and hazard list
Start with hazards, not code:
- Dry run can damage pump hardware
- Stuck relay can overfill tanks
- Sensor drift can cause silent bad decisions
- Reboot during active cycle can leave outputs unsafe
For each hazard, define a mitigation in firmware and hardware. If one mitigation fails, the second one should still reduce risk.
2. Hardware safety architecture
I recommend this arrangement:
- Pump relay defaults to OFF on MCU reset
- Float switch wired as independent hardware interlock
- Current sensor to detect pump running unexpectedly
- Separate fuse for pump power branch
- Physical emergency stop switch in series with relay output
The interlock path should not rely only on software logic.
3. Explicit finite state machine
Use an explicit state machine to prevent contradictory behavior:
IDLEPRIMINGPUMPINGCOOLDOWNFAULT_LATCHED
Each transition has entry and exit conditions. Example:
PUMPING -> FAULT_LATCHEDwhen dry-run signal is active for 3 consecutive samples.FAULT_LATCHED -> IDLEonly after operator acknowledgement and sensor health check.
This structure is easier to audit than nested if blocks.
4. Timing and anti-chatter policy
Never switch pump state directly on single-threshold crossings. Add hysteresis and minimum run windows:
- Minimum ON duration: protects relay contacts and motor startup
- Minimum OFF duration: prevents rapid restart cycles
- Sensor debounce windows: smooth mechanical switch noise
These values should be configurable through persistent settings with bounds validation.
5. Fault detection signals
A robust controller combines multiple signals:
- Level sensor indicates demand
- Current sensor confirms motor actually runs
- Runtime watchdog checks max cycle duration
- Optional pressure sensor verifies expected hydraulic response
If command says ON but current remains zero, classify as actuation fault. If current is high but level does not change, classify as possible blockage.
6. Recovery strategy
Use staged recovery, not immediate repeated retries:
- First fault: stop pump, wait cooldown, retry once
- Second fault in same window: lock into
FAULT_LATCHED - Require manual reset to continue
Manual reset is a feature, not an inconvenience, for systems with real physical risk.
7. Logging that helps postmortems
Log these event types with timestamps:
- state transitions
- command outputs
- fault reasons
- reset causes
- operator acknowledgements
Postmortem quality depends on event logs. Without them, teams tend to blame hardware randomly.
8. Commissioning test protocol
Before production:
- Simulate dry-run and overfill conditions
- Force sensor disconnections during operation
- Power cycle during each state
- Validate safe startup after unexpected reset
If the controller passes these tests cleanly, confidence is earned, not assumed.
Final note
Fail-safe design is about predictable behavior under bad conditions. Arduino can be fully suitable for this class of project when state modeling, hardware interlocks, and fault latching are built in from the start.