An irrigation pump controller using a float switch and timer relay provides reliable automatic pump management for farm water systems — preventing dry running damage and ensuring consistent water delivery on schedule. For millions of Indian farmers who irrigate at night or during off-peak electricity hours, an automated pump controller with safety features saves equipment and reduces manual intervention. This guide covers building a comprehensive irrigation pump controller with Arduino, float switches, timer control, and GSM monitoring.
Table of Contents
- Common Irrigation Pump Problems in India
- Understanding Float Switches
- Components Required
- Circuit and Safety Design
- Arduino Controller Code
- GSM Alert Integration
- Timer and Scheduling Logic
- Frequently Asked Questions
Common Irrigation Pump Problems in India
Irrigation pump failures cause significant economic losses for Indian farmers:
- Dry running: Pump runs without water — destroys impeller in 5-10 minutes. Happens when sump/well runs low. Costs Rs 3,000-15,000 for motor rewinding
- Overflow: Overhead tank overflows due to inattention — wastes water and causes property damage
- Phase failure: Single-phase condition in 3-phase motors causes winding burnout — most common cause of motor failure in Indian agriculture
- Manual operation errors: Farmer falls asleep during night irrigation — pump runs for 10+ hours over-watering crops
- Power surge damage: Voltage fluctuations during rural power restoration — starter relay pitting and motor insulation damage
An automated controller with float switch protection, timer cutoff, and phase monitoring prevents all of these failure modes at a hardware cost of Rs 1,500-3,000.
Understanding Float Switches
Float switches are simple level sensors with a ball that rises/falls with water level, opening or closing a switch contact:
- Normally Open (NO): Circuit opens when float rises. Used for overflow protection — cuts power when tank is full.
- Normally Closed (NC): Circuit opens when float falls. Used for dry-run protection — cuts power when well/sump level drops.
- Tethered float switches: Length of cable determines activation depth. Standard sizes: 2m, 3m, 5m cable.
For a typical Indian farm water system:
- Source (borewell/sump) float switch: NC type at minimum water level — stops pump if source runs dry
- Destination (overhead tank) float switch: NO type at maximum level — stops pump when tank is full
Components Required
Products from Zbotic
- 5V/12V Relay Control Module — for pump control relay stage (low-voltage side)
- 12V DC Mini Submersible Water Pump — suitable for 12V DC irrigation pump systems
Full controller parts list:
- Arduino Nano or Uno
- 2x Float switch (one NC for source, one NO for destination tank)
- DS3231 RTC module (for timer scheduling)
- 16×2 LCD with I2C adapter
- Single-channel relay module (or SSR for 3-phase motors)
- Push buttons (3x: start, stop, set)
- SIM800L GSM module (optional, for SMS alerts)
- Current sensor module (ACS712, for pump running confirmation)
- 12V 2A power supply for Arduino/relay
- Contactor (for 3-phase 5HP+ motors) + relay interface
Circuit and Safety Design
Safety-critical wiring:
- Source float switch NC contact -> Arduino GPIO2 (interrupt, pulled HIGH)
- Destination float switch NO contact -> Arduino GPIO3 (interrupt, pulled HIGH)
- Current sensor ACS712 OUT -> Arduino A0 (pump running confirmation)
- Relay IN -> Arduino D7 (pump control)
- RTC DS3231 SDA -> A4, SCL -> A5
- LCD I2C SDA -> A4, SCL -> A5
- Start button -> D8, Stop button -> D9, Set button -> D10
Important: The relay module’s COM and NO terminals switch the coil of a properly rated contactor for AC motor loads. Never switch AC motor currents directly through a small relay module — use a motor starter contactor rated for the motor HP. The Arduino+relay module only controls the contactor coil (24V or 230V AC, low current).
Arduino Controller Code
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <EEPROM.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
RTC_DS3231 rtc;
// I/O Pins
#define SOURCE_FLOAT 2 // NC - LOW when level too low (pump dry run)
#define DEST_FLOAT 3 // NO - LOW when tank full
#define PUMP_RELAY 7 // LOW = pump ON
#define CURRENT_PIN A0
#define BTN_START 8
#define BTN_STOP 9
// Runtime tracking
bool pumpOn = false;
unsigned long pumpStartTime = 0;
unsigned long maxRunMinutes = 120; // 2 hour max run per cycle
// Schedule: pump at specific hours if float allows
int scheduleHours[] = {6, 14, 20}; // 6am, 2pm, 8pm
bool scheduledThisHour[24] = {false};
float readCurrent() {
int raw = analogRead(CURRENT_PIN);
float v = (raw - 512) * (5.0 / 1024.0); // Centre = 2.5V at zero current
return abs(v / 0.185); // ACS712-5A: 185mV/A
}
bool isSourceSafe() { return digitalRead(SOURCE_FLOAT) == HIGH; } // HIGH = water present (NC float normally closed)
bool isDestFull() { return digitalRead(DEST_FLOAT) == LOW; } // LOW = full (NO float closed when full)
bool isPumpRunning() { return readCurrent() > 0.5; } // More than 0.5A = pump actually running
void startPump() {
if (!isSourceSafe()) {
lcd.setCursor(0, 1);
lcd.print("ERR: Source LOW! ");
return;
}
if (isDestFull()) {
lcd.setCursor(0, 1);
lcd.print("Tank full, skip ");
return;
}
digitalWrite(PUMP_RELAY, LOW); // Pump ON
pumpOn = true;
pumpStartTime = millis();
Serial.println("Pump STARTED");
}
void stopPump(const char* reason) {
digitalWrite(PUMP_RELAY, HIGH); // Pump OFF
pumpOn = false;
Serial.print("Pump STOPPED: ");
Serial.println(reason);
lcd.setCursor(0, 1);
lcd.print("Stop:"); lcd.print(reason);
lcd.print(" ");
}
void setup() {
Serial.begin(9600);
Wire.begin();
lcd.init(); lcd.backlight();
rtc.begin();
EEPROM.get(0, maxRunMinutes);
if (maxRunMinutes < 5 || maxRunMinutes > 480) maxRunMinutes = 120;
pinMode(SOURCE_FLOAT, INPUT_PULLUP);
pinMode(DEST_FLOAT, INPUT_PULLUP);
pinMode(PUMP_RELAY, OUTPUT); digitalWrite(PUMP_RELAY, HIGH);
pinMode(BTN_START, INPUT_PULLUP);
pinMode(BTN_STOP, INPUT_PULLUP);
lcd.print("Pump Controller");
lcd.setCursor(0,1);
lcd.print("v1.0 - Ready");
delay(2000);
}
void loop() {
DateTime now = rtc.now();
// Manual controls
if (!digitalRead(BTN_START) && !pumpOn) {
startPump();
delay(500);
}
if (!digitalRead(BTN_STOP) && pumpOn) {
stopPump("Manual");
delay(500);
}
// Safety checks while running
if (pumpOn) {
unsigned long runMinutes = (millis() - pumpStartTime) / 60000;
if (!isSourceSafe()) {
stopPump("SrcLow");
} else if (isDestFull()) {
stopPump("TankFull");
} else if (runMinutes > maxRunMinutes) {
stopPump("Timeout");
} else if (!isPumpRunning()) {
// Current sensor: pump should be drawing current
static int noCurrentCount = 0;
noCurrentCount++;
if (noCurrentCount > 5) { // 5 consecutive no-current readings
stopPump("NoCurrent");
noCurrentCount = 0;
}
}
}
// Scheduled operation
int hr = now.hour();
for (int i = 0; i < 3; i++) {
if (hr == scheduleHours[i] && now.minute() == 0 && !scheduledThisHour[hr]) {
scheduledThisHour[hr] = true;
startPump();
}
}
if (hr == 0 && now.minute() == 0) memset(scheduledThisHour, false, sizeof(scheduledThisHour));
// Display
lcd.setCursor(0, 0);
lcd.print(now.hour(), DEC); lcd.print(":");
if (now.minute() < 10) lcd.print("0");
lcd.print(now.minute(), DEC);
lcd.print(pumpOn ? " PUMP:ON " : " PUMP:off ");
lcd.setCursor(0, 1);
lcd.print("Src:");
lcd.print(isSourceSafe() ? "OK " : "LOW");
lcd.print(" Dst:");
lcd.print(isDestFull() ? "FULL" : "ok ");
delay(1000);
}
GSM Alert Integration
Add SMS alerts for critical events:
- Pump started (scheduled or manual)
- Pump stopped (reason: source low, tank full, timeout, no current)
- Motor current anomaly (phase failure or bearing seizure)
- Daily “all OK” status at 8am
Use SIM800L connected to Arduino’s SoftwareSerial pins. Critical alerts use GSM, routine reports use GPRS/SMS depending on connectivity at the farm location.
Timer and Scheduling Logic
The RTC-based scheduler supports three modes:
- Time-based: Run at fixed hours (6am, 2pm, 8pm) subject to float switch conditions
- Duration-based: After starting, run for exactly N minutes (operator sets max run time)
- Continuous-duty: Keep pump on as long as source has water and destination is not full (reservoir-to-reservoir transfer)
EEPROM stores the schedule so it persists across power cuts — common in Indian rural areas with frequent interruptions.
Frequently Asked Questions
Can I use this controller for a 3-phase 5HP borewell motor?
Yes, but the Arduino relay module controls only the contactor coil — never the motor power directly. Use a rated motor starter contactor (Siemens, L&T, or equivalent) with coil voltage matching your supply (220V or 24V). Add an overload relay for motor thermal protection. The Arduino relay energises/de-energises the contactor coil.
How does the current sensor detect dry running?
When a pump runs dry (no water), it draws significantly less current than when pumping water (10-40% less, depending on pump type). The ACS712 current sensor detects this drop. Calibrate the “pump loaded” current threshold during normal operation — any reading below 50% of normal current for more than 10 seconds indicates a problem.
Can the controller handle power failures and restart automatically?
Yes. On power restoration, the Arduino restarts and checks if the current time matches a scheduled run time. If the float switch conditions are met, it restarts the pump. Add a 30-second startup delay after power restoration to allow voltage to stabilise before starting the motor.
What is the maximum pump power this controller can manage?
With a properly rated contactor, there is no practical upper limit. 10HP (7.5kW) and 20HP (15kW) borewell pumps are commonly controlled with similar Arduino-based controllers in India. The Arduino only controls the low-current contactor coil — the actual motor current flows through the contactor, not the controller.
Add comment