Why the Sump Pump Monitor Tops the List of Useful Arduino Projects
When makers search for useful Arduino projects, they usually wade through endless LED cubes and Bluetooth-controlled cars. But a project only earns the 'useful' label when it solves a real, expensive problem. A flooded basement costs an average of $4,000 to remediate. A smart sump pump monitor that tracks both water level and actual pump current draw—and alerts you via MQTT when the pump fails to move water—is the ultimate intersection of embedded engineering and home protection.
Unlike older iterations of useful Arduino projects that relied on clunky ESP8266 AT-command shields, this build uses the modern Arduino Uno R4 WiFi. It features a native Renesas RA4M1 microcontroller paired with an ESP32-S3 coprocessor, giving you 5V-tolerant GPIO pins and native WiFiS3 library support without sacrificing the classic Uno footprint.
Hardware Spec Sheet & Pin Mapping
To ensure reliability in a damp basement environment, we are avoiding cheap, unsealed modules. Here is the exact bill of materials and wiring map.
| Component | Exact Variant / Model | Est. Cost | Purpose |
|---|---|---|---|
| Microcontroller | Arduino Uno R4 WiFi (ABX00087) | $27.50 | Logic, WiFi, MQTT processing |
| Current Sensor | ACS712-20A Module (5V logic) | $4.50 | Verifies pump motor is actually drawing current |
| Level Sensor | XKC-Y25-V (Non-contact, 5V out) | $14.00 | Detects high water level through PVC pipe wall |
| Relay Module | 5V 2-Channel Optocoupler Relay | $3.50 | Triggers local 120V siren or secondary backup pump |
| Power Supply | Mean Well IRM-10-5 (5V 2A) | $12.00 | Isolated, sealed AC-DC power for the enclosure |
| Enclosure | NEMA 4X Polycarbonate (6x6x4) | $22.00 | Waterproof housing for basement mounting |
Pin Mapping Table
| Arduino Uno R4 Pin | Module | Module Pin | Wire Gauge / Notes |
|---|---|---|---|
| 5V | ACS712-20A | VCC | 22 AWG Red |
| GND | ACS712-20A | GND | 22 AWG Black |
| A0 | ACS712-20A | OUT | 22 AWG Shielded (Analog) |
| D2 | XKC-Y25-V | OUT (Signal) | 22 AWG Blue (Digital Interrupt) |
| D3 | Relay Module | IN1 | 22 AWG Yellow |
| VIN | Mean Well 5V PSU | +V | 18 AWG (Main Power Feed) |
Step-by-Step Assembly & Wiring
- Mount the PSU and Arduino: Secure the Mean Well IRM-10-5 and the Uno R4 WiFi to the DIN rail inside the NEMA 4X enclosure. Ensure the WiFi antenna on the R4 is oriented vertically and not blocked by metal.
- Wire the AC Input: Run 14 AWG THHN from a dedicated 15A GFCI-protected basement receptacle to the AC input terminals of the Mean Well PSU. Connect the PSU's 5V DC output to the Arduino's VIN and GND pins.
- Install the Current Sensor: Pass only the 120V Hot (black) wire of the sump pump's power cord through the center hole of the ACS712. Do not pass the neutral or ground, or the magnetic fields will cancel out and you will read 0A.
- Attach the Level Sensor: Strap the XKC-Y25-V to the outside of your PVC sump pit discharge pipe or the pit wall at your 'high water alarm' threshold. The non-contact sensor reads through up to 12mm of non-metallic material. Use stainless steel hose clamps, not zip ties, which degrade in damp environments.
- Connect Logic Wires: Route the 22 AWG sensor wires back to the enclosure. Keep analog wires (A0) physically separated from the 120V AC lines by at least 2 inches to prevent inductive noise from skewing your current readings.
Complete Arduino IDE Code with Error Handling
This code targets the Arduino Uno R4 WiFi. It uses the native WiFiS3 and ArduinoMqttClient libraries. It includes error handling for WiFi drops and MQTT disconnects, ensuring the system recovers automatically after a brownout.
#include <WiFiS3.h>
#include <ArduinoMqttClient.h>
// --- PIN DEFINITIONS ---
#define PIN_CURRENT_SENSOR A0
#define PIN_LEVEL_SENSOR 2
#define PIN_ALARM_RELAY 3
// --- NETWORK & MQTT CONFIG ---
const char ssid[] = "YourNetworkSSID";
const char pass[] = "YourNetworkPassword";
const char broker[] = "192.168.1.50"; // Your MQTT Broker IP
const int port = 1883;
const char topic_current[] = "home/basement/sump/current";
const char topic_alarm[] = "home/basement/sump/alarm";
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
// Thresholds
const float CURRENT_THRESHOLD_AMPS = 2.5; // Pump should draw at least this when on
const int ALARM_PIN_ACTIVE = LOW; // Depends on relay module logic
void setup() {
Serial.begin(115200);
pinMode(PIN_LEVEL_SENSOR, INPUT);
pinMode(PIN_ALARM_RELAY, OUTPUT);
digitalWrite(PIN_ALARM_RELAY, HIGH); // Assume active LOW relay, start OFF
connectToWiFi();
connectToMQTT();
}
void loop() {
// 1. Maintain Connections
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi dropped. Reconnecting...");
connectToWiFi();
}
if (!mqttClient.connected()) {
Serial.println("MQTT dropped. Reconnecting...");
connectToMQTT();
}
mqttClient.poll();
// 2. Read Sensors
int levelState = digitalRead(PIN_LEVEL_SENSOR);
float currentAmps = readCurrent();
// 3. Logic & Error Detection
if (levelState == HIGH) {
// Water is high. Is the pump running?
if (currentAmps < CURRENT_THRESHOLD_AMPS) {
triggerAlarm("CRITICAL: High Water but Pump NOT drawing current!");
} else {
publishStatus("NORMAL: High water, pump is running.");
}
} else {
publishStatus("NORMAL: Water level low.");
deactivateAlarm();
}
// 4. Publish Telemetry
mqttClient.beginMessage(topic_current);
mqttClient.print(currentAmps, 2);
mqttClient.endMessage();
delay(5000); // 5 second polling interval
}
float readCurrent() {
// ACS712-20A sensitivity is 100mV/A. Offset is 2.5V.
int raw = analogRead(PIN_CURRENT_SENSOR);
float voltage = (raw * 5.0) / 1023.0;
float amps = (voltage - 2.5) / 0.100;
return abs(amps); // AC current will fluctuate, abs() gives magnitude
}
void triggerAlarm(const char* msg) {
digitalWrite(PIN_ALARM_RELAY, ALARM_PIN_ACTIVE);
mqttClient.beginMessage(topic_alarm);
mqttClient.print(msg);
mqttClient.endMessage();
Serial.println(msg);
}
void deactivateAlarm() {
digitalWrite(PIN_ALARM_RELAY, HIGH);
}
void publishStatus(const char* msg) {
Serial.println(msg);
}
void connectToWiFi() {
int attempts = 0;
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
attempts++;
}
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi connection failed. Rebooting to retry.");
NVIC_SystemReset(); // Hardware reset for R4
}
}
void connectToMQTT() {
String clientId = "ArduinoSump-" + String(random(0xffff), HEX);
mqttClient.setId(clientId);
if (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code: ");
Serial.println(mqttClient.connectError());
}
}
Debugging: "Failed to connect to MQTT broker" Error
When deploying useful Arduino projects onto a home network, MQTT failures are the most common roadblock. If your serial monitor outputs the exact error string: MQTT connection failed! Error code: -2, the ArduinoMqttClient library is timing out or being actively refused by the broker.
Ranked Causes for Error Code -2
- Broker IP Unreachable (Firewall/VLAN): The Uno R4 WiFi is on an IoT VLAN that is blocked from reaching the MQTT broker's subnet on port 1883.
- MQTT Service Not Running: The Mosquitto service or Home Assistant MQTT addon on the target IP has crashed or is not configured to accept anonymous connections.
- Client ID Collision: Though the code uses a random hex suffix, if the device is rebooting rapidly, a stale session might be locking the base ID on the broker.
The First 3 Things to Check When It Fails
- Ping the Broker: Open a terminal on a PC connected to the exact same WiFi SSID as the Arduino. Run
ping 192.168.1.50. If it times out, your network routing is the issue, not the code. - Verify Broker Port and Auth: Use a tool like MQTT Explorer on your PC to connect to
192.168.1.50:1883. If it requires a username/password, you must addmqttClient.setUsernamePassword("user", "pass");to the Arduino code before callingconnect(). - Check the ACS712 Noise: If the MQTT connects but you get false alarms, the ACS712 is picking up EMI from the pump motor. Add a 0.1µF ceramic capacitor between the A0 pin and GND at the Arduino header to filter high-frequency noise.
Extending and Simplifying the Build
Not every deployment needs a full MQTT stack. Here is how to adapt this project to your specific infrastructure.
How to Simplify (No Network Required)
If you don't run a home automation server, strip out the WiFiS3 and ArduinoMqttClient libraries. Replace the MQTT publish blocks with a direct trigger to a local 120V piezoelectric siren wired through the relay module. You can also swap the Uno R4 WiFi for a standard Arduino Uno R3 ($24.00) or an even cheaper clone, as network connectivity is no longer required.
How to Extend (Full Home Assistant Integration)
To integrate this into Home Assistant via MQTT, expand the code to publish a JSON payload instead of raw strings. Add a third sensor—a standard DS18B20 waterproof temperature probe—and publish the sump pit water temperature. This allows you to track groundwater infiltration rates based on seasonal temperature shifts. Ensure you add MQTT Discovery configuration messages so Home Assistant auto-detects the sensors without manual YAML editing.
FAQ: Useful Arduino Projects for the Home
What are the most useful Arduino projects for beginners to build?
For beginners, the most useful projects solve daily annoyances without requiring high-voltage wiring. Top choices include automated plant watering systems using capacitive soil moisture sensors (avoid resistive ones, they corrode in a week), smart mailbox flags using a reed switch and an ESP32, and automated blinds using NEMA 17 stepper motors. The sump pump monitor above is an intermediate step up, introducing AC current sensing and network resilience.
How do I make my useful Arduino projects connect to Home Assistant?
The cleanest method is using MQTT with Home Assistant's MQTT Discovery protocol. Your Arduino publishes a configuration JSON payload to a specific discovery topic (e.g., homeassistant/sensor/sump_current/config) on boot. Home Assistant reads this and automatically creates the dashboard entities. Alternatively, you can use the ESPHome framework if you switch to an ESP32 board, which handles the Home Assistant API integration natively without writing raw C++ networking code.
Can I use an Arduino Uno R3 instead of the R4 WiFi for these useful Arduino projects?
You can use the classic Uno R3 for the sensor reading and relay logic, but it lacks native WiFi. To connect it to a network, you would need to add an external module like the Arduino MKR WiFi 1010 shield or wire up an ESP-01S module and use AT commands over Serial. The Uno R4 WiFi is highly recommended for modern useful Arduino projects because it integrates the ESP32-S3 natively on the board, saving you from managing complex shield stacks and voltage level-shifting in a damp basement enclosure.
What power supply should I use for permanent useful Arduino projects?
Never use a cheap, unbranded USB wall wart for a permanent home installation. They lack over-current protection, thermal shutoffs, and often output noisy DC that causes microcontroller brownouts. For 5V projects, use a sealed, DIN-rail mountable AC-DC converter like the Mean Well IRM series (e.g., IRM-10-5). They are potted in thermally conductive resin, making them immune to basement humidity and dust, and they carry proper UL/CE safety certifications.






