Built-in project · Arduino Uno R3

Sump alarm on an Arduino Uno

A float switch in the sump on an Uno: when the water lifts the float, a buzzer sounds a siren and a red LED lights until the water has gone back down. The whole build, an Arduino Uno and 4 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.

Teaching? Assign it to your class in one click.

Beginner About 15 minutes to build and run. Runs in your browser. Free, and no account needed.

The parts retail for about $32. On Mokxi they're free.

The circuit runs here once the page has loaded.

What you'll learn

  • Reading a normally open switch with INPUT_PULLUP
  • Debouncing with millis so a chattering input does not trip the alarm
  • Using different delays to turn an alarm on and off
  • Why the switch signals the Arduino and the Arduino drives the buzzer
  • Difficulty: Beginner
  • Time: About 15 minutes
  • Board: Arduino Uno R3
  • Parts: 6

How it works

A float switch hangs in the sump. It has a magnet in the float and a reed switch in the stem. With the water low, the switch is open and pin 2 reads HIGH from the internal pull-up. When the water lifts the float, the switch closes and pin 2 reads LOW.

Water slops about, so the sketch does not trust a change right away. It needs the water to stay high for half a second before it sounds the alarm. Once the alarm is on, it stays on until the water has been back down for two seconds.

The alarm lights the red LED on pin 13 and plays a two-tone siren on the buzzer on pin 8, switching tones every quarter second. Once a second it prints the float and alarm state to the serial monitor.

Parts list

6 parts, plus the jumper wires. They retail for about $32; on Mokxi they're free.

Wiring table

Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.

Part and pinConnects to
Float switch, ZP4510 pin 2Arduino Uno R3 pin GND
Buzzer pin 2Arduino Uno R3 pin GND
LED, red pin CArduino Uno R3 pin GND
Resistor, 220 Ω pin 1Arduino Uno R3 pin 13
Buzzer pin 1Arduino Uno R3 pin 8
Float switch, ZP4510 pin 1Arduino Uno R3 pin 2
LED, red pin AResistor, 220 Ω pin 2

The code

The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.

sketch.ino · Arduino Uno R3
// Sump alarm: a float switch in the sump, a buzzer and a red LED.
//
//   pin 2    the float switch (its other wire to GND)
//   pin 8    the buzzer (its other leg to GND)
//   pin 13   the red LED, through 220 ohms
//
// The float switch is a reed in the stem and a magnet in the float. As it
// ships it is normally open: with the water low the float hangs down and the
// reed is open, so pin 2, pulled up by the chip, reads HIGH. When the water
// lifts the float the reed closes and pin 2 reads LOW. Turn the float over on
// its stem and it works the other way around; flip HIGH and LOW below to suit.
//
// Water near the switching level slops about, so a real float chatters. The
// sketch only believes a change that has held for half a second, and once
// the alarm is sounding it stays on until the water has been back down for
// two seconds.
//
// The float is a signal contact, 10 W and half an amp at most: it tells the
// Arduino, and the Arduino drives the buzzer. A pump would go on a relay.

const int FLOAT_SWITCH = 2;
const int BUZZER = 8;
const int LED = 13;

bool alarm = false;
bool lastRaw = false;
unsigned long changedAt = 0;
unsigned long lastReport = 0;

void setup() {
  Serial.begin(115200);
  Serial.println("Mokxi Arduino Uno: sump alarm");
  pinMode(FLOAT_SWITCH, INPUT_PULLUP);
  pinMode(BUZZER, OUTPUT);
  pinMode(LED, OUTPUT);
}

void loop() {
  // LOW means the float is lifted: the water is up.
  bool high = digitalRead(FLOAT_SWITCH) == LOW;
  if (high != lastRaw) {
    lastRaw = high;
    changedAt = millis();
  }
  unsigned long held = millis() - changedAt;
  if (!alarm && high && held >= 500) {
    alarm = true;
    Serial.println("ALARM: water high");
  }
  if (alarm && !high && held >= 2000) {
    alarm = false;
    Serial.println("OK: water back down");
  }

  digitalWrite(LED, alarm ? HIGH : LOW);
  if (alarm) {
    // A two-tone siren, a quarter of a second each.
    tone(BUZZER, (millis() / 250) % 2 ? 1800 : 1200);
  } else {
    noTone(BUZZER);
  }

  if (millis() - lastReport >= 1000) {
    lastReport = millis();
    Serial.print("float ");
    Serial.print(high ? "up" : "down");
    Serial.print(", alarm ");
    Serial.println(alarm ? 1 : 0);
  }
}

Code walkthrough

The key functions of the sketch, and what each one does.

setup sketch.ino

Starts the serial port, then sets the float switch pin as INPUT_PULLUP and the buzzer and LED pins as outputs. The pull-up means the switch needs only one wire to ground.

void setup() {
  Serial.begin(115200);
  Serial.println("Mokxi Arduino Uno: sump alarm");
  pinMode(FLOAT_SWITCH, INPUT_PULLUP);
  pinMode(BUZZER, OUTPUT);
  pinMode(LED, OUTPUT);
}

loop sketch.ino

Reads pin 2 and remembers when it last changed. If the water has been up for 500 ms, alarm turns on. If it has been down for 2000 ms, alarm turns off. Then it sets the LED and plays the siren with tone, or calls noTone. A report prints each second.

void loop() {
  // LOW means the float is lifted: the water is up.
  bool high = digitalRead(FLOAT_SWITCH) == LOW;
  if (high != lastRaw) {
    lastRaw = high;
    changedAt = millis();
  }
  unsigned long held = millis() - changedAt;
  if (!alarm && high && held >= 500) {
    alarm = true;
    Serial.println("ALARM: water high");
  }
  if (alarm && !high && held >= 2000) {
    alarm = false;
    Serial.println("OK: water back down");
  }

  digitalWrite(LED, alarm ? HIGH : LOW);
  if (alarm) {
    // A two-tone siren, a quarter of a second each.
    tone(BUZZER, (millis() / 250) % 2 ? 1800 : 1200);
  } else {
    noTone(BUZZER);
  }

  if (millis() - lastReport >= 1000) {
    lastReport = millis();
    Serial.print("float ");
  // ... 5 more lines in the editor

Troubleshooting

The usual mistakes with this circuit, and the fix for each.

  • The alarm sounds with the water low. This project
    A float turned over on its stem works the opposite way. Swap HIGH and LOW in the read of FLOAT_SWITCH.
  • The alarm waits before sounding. This project
    That is on purpose: the water must stay up for 500 ms. The alarm also stays on for 2 seconds after the water drops.
  • No sound but the LED works. This project
    Check the buzzer: pin 8 on one leg and GND on the other.
  • The switch acts opposite to what you expected: closed when dry, open when wet. Float switch
    The float can be mounted either way up. Turn the float over on the stem to change whether the reed closes or opens when the water rises. Test with a meter.
  • The input reads random values or the pump chatters at the water level. Float switch
    Wire it between the pin and ground with INPUT_PULLUP. Waves make the reed flicker, so add a delay or a short debounce time and keep the float in calm water.
  • The buzzer makes a constant tone, or you cannot change its pitch. Buzzer
    An active buzzer has its own oscillator, so it only beeps on and off. A passive buzzer needs tone() to set pitch. Check which type you have.
  • The buzzer is silent or very quiet. Buzzer
    Check polarity: the plus mark goes to the pin or supply. For loud buzzers, drive them through a transistor instead of straight from a pin.
  • The LED is dim, burns out, or the pin reads wrong because the resistor value is off. Resistor
    Read the color bands again. A 220 ohm to 330 ohm resistor suits a typical LED on 5 V. 10k is a common pull-up or pull-down value. Check with a multimeter if unsure.

Change it and keep it

Open it in the editor, change the circuit or the code, and keep your version in a free account.