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.

Difficulty: Intermediate (Requires basic AC/DC safety awareness and MQTT broker setup)
Time to Build: 3-4 hours
Target Board: Arduino Uno R4 WiFi (ABX00087)

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.

ComponentExact Variant / ModelEst. CostPurpose
MicrocontrollerArduino Uno R4 WiFi (ABX00087)$27.50Logic, WiFi, MQTT processing
Current SensorACS712-20A Module (5V logic)$4.50Verifies pump motor is actually drawing current
Level SensorXKC-Y25-V (Non-contact, 5V out)$14.00Detects high water level through PVC pipe wall
Relay Module5V 2-Channel Optocoupler Relay$3.50Triggers local 120V siren or secondary backup pump
Power SupplyMean Well IRM-10-5 (5V 2A)$12.00Isolated, sealed AC-DC power for the enclosure
EnclosureNEMA 4X Polycarbonate (6x6x4)$22.00Waterproof housing for basement mounting

Pin Mapping Table

Arduino Uno R4 PinModuleModule PinWire Gauge / Notes
5VACS712-20AVCC22 AWG Red
GNDACS712-20AGND22 AWG Black
A0ACS712-20AOUT22 AWG Shielded (Analog)
D2XKC-Y25-VOUT (Signal)22 AWG Blue (Digital Interrupt)
D3Relay ModuleIN122 AWG Yellow
VINMean Well 5V PSU+V18 AWG (Main Power Feed)

Step-by-Step Assembly & Wiring

Safety Callout: You will be routing a 120V AC line to the Mean Well power supply and the ACS712 sensor. De-energize the basement circuit at the main panel, lock out the breaker, and verify dead with a CAT III multimeter before opening any junction boxes. Local code may require a licensed electrician for permanent 120V hardwiring.
  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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

  1. 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.
  2. 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.
  3. 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

  1. 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.
  2. 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 add mqttClient.setUsernamePassword("user", "pass"); to the Arduino code before calling connect().
  3. 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.