DIY Water Level Indicator for Tanks (2026 Updated Version) — Simple & Reliable
Build a reliable, low-cost water level indicator for overhead or underground tanks. This 2026 updated guide covers three versions: (A) Basic float-switch/sensor-based indicator, (B) Arduino 4-level digital indicator, and (C) Ultrasonic non-contact sensor version. All designs are beginner-friendly with practical troubleshooting, anti-corrosion techniques, and enclosure waterproofing.
Why build your own water level indicator?
Commercial indicators are fine, but a DIY unit gives you more control, better repair options, and significantly lower cost over the life of the system.
- Cost savings — build for a fraction of retail price, especially if you already have basic tools.
- Custom alerts — multiple levels, buzzer patterns, and optional WiFi/app notifications.
- Easy repairability — you can replace only the failed sensor, relay, or board instead of the full unit.
- Scalability — start with LEDs, then add LCD, app monitoring, or auto-pump control later.
- Learning opportunity — understand sensors, microcontrollers, and safe mains isolation.
Sensor types compared
Before picking a circuit, quickly compare the main sensor options: conductive probes, float switches, and ultrasonic distance sensors. Each has trade-offs in cost, reliability, and maintenance.
| Sensor Type | Approx. Cost | Pros | Cons | Best For |
|---|---|---|---|---|
| Conductive Probes | ₹60–₹200 | Very cheap, easy multi-level sensing | Can corrode over time, needs cleaning | Clean water tanks, budget builds |
| Float Switches | ₹150–₹400 | Robust, no electrolytic corrosion | Mechanical wear, usually single-level | Sumps, slightly dirty water |
| Ultrasonic (HC-SR04) | ₹100–₹250 | Non-contact, no corrosion, continuous level | Needs dry mounting zone, sensitive to splashes | Overhead tanks, long-term low-maintenance |
| Capacitive Sensors | ₹300–₹800 | Can sense through plastic walls, no direct contact | More expensive, needs careful calibration | Food-grade/liquids where probes not allowed |
Which version should you choose?
Pick one based on features you want and how much complexity you are comfortable with:
- Basic (No MCU): Float switches or conductive probes driving LEDs / buzzers. Very easy, low cost, and robust for simple “tank full / tank empty” indication.
- Smart (Arduino / ESP8266): Multiple level detection, LCD or web dashboard, pump auto-control, and optional push notifications.
- Ultrasonic (Non-contact): Ultrasonic sensor at the top of the tank to measure distance to water and display percentage full, ideal where probe corrosion is a concern.
Parts & recommended buys
Replace the # in each Buy button with your Amazon affiliate link.
Float Switch (Mini) — Basic level sensor
Mechanical float switch for on/off detection. Ideal for single-level low-cost builds or overflow alarms.
Buy on Amazon
Probe / Conductive Sensor — Multi-level
Simple stainless-steel probe wires used to detect water contact (pull-down or pull-up logic). Use 3–5 probes for Empty, Low, Half, Full, and Overflow.
Buy on Amazon
Arduino Nano / Uno
Use Nano for compact installations. Arduino reads probes or ultrasonic sensor and drives LEDs, LCD, and relays.
Buy on Amazon
NodeMCU (ESP8266) — Optional WiFi
Add notifications or a simple web dashboard using ESP8266. Great for remote alerts and mobile app integration.
Buy on Amazon
Relay Module, LEDs, Buzzer
Use relays to control pump/signal and LEDs for multi-level indicators. Add a small buzzer for low-water or overflow alarms.
Buy on Amazon
HC-SR04 Ultrasonic Sensor
Non-contact distance measurement (2 cm – 400 cm). Perfect for overhead tanks where probes can corrode.
Buy on Amazon
16×2 LCD with I2C Module
Displays water level (%), pump status, and error messages. I2C module reduces wiring to only 4 pins.
Buy on Amazon
IP65 Waterproof Enclosure (15×10×7cm)
Protects electronics from rain, dust, and insects. Essential for outdoor tank installations.
Buy on Amazon
Waterproof enclosure guide
A good circuit can still fail if moisture enters the box. Spend a few minutes planning the enclosure and cable entry to extend the life of your system.
- Use an IP65-rated plastic enclosure with a gasketed lid for all outdoor or semi-outdoor installations.
- Bring cables through proper cable glands instead of open holes; tighten glands firmly around cable jackets.
- Mount the enclosure vertically on a wall, slightly under a shade or balcony to avoid direct rain.
- Keep the PCB at least 1–2 cm above the enclosure bottom so any condensation or minor leaks do not pool under the board.
- Optionally drop a small silica gel packet inside the box to absorb moisture over time.
Tip: After wiring, lightly spray around the box with water (or use a mug) for a few minutes and check inside after 30–60 minutes for any sign of moisture.
Basic circuit (probe or float switch)
The simplest approach uses either float switches at two levels (FULL and EMPTY) or multiple conductive probes. Each sensor closes or opens a circuit when water reaches that height. Drive LEDs or relays directly with transistors or an opto/relay module.
- Mount float switch at overflow level → connects to buzzer/LED when full.
- Mount probe or second float near minimum level → triggers low-water alarm.
- Use a small NPN transistor (e.g., 2N2222) as a switch to power LEDs from a 12V supply or use a relay module for pumps.
Tip: For conductive probes, use resistors (10k pull-down/up) and never run mains through probes — keep probes in low-voltage DC circuit only.
For better long-term life, use stainless steel screws/rods as probes and avoid copper directly in water. If corrosion is still a problem in hard water, you can periodically reverse polarity or switch to an ultrasonic sensor version.
Smart circuit (Arduino / ESP8266) — 4 level indicator
This version detects four levels: Empty, Low, Half, Full and can display status using LEDs, an LCD, or even a simple web interface. You can also switch a relay to control a pump automatically.
Connections (summary)
- Probes A, B, C, D → Arduino digital inputs with 10k pull-down resistors.
- LEDs → Arduino digital outputs with 330Ω resistors for current limiting.
- Relay (optional) → Relay module IN → Arduino output to switch pump via mains-rated contacts.
- LCD I2C (optional) → SDA (A4), SCL (A5) on Arduino Uno/Nano, powered from 5V.
- ESP8266 variant replaces Arduino and uses digital pins + WiFi library for notifications or Blynk-style dashboards.
Safety notes
- Use an isolated 5V power supply for the microcontroller. Keep all mains wiring physically separated and inside proper junction boxes.
- Use stainless-steel probes or dedicated level sensors to reduce corrosion; avoid bare copper in water.
- Always include a flyback diode across relay coils and use proper earthing for the pump/motor.
Ultrasonic non-contact version
The ultrasonic version uses a sensor like HC-SR04 mounted at the top of the tank, pointing down at the water surface. It measures the distance to water and converts it into a percentage full value in software.
- Mount the sensor inside a small protective hood or pipe so splashes and direct wind do not affect readings.
- Connect Trig → Arduino D9, Echo → Arduino D10, plus 5V and GND (check sensor voltage compatibility).
- Measure empty-tank distance and full-tank distance once, then calibrate your
map()function accordingly. - Because there is no direct water contact, there is no corrosion and almost no maintenance apart from occasional cleaning of the sensor face.
For deep or foamy tanks, add some software averaging (for example average 5–10 readings) to reduce random fluctuations.
Wiring diagrams (ASCII)
Basic probe + LED (no MCU)
[Probe Top] -----[Pull-down 10k]----->LED Full (via NPN transistor)
[Probe Mid] -----[Pull-down 10k]----->LED Half
[Probe Low] -----[Pull-down 10k]----->LED Low/Buzzer
Vcc (5V) ------------------------------+
Arduino 4-level (simplified)
Probes: D2 (Empty), D3 (Low), D4 (Half), D5 (Full)
LEDs: D6 (Empty LED), D7 (Low LED), D8 (Half LED), D9 (Full LED)
Relay: D10 -> Relay IN (pump control)
GND: Common ground
Arduino with Ultrasonic + LCD (simplified)
Ultrasonic:
Trig -> D9
Echo -> D10
VCC -> 5V
GND -> GND
LCD I2C:
SDA -> A4
SCL -> A5
VCC -> 5V
GND -> GND
Code — Arduino & ESP8266 examples
Arduino (4-level indicator with optional LCD)
// Arduino 4-level Water Indicator (basic + LCD skeleton)
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Adjust address if needed
const int probeEmpty = 2;
const int probeLow = 3;
const int probeHalf = 4;
const int probeFull = 5;
const int ledEmpty = 6;
const int ledLow = 7;
const int ledHalf = 8;
const int ledFull = 9;
const int relayPin = 10; // optional pump control
void setup() {
Serial.begin(9600);
pinMode(probeEmpty, INPUT);
pinMode(probeLow, INPUT);
pinMode(probeHalf, INPUT);
pinMode(probeFull, INPUT);
pinMode(ledEmpty, OUTPUT);
pinMode(ledLow, OUTPUT);
pinMode(ledHalf, OUTPUT);
pinMode(ledFull, OUTPUT);
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, LOW); // pump off
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Water Level");
}
void loop() {
bool e = digitalRead(probeEmpty);
bool l = digitalRead(probeLow);
bool h = digitalRead(probeHalf);
bool f = digitalRead(probeFull);
// LEDs (light when probe is HIGH)
digitalWrite(ledEmpty, e);
digitalWrite(ledLow, l);
digitalWrite(ledHalf, h);
digitalWrite(ledFull, f);
// Simple pump logic: turn on pump if below low and off when full
if (!l) {
digitalWrite(relayPin, HIGH); // Pump ON
} else if (f) {
digitalWrite(relayPin, LOW); // Pump OFF
}
// Simple LCD status line
lcd.setCursor(0,1);
if (!e && !l && !h && !f) {
lcd.print("Empty ");
} else if (l && !h && !f) {
lcd.print("Low ");
} else if (h && !f) {
lcd.print("Half ");
} else if (f) {
lcd.print("Full ");
} else {
lcd.print("Changing... ");
}
delay(500);
}
Arduino (Ultrasonic percentage example)
// Ultrasonic water level (percentage) example
const int trigPin = 9;
const int echoPin = 10;
// Adjust these to match your tank dimensions (in cm)
const int tankEmptyDistance = 100; // distance when tank is empty
const int tankFullDistance = 20; // distance when tank is full
long readDistance() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH, 30000); // timeout 30ms
long distance = duration * 0.034 / 2;
return distance;
}
void setup() {
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
long d = readDistance();
int level = map(d, tankEmptyDistance, tankFullDistance, 0, 100);
if (level < 0) level = 0;
if (level > 100) level = 100;
Serial.print("Distance: ");
Serial.print(d);
Serial.print(" cm Level: ");
Serial.print(level);
Serial.println("%");
delay(1000);
}
ESP8266 (NodeMCU) — Simple web status (conceptual)
// NodeMCU example (conceptual only)
// Shows levels on a simple web page (probe-based)
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
const int probePins[] = {D2, D3, D4, D5}; // adjust pins
ESP8266WebServer server(80);
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASS";
String readLevels() {
String out = "";
for (int i = 0; i < 4; i++) {
out += String(digitalRead(probePins[i]));
if (i < 3) out += ",";
}
return out;
}
void handleRoot() {
String html = "<h1>Tank Levels</h1>";
html += "<p>Probes (Empty,Low,Half,Full): ";
html += readLevels();
html += "</p>";
server.send(200, "text/html", html);
}
void setup() {
Serial.begin(115200);
for (int i = 0; i < 4; i++) {
pinMode(probePins[i], INPUT);
}
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("IP: ");
Serial.println(WiFi.localIP());
server.on("/", handleRoot);
server.begin();
}
void loop() {
server.handleClient();
}
Note: ESP8266 code above is intentionally minimal for clarity. In a production build, add debouncing, input protection, authentication for the web page, and timeouts/reconnect logic for WiFi.
Testing & calibration
- Dry-run test: Keep probes dry and confirm all LEDs are OFF (or reflect the expected “Empty” state). Make sure the pump does not start.
- Fill to low/half: Add water until it touches the Low or Half probe and confirm the respective LED turns ON and LCD/web status updates.
- Fill to full: Water should reach the top probe and Full LED should indicate. If configured, the pump should stop at this point.
- Ultrasonic calibration: Measure distance when tank is empty and full, then plug those values into the code and verify the percentage outputs are sensible.
- Debounce: If readings bounce due to waves, add a short software averaging delay (100–300 ms) or move probes slightly away from the inlet pipe.
Troubleshooting & maintenance
- False readings: Often caused by probe corrosion or mineral buildup. Clean probes with a brush and, if recurring, switch to stainless steel or consider an ultrasonic sensor.
- Intermittent LEDs: Usually due to loose wiring, poor solder joints, or weak pull-down resistors. Re-check screw terminals and re-solder suspicious joints.
- Pump keeps running: Check relay wiring, logic inversion in code, and whether the Full probe is actually making contact with water. Add a manual override switch for safety.
- Power issues: Use a stable 5V regulator for MCU and, if the relay draws more current, power relays from a separate supply with common ground.
- Ultrasonic noise: If the ultrasonic sensor gives random spikes, add simple averaging in code and ensure the sensor has a clear, flat view of the water surface.
Maintenance checklist
- Inspect probes monthly and clean any mineral buildup or algae deposits.
- Check all cable glands, seals, and the enclosure lid to prevent moisture ingress into the electronics box.
- Test float switches for mechanical wear annually by manually lifting the float and watching the LED/buzzer response.
- For ultrasonic setups, gently wipe the sensor face with a soft cloth every few months.
Long-term maintenance schedule
- Monthly: Visual inspection of cables, probes, and enclosure; quick test of LEDs/buzzer or LCD display.
- Quarterly: Run a full tank cycle (Empty → Full → Empty) and confirm pump control logic works as expected.
- Yearly: Re-tighten terminals, verify relay operation under load, and back up any custom code for Arduino/ESP8266.
- When relocating: Recalibrate probes or ultrasonic distances for the new tank height and re-label any level indicators.
FAQs
1. Can I use mains voltage sensors directly in the tank?
No. Keep probes and sensors on low-voltage DC circuits only. Use properly rated relays or contactors to switch mains loads like pumps.
2. How many probes should I use?
Three to five probes are typical: Empty, Low, Half, Full (and optional Overflow). More probes give finer control and clearer indication.
3. Will conductive probes corrode?
Yes, basic metal probes can corrode over time, especially in hard water. Use stainless steel or switch to ultrasonic/capacitive sensors for longer life.
4. Can I use ultrasonic for underground sumps?
You can if you have a clear, vertical mounting position at the top and a relatively calm water surface. For narrow, very deep, or covered sumps, float switches may be simpler.
5. How do I reduce false triggering in ESP8266/Arduino readings?
Add software debouncing (like averaging several readings), keep signal wires short, and separate them from mains power cables to reduce noise.
6. Capacitive vs conductive probes — which is better?
Conductive probes are cheaper and easier but need cleaning. Capacitive sensors are more expensive but do not require direct contact with water and work better for long-term installations.
7. Is there a risk of the pump relay sparking or failing?
Yes, if the relay is underrated for motor current or wired incorrectly. Use a relay module rated above your pump’s starting current and include a snubber or surge protection if needed.
8. Can I power the indicator from a battery or solar panel?
Yes. A small 5V power bank or 6–12V battery with a regulator is enough for the electronics. For solar, add a charge controller and size your panel and battery for at least one cloudy day of backup.
9. What happens if WiFi is down in the ESP8266 version?
The local logic (probes, LEDs, pump relay) can still run offline if coded that way. Only the app/dashboard and remote alerts will stop until WiFi reconnects.
10. How do I extend the life of probes in very hard water?
Use thicker stainless-steel rods, keep current through probes very low (via large resistors), clean them periodically, or upgrade to an ultrasonic solution for zero-contact sensing.














