A smart irrigation timer built with Arduino and relay automates garden watering schedules, reducing water waste and eliminating the need for manual timing. Unlike basic mechanical timers available at hardware stores (₹200-500), an Arduino-based smart timer can be programmed with multiple daily watering schedules, adjusted for seasons, and expanded with soil moisture sensors for truly intelligent irrigation. This tutorial covers building a complete irrigation timer suitable for Indian home gardens, kitchen gardens, and small farms.
Table of Contents
- Components List
- Wiring Diagram
- Setting Up the DS3231 RTC
- Relay Safety for Mains Power
- Complete Arduino Code
- Adding LCD Status Display
- Upgrading with Soil Moisture Sensor
- Frequently Asked Questions
Components List
- Arduino Uno or Nano (₹200-400)
- DS3231 RTC module with CR2032 battery (₹100-200)
- 5V 1-channel or 4-channel relay module (₹50-200)
- 16×2 LCD display with I2C backpack (₹100-200)
- Push buttons x3 (for menu navigation) (₹30-60)
- 12V solenoid valve (24V AC or 12V DC) (₹200-400)
- 12V DC adapter for solenoid valve power
- Capacitive soil moisture sensor (optional, ₹80-150)
- Project enclosure (₹100-250)
Total cost: ₹900-1,900 for a basic timed system, ₹1,500-2,500 with LCD, moisture sensing, and multi-zone capability. The Arduino Nano is preferred over Uno for its compact size fitting easily in a small enclosure.
Wiring Diagram
| Component | Pin | Arduino Pin |
|---|---|---|
| DS3231 RTC | SDA | A4 |
| DS3231 RTC | SCL | A5 |
| LCD I2C | SDA/SCL | A4/A5 (shared) |
| Relay Module | IN | D8 |
| Button 1 (Menu) | — | D4 |
| Button 2 (Up) | — | D5 |
| Button 3 (Down) | — | D6 |
| Soil Moisture | AOUT | A0 |
Setting Up the DS3231 RTC
The DS3231 maintains accurate time independently even when Arduino power is off, using a CR2032 coin cell battery. On first use, set the time by uploading a sketch with RTClib:
#include <Wire.h>
#include <RTClib.h>
RTC_DS3231 rtc;
void setup() {
rtc.begin();
// Set time: use compile date/time for accurate setting
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// Or manually: rtc.adjust(DateTime(2024, 3, 15, 8, 0, 0));
}
The DS3231 is temperature-compensated and drifts less than 2 minutes per year, making it ideal for irrigation timing. A cheaper DS1307 can drift 5-15 minutes per year in Indian temperature conditions.
Relay Safety for Mains Power
If your irrigation system uses a 230V AC pump or solenoid valve:
- Use a relay rated for minimum 10A at 250V AC (not cheap relay modules claiming 10A that are actually rated much lower)
- Keep the mains side of the relay completely separate from the Arduino/low-voltage side — never bridge the two
- Use heat-shrink tubing on all mains connections; no bare wires
- Install a properly rated fuse (5-10A) on the live wire before the relay
- Have a qualified electrician inspect the mains wiring before powering on
For safety and simplicity, prefer a 12V DC solenoid valve or submersible pump, which can be safely switched by any relay module without mains safety concerns. Most garden drip irrigation systems in India work fine with 12V DC solenoid valves (₹200-400) that operate at the same pressure as municipal water supply (1.5-4 bar).
Complete Arduino Code
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
#define RELAY_PIN 8
LiquidCrystal_I2C lcd(0x27, 16, 2);
RTC_DS3231 rtc;
// Irrigation schedule: up to 4 daily watering events
struct IrrigSchedule {
int startHour, startMin;
int durationMin;
bool enabled;
};
IrrigSchedule schedule[] = {
{6, 0, 15, true}, // 6:00 AM, 15 minutes
{18, 30, 10, true}, // 6:30 PM, 10 minutes
{0, 0, 0, false}, // Disabled
{0, 0, 0, false} // Disabled
};
bool isWateringTime(DateTime now) {
for (auto &s : schedule) {
if (!s.enabled) continue;
if (now.hour() == s.startHour && now.minute() == s.startMin) return true;
// Check if within duration
DateTime schedStart = DateTime(now.year(), now.month(), now.day(), s.startHour, s.startMin, 0);
if (now >= schedStart && now < (schedStart + TimeSpan(0, 0, s.durationMin, 0))) return true;
}
return false;
}
void setup() {
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, HIGH); // Active-LOW relay: HIGH = off
lcd.begin(16, 2);
lcd.backlight();
Wire.begin();
rtc.begin();
}
void loop() {
DateTime now = rtc.now();
bool waterNow = isWateringTime(now);
digitalWrite(RELAY_PIN, waterNow ? LOW : HIGH); // LOW = on for active-LOW relay
lcd.setCursor(0, 0);
lcd.printf("%02d/%02d %02d:%02d:%02d", now.day(), now.month(), now.hour(), now.minute(), now.second());
lcd.setCursor(0, 1);
lcd.print(waterNow ? "IRRIGATING... " : "Next: 6:00 AM ");
delay(1000);
}
Adding LCD Status Display
The 16×2 LCD with I2C backpack (PCF8574) shows current time, irrigation status, and next scheduled watering time. The I2C address is typically 0x27 — run an I2C scanner if it does not detect. The LiquidCrystal_I2C library from Arduino IDE Library Manager supports printf-style formatting with lcd.printf() on recent versions, simplifying display code significantly.
For a more sophisticated display, use an OLED (SSD1306) that provides 128×64 pixels for showing the full weekly schedule, soil moisture bar graph, and next watering countdown in a compact layout.
Upgrading with Soil Moisture Sensor
Add a capacitive soil moisture sensor to irrigate only when actually needed, overriding time-based schedules:
// Add to loop():
int moisture = analogRead(A0);
int moisturePercent = map(moisture, 3200, 1500, 0, 100);
moisturePercent = constrain(moisturePercent, 0, 100);
bool moistureLow = (moisturePercent < 35);
bool waterNow = isWateringTime(now) && moistureLow; // Only water if both time AND soil is dry
lcd.setCursor(0, 1);
if (waterNow) lcd.print("IRRIGATING... ");
else if (!moistureLow) lcd.print("Soil OK: " + String(moisturePercent) + "% ");
else lcd.print("Dry, not time ");
This hybrid approach combines the reliability of time-based scheduling (watering at optimal times regardless of sensor failure) with the intelligence of moisture-based control (skipping irrigation when soil is already adequately moist after unexpected rainfall).
Frequently Asked Questions
How do I adjust irrigation schedules seasonally in India?
Store schedules in Arduino EEPROM so they persist after power cycles. Add a seasonal mode selection button: Summer mode (increase frequency, water early morning and evening), Monsoon mode (disable or greatly reduce irrigation), Winter mode (water once in morning only). Map these to predefined schedule arrays stored in PROGMEM to avoid SRAM overflow. A simpler approach is to use the DS3231’s alarm functionality to trigger watering at specific times rather than polling in the loop.
Can I control multiple irrigation zones with one Arduino?
Yes, using a 4-channel relay module. Each relay controls one zone’s solenoid valve. Power all valves from a common 12V supply; the Arduino’s digital pins control each relay independently. With 4 zones, you can water different garden sections at different times (vegetables in the morning, lawn in the evening, orchard at night). Keep zone schedules non-overlapping to avoid total current draw exceeding your pump or supply capacity.
What happens to my schedule if power goes out?
The DS3231 RTC continues keeping accurate time on its CR2032 battery during power outages — your schedules remain accurate. The Arduino’s EEPROM retains stored schedules without power. When power is restored, the Arduino restarts, reads the current time from DS3231, and resumes the correct schedule automatically. Add a startup delay (30 seconds) before activating any valve after power restoration to ensure stable power before controlling solenoids.
My relay clicks repeatedly without activating the valve. What is wrong?
This is almost always a power supply issue. Solenoid valves draw 200-500mA at 12V during activation — if powered from the same 5V supply as Arduino, the voltage drop when the valve activates causes Arduino to reset, which releases the relay, which allows voltage to recover, causing another Arduino restart (the clicking cycle). Use separate power supplies: 5V USB for Arduino, 12V dedicated adapter for solenoid valves. Connect the grounds together for a common reference.
How do I make the irrigation timer work without internet (completely offline)?
The build described above is already completely offline — it uses only the local DS3231 RTC for timekeeping. No internet, cloud, or Wi-Fi is required. This is ideal for areas with unreliable connectivity. If you later want to add remote monitoring or control, add an ESP8266 module that connects to Wi-Fi when available and uses the Arduino’s offline schedule as a fallback when Wi-Fi is unavailable.
Add comment