Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.
Plant Watering System: the finished build
ESP32Home automation

Automatic plant watering system (ESP32)

Waters your plants in short bursts when the soil gets dry.

Difficulty
Easy
Build time
1 h
Parts cost
₹860 · $10
Verified — core esp32 3.3.12, 3 Nov 2026Compile-only

Community draft — report a mistake

Parts list

PartQtyApprox.Buy
ESP32 DevKit V1 (30-pin)1₹380Buy ESP32 DevKit V1 (30-pin)
Capacitive soil moisture sensor v1.21₹80Buy Capacitive soil moisture sensor v1.2
1-channel relay module, 5 V coil, 3.3 V-trigger (active-LOW)1₹70Buy 1-channel relay module, 5 V coil, 3.3 V-trigger (active-LOW)
5 V submersible mini pump + 1 m silicone tube1₹150Buy 5 V submersible mini pump + 1 m silicone tube
5 V 2 A adapter for the pump1₹150Buy 5 V 2 A adapter for the pump
Jumper wires1₹30Buy Jumper wires
Total₹860

Affiliate disclosure: “Buy” links may earn FlashReady a small commission at no extra cost to you. Prices are indicative.

Wiring

ESP32 DevKit V1Only the pins used are shown · 3.3 V logic5 V 2 A pump adapterCapacitive soil moisture sensor v1.21-channel relay module (5 V coil)+5VGNDD34D26GNDVIN3V3GNDVCCAOUTDC+DC−INCOMNO → Pump + (pump − to the adapter’s GND)NC (not connected)
Every connection
ESP32 DevKit V1Part · pinWireNotes
—1-channel relay module (5 V coil) · NO—To Pump + (pump − to the adapter’s GND) (not drawn)
3V3Capacitive soil moisture sensor v1.2 · VCCred3.3 V keeps AOUT inside the ESP32’s ADC range
GNDCapacitive soil moisture sensor v1.2 · GNDblack
D34Capacitive soil moisture sensor v1.2 · AOUTpurpleADC1 — works with Wi-Fi on
VIN1-channel relay module (5 V coil) · DC+red
GND1-channel relay module (5 V coil) · DC−black
D261-channel relay module (5 V coil) · INgreenActive-LOW
5 V 2 A pump adapter · +5V1-channel relay module (5 V coil) · COMredRelay NO → pump +; pump − → the adapter’s GND. Low voltage only

Board quirks: Calibrate <code>RAW_DRY</code> and <code>RAW_WET</code> for your sensor: print the raw value in air and in water. The relay switches the pump’s own 5 V supply — low voltage only. Don’t run the pump from the ESP32’s pins.

Code

plant-watering-system.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// Plant watering system — ESP32 DevKit V1 + capacitive soil sensor + relay module + 5 V DC pump.
// Waters in short bursts when the soil is dry, then waits for the water to soak in.
// Soil AOUT → D34 (ADC1, works with Wi-Fi on). Relay IN → D26 (active-LOW). The relay switches the
// pump's own 5 V supply — low voltage only, never mains.
constexpr uint8_t SOIL_PIN = 34;
constexpr uint8_t RELAY_PIN = 26;
constexpr bool RELAY_ACTIVE_LOW = true;

// Calibrate: read the raw value with the probe in dry air and in a glass of water.
constexpr int RAW_DRY = 3000;
constexpr int RAW_WET = 1300;
constexpr int WATER_BELOW_PERCENT = 35;
constexpr unsigned long PUMP_MS = 5000;                 // one watering burst
constexpr unsigned long SOAK_MS = 60UL * 1000;          // let it soak before measuring again
constexpr uint8_t MAX_BURSTS_PER_HOUR = 6;              // safety: a broken sensor can't flood the pot

unsigned long hourStart = 0;
uint8_t burstsThisHour = 0;

void setPump(bool on) {
  digitalWrite(RELAY_PIN, (on != RELAY_ACTIVE_LOW) ? HIGH : LOW);
}

int moisturePercent() {
  long sum = 0;
  for (int i = 0; i < 16; i++) {
    sum += analogRead(SOIL_PIN);
    delay(5);
  }
  int raw = sum / 16;
  return constrain(map(raw, RAW_DRY, RAW_WET, 0, 100), 0, 100);
}

void setup() {
  digitalWrite(RELAY_PIN, HIGH);        // pump off before the pin becomes an output
  pinMode(RELAY_PIN, OUTPUT);
  setPump(false);
  analogReadResolution(12);
  Serial.begin(115200);
}

void loop() {
  if (millis() - hourStart > 3600UL * 1000) {
    hourStart = millis();
    burstsThisHour = 0;
  }
  int moisture = moisturePercent();
  Serial.printf("Soil moisture: %d%%\n", moisture);

  if (moisture < WATER_BELOW_PERCENT && burstsThisHour < MAX_BURSTS_PER_HOUR) {
    Serial.println("Dry — watering");
    setPump(true);
    delay(PUMP_MS);
    setPump(false);
    burstsThisHour++;
    delay(SOAK_MS);
  } else {
    if (burstsThisHour >= MAX_BURSTS_PER_HOUR) Serial.println("Burst limit reached — check the sensor and tank");
    delay(10000);
  }
}

Compiled for esp32 on esp32 3.3.12 · 3 Nov 2026

How it works

A capacitive soil sensor measures how well the soil stores charge, which rises with water content. Unlike the cheap two-prong resistive probes, it has no exposed metal to corrode, so it lasts for months in a pot.

The ESP32 reads the sensor on GPIO34 (an ADC1 pin, so it still works when you add Wi-Fi later), averages 16 readings and maps them onto 0–100 % using two calibration numbers. Below 35 % it runs the pump for five seconds, then waits a minute for the water to soak in before measuring again — otherwise it would keep pumping while the water was still on its way down.

A burst limit caps watering at six bursts an hour. If the sensor falls out of the pot or breaks, the worst case is a little extra water rather than a flooded balcony.

The pump runs on its own 5 V adapter through the relay’s COM and NO contacts. It’s all low voltage — no mains anywhere in this build.

Troubleshooting

Moisture jumps around

Push the probe in up to its line and keep the electronics above the soil — water on the top of the board gives wild readings.

The pump runs but no water comes out

Mini pumps can’t self-prime: it must sit under water in the tank. Check for air in the tube.

It waters too much

Raise SOAK_MS so water has time to spread before the next measurement, or lower WATER_BELOW_PERCENT.

Upgrades

  • Add a float switch so the pump never runs a dry tank.
  • Send a phone notification when the tank needs refilling.
  • Water several pots with a second sensor and pump.

↑↓ to move · Enter to open