Built-in project · Arduino Uno R3

Mini pump plant waterer on an Arduino Uno

A capacitive soil probe watches the pot; when it reads dry, a relay runs the mini pump for three seconds, then waits for the water to soak in. The whole build, an Arduino Uno and 3 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.

Teaching? Assign it to your class in one click.

Beginner About 25 minutes to build and run. Runs in your browser. Free, and no account needed.

The parts retail for about $35. On Mokxi they're free.

The circuit runs here once the page has loaded.

What you'll learn

  • A capacitive sensor reads higher when it is dry
  • Turning raw counts into a percentage with two calibration points
  • Switching a pump with a relay and a separate supply
  • Waiting after an action so a slow sensor can catch up
  • Difficulty: Beginner
  • Time: About 25 minutes
  • Board: Arduino Uno R3
  • Parts: 6

How it works

A capacitive soil probe on A0 reads higher in dry soil and lower in wet soil. The sketch turns the reading into a moisture percentage, using 522 counts for dry and 260 for wet.

If the soil is under 35 percent, pin 7 switches the relay on and the pump runs for three seconds. The pump has its own 6 V supply, switched through the relay's COM and NO contacts.

After watering, the sketch waits ten seconds for the water to soak in before it checks again. Otherwise it checks once a second.

Parts list

6 parts, plus the jumper wires. They retail for about $35; on Mokxi they're free.

Kits that can build it

These 2 starter kits have every part in the circuit. Each kit's page lists what else it can build.

Wiring table

Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.

Part and pinConnects to
Relay module pin INArduino Uno R3 pin 7
Soil moisture sensor, capacitive pin VCCArduino Uno R3 pin 5V
Relay module pin VCCArduino Uno R3 pin 5V
Soil moisture sensor, capacitive pin GNDArduino Uno R3 pin GND
Relay module pin GNDArduino Uno R3 pin GND
Mini water pump pin V-Arduino Uno R3 pin GND
Soil moisture sensor, capacitive pin AOUTArduino Uno R3 pin A0
Mini water pump pin V+Relay module pin NO
Relay module pin COM6 V

The code

The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.

sketch.ino · Arduino Uno R3
// Plant waterer: a capacitive soil moisture probe, a relay and a mini pump.
//
//   A0       the probe's AOUT (VCC and GND from the breadboard rails)
//   pin 7    the relay module's IN (high pulls the relay in)
//   relay    COM to the pump's own 6 V supply, NO to the pump's V+;
//            the pump's V- to ground
//
// A capacitive probe reads higher in dry soil: about 2.55 V in air and
// 1.27 V in water on this one, so on a 5 V board about 522 and 260 counts.
// The sketch turns that into a percentage, and under 35% runs the pump for
// three seconds, then waits ten for the water to soak in before it looks
// again, so it never floods the pot chasing a probe that has not caught up.

const int PROBE = A0;
const int RELAY = 7;

const long DRY_COUNTS = 522;
const long WET_COUNTS = 260;
const int THIRSTY = 35;
const unsigned long PUMP_MS = 3000;
const unsigned long SOAK_MS = 10000;

int waterings = 0;

int moisture() {
  long counts = analogRead(PROBE);
  long percent = (DRY_COUNTS - counts) * 100 / (DRY_COUNTS - WET_COUNTS);
  if (percent < 0) percent = 0;
  if (percent > 100) percent = 100;
  return (int)percent;
}

void setup() {
  Serial.begin(115200);
  Serial.println("Mokxi Arduino Uno: plant waterer");
  pinMode(RELAY, OUTPUT);
  digitalWrite(RELAY, LOW);
}

void loop() {
  int percent = moisture();
  Serial.print("soil ");
  Serial.print(percent);
  Serial.println("%");
  if (percent < THIRSTY) {
    waterings++;
    Serial.print("dry: watering ");
    Serial.println(waterings);
    digitalWrite(RELAY, HIGH);
    delay(PUMP_MS);
    digitalWrite(RELAY, LOW);
    Serial.println("soaking");
    delay(SOAK_MS);
  } else {
    delay(1000);
  }
}

Code walkthrough

The key functions of the sketch, and what each one does.

moisture sketch.ino

Reads A0 and rescales it between DRY_COUNTS and WET_COUNTS so dry is 0 percent and wet is 100. Readings outside that range are clamped to 0 or 100.

int moisture() {
  long counts = analogRead(PROBE);
  long percent = (DRY_COUNTS - counts) * 100 / (DRY_COUNTS - WET_COUNTS);
  if (percent < 0) percent = 0;
  if (percent > 100) percent = 100;
  return (int)percent;
}

setup sketch.ino

Opens serial at 115200 baud, makes the relay pin an output, and starts it LOW so the pump is off at power-up.

void setup() {
  Serial.begin(115200);
  Serial.println("Mokxi Arduino Uno: plant waterer");
  pinMode(RELAY, OUTPUT);
  digitalWrite(RELAY, LOW);
}

loop sketch.ino

Prints the soil percentage. Below THIRSTY it counts a watering, runs the pump for PUMP_MS, then waits SOAK_MS. Otherwise it waits one second.

void loop() {
  int percent = moisture();
  Serial.print("soil ");
  Serial.print(percent);
  Serial.println("%");
  if (percent < THIRSTY) {
    waterings++;
    Serial.print("dry: watering ");
    Serial.println(waterings);
    digitalWrite(RELAY, HIGH);
    delay(PUMP_MS);
    digitalWrite(RELAY, LOW);
    Serial.println("soaking");
    delay(SOAK_MS);
  } else {
    delay(1000);
  }
}

Troubleshooting

The usual mistakes with this circuit, and the fix for each.

  • The pump runs too often or never This project
    Retune DRY_COUNTS and WET_COUNTS to your probe's readings in air and in water, or change THIRSTY.
  • The relay clicks but the pump stays off This project
    The pump needs its own 6 V on COM, NO to the pump's V+, and the pump's V- to ground.
  • The pump runs when the soil is wet This project
    A capacitive probe reads higher when dry, so check that the wiring and calibration numbers are not swapped.
  • The reading seems backward: wet soil gives a lower number. Soil moisture sensor
    A capacitive sensor reads lower when wetter. Measure it in dry air and in a glass of water, then map those two values to 0 and 100 percent.
  • The reading is unstable or the sensor corrodes. Soil moisture sensor
    Keep the electronics above the soil line and do not submerge past the marked line. Power it from 3.3 V or 5 V as the board allows, and average several readings.
  • The relay does not click, or the board resets when it switches. Relay module
    A relay coil needs more current than a pin can give. Use a module with a transistor driver, and power VCC from 5 V. Share ground between the module and the Arduino.
  • The relay works backwards: on when you expect off. Relay module
    Many modules are active LOW: the input must go LOW to turn the relay on. Set the pin HIGH at startup so the load does not switch on during boot.
  • A pump wired straight to a microcontroller pin does not run or resets the board. It draws far more than a pin can give. Mini water pump
    Switch it with a logic level MOSFET or a transistor with a base resistor, from its own supply of 3 to 6 V. Join the grounds.

Change it and keep it

Open it in the editor, change the circuit or the code, and keep your version in a free account.