Build an intelligent plant watering system that monitors soil moisture and automatically waters your plants when needed! This Arduino project uses capacitive soil sensors, a water pump, and an LCD display to keep your garden thriving even when you're away. Perfect for indoor plants, balcony gardens, or small vegetable patches.
This automated garden system takes the guesswork out of plant care. Using capacitive soil moisture sensors, the Arduino continuously monitors the water content in your soil and triggers a water pump when plants need hydration.
The system displays real-time moisture levels on an LCD screen and can be configured with custom thresholds for different plant types. Whether you have succulents that need minimal water or thirsty tomatoes, this system adapts to your garden's needs.
| Part Name | Qty |
|---|---|
| Arduino UNO | 1 |
| Capacitive Soil Moisture Sensor | 1-4 |
| 5V Mini Water Pump | 1 |
| 5V Relay Module | 1 |
| 16x2 LCD with I2C | 1 |
| Silicone Tubing (6mm) | 1m |
| Water Reservoir Container | 1 |
| Jumper Wires | 1 set |
Follow this pin mapping guide to connect your sensors and actuators to the Arduino UNO:
| Peripheral | Device Pin | Arduino Pin | Notes |
|---|---|---|---|
| Soil Sensor | AOUT | Analog A0 | Moisture Data |
| Relay Module | IN / SIG | Digital 7 | Pump Control |
| LCD Display | SDA | Analog A4 | I2C Data |
| LCD Display | SCL | Analog A5 | I2C Clock |
| Power | VCC / 5V | 5V Pin | Shared VCC Rail |
| Power | GND | GND Pin | Common Ground |
The system operates on a simple but effective principle:
1. Monitor: Soil moisture sensor reads water content (0-100%)
2. Compare: Arduino checks if moisture is below threshold (e.g., 30%)
3. Activate: If dry, relay turns on water pump
4. Water: Pump runs until moisture reaches target level (e.g., 60%)
5. Display: LCD shows real-time moisture and system status
Use a capacitive sensor (not resistive) for longer life. Keep electronics away from water. Always include a timeout to prevent overwatering if the sensor fails.
Before wiring everything, test your sensor. Read values in dry air (your "dry" value, typically ~520) and submerged in water (your "wet" value, typically ~260). These will be used to map to 0-100%.
Connect the sensor VCC to Arduino 5V, GND to GND, and the analog output (AOUT in (A) to analog pin A0. If using multiple sensors, use A0, A1, A2, etc.
Wire relay VCC to 5V, GND to GND, and IN to digital pin 7. Connect the water pump's positive wire through the relay's NO (normally open) terminal.
Connect the I2C LCD: SDA to A4, SCL to A5, VCC to 5V, and GND to GND. Install the LiquidCrystal_I2C library via Arduino Library Manager.
Connect silicone tubing from the water reservoir to the pump inlet, and from the pump outlet to your plant pot. Secure all connections to prevent leaks.
Upload the code, then test by removing the sensor from soil. The pump should activate. Insert into moist soil to verify it stops. Adjust thresholds as needed.
// Smart Garden Watering System // MakersDeck Arduino Project #include <Wire.h> #include <LiquidCrystal_I2C.h> // Pin definitions #define MOISTURE_PIN A0 #define PUMP_RELAY 7 // Calibration values (adjust for your sensor) #define DRY_VALUE 520 #define WET_VALUE 260 // Threshold settings #define DRY_THRESHOLD 30 // Start watering below this % #define WET_THRESHOLD 60 // Stop watering above this % #define PUMP_TIMEOUT 30000 // Max pump runtime (30 sec) LiquidCrystal_I2C lcd(0x27, 16, 2); bool pumpRunning = false; unsigned long pumpStartTime = 0; void setup() { Serial.begin(9600); lcd.init(); lcd.backlight(); pinMode(PUMP_RELAY, OUTPUT); digitalWrite(PUMP_RELAY, LOW); lcd.setCursor(0, 0); lcd.print("Smart Garden"); lcd.setCursor(0, 1); lcd.print("Initializing..."); delay(2000); } int getMoisturePercent() { int raw = analogRead(MOISTURE_PIN); // Map raw value to percentage int percent = map(raw, DRY_VALUE, WET_VALUE, 0, 100); return constrain(percent, 0, 100); } void loop() { int moisture = getMoisturePercent(); // Control pump with hysteresis if (moisture < DRY_THRESHOLD && !pumpRunning) { pumpRunning = true; pumpStartTime = millis(); digitalWrite(PUMP_RELAY, HIGH); } if (pumpRunning) { // Stop if wet enough or timeout if (moisture >= WET_THRESHOLD || (millis() - pumpStartTime > PUMP_TIMEOUT)) { pumpRunning = false; digitalWrite(PUMP_RELAY, LOW); } } // Update display lcd.clear(); lcd.setCursor(0, 0); lcd.print("Moisture: "); lcd.print(moisture); lcd.print("%"); lcd.setCursor(0, 1); if (pumpRunning) { lcd.print("WATERING..."); } else if (moisture < DRY_THRESHOLD) { lcd.print("Soil is DRY"); } else { lcd.print("Soil is OK"); } delay(1000); }