Freedom Sale
Independence Day Special — Unlock the AI Path 70% off our most popular AI course · Limited time offer
--Days
--Hrs
--Min
--Sec
Claim Your Discount
✦ Beginner ⏱ 30 min

🌱 Build a Plant Watering Reminder with Arduino

🎯 What You'll Build

A soil moisture monitor that reads a capacitive sensor, displays moisture percentage on an LCD, and triggers a buzzer and LED alert when the plant needs water.

📋 What You'll Need

1

Read the soil moisture sensor

The capacitive sensor outputs an analog voltage — lower voltage means wetter soil.

// Capacitive Soil Moisture Sensor v1.2
// AOUT -> A0
// VCC  -> 3.3V (not 5V — this prevents corrosion)
// GND  -> GND

const int SENSOR_PIN  = A0;
const int DRY_VALUE   = 880;  // Calibrate: value in dry air
const int WET_VALUE   = 430;  // Calibrate: value fully submerged

void setup() {
  Serial.begin(9600);
}

int getMoisturePercent() {
  int raw    = analogRead(SENSOR_PIN);
  int percent = map(raw, DRY_VALUE, WET_VALUE, 0, 100);
  return constrain(percent, 0, 100);
}

void loop() {
  int moisture = getMoisturePercent();
  int raw      = analogRead(SENSOR_PIN);

  Serial.print("Raw: "); Serial.print(raw);
  Serial.print("  Moisture: "); Serial.print(moisture); Serial.println("%");

  delay(1000);
}
2

Display on LCD and trigger alerts

Show the moisture level on screen and alert when it drops below the threshold.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

const int SENSOR_PIN    = A0;
const int LED_PIN       = 7;
const int BUZZER_PIN    = 6;
const int DRY_VALUE     = 880;
const int WET_VALUE     = 430;
const int WATER_THRESHOLD = 30;   // Alert if moisture below 30%

int getMoisturePercent() {
  int raw = analogRead(SENSOR_PIN);
  return constrain(map(raw, DRY_VALUE, WET_VALUE, 0, 100), 0, 100);
}

void setup() {
  lcd.init();
  lcd.backlight();
  pinMode(LED_PIN,    OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);
}

void loop() {
  int moisture = getMoisturePercent();

  // LCD line 1: moisture bar
  lcd.setCursor(0, 0);
  lcd.print("Soil: ");
  lcd.print(moisture);
  lcd.print("%   ");

  // LCD line 2: status
  lcd.setCursor(0, 1);
  if (moisture < WATER_THRESHOLD) {
    lcd.print("WATER ME!       ");
    digitalWrite(LED_PIN, HIGH);
    tone(BUZZER_PIN, 1500, 300);
    delay(700);
    noTone(BUZZER_PIN);
  } else if (moisture < 50) {
    lcd.print("Getting dry...  ");
    digitalWrite(LED_PIN, LOW);
    noTone(BUZZER_PIN);
  } else {
    lcd.print("Good moisture   ");
    digitalWrite(LED_PIN, LOW);
    noTone(BUZZER_PIN);
  }

  delay(2000);
}
💡 Tip: You MUST calibrate DRY_VALUE and WET_VALUE for your specific sensor — every batch is slightly different. Read the raw Serial output with the sensor in air, then in a glass of water, and update the constants. This takes 30 seconds and makes the % reading accurate.

🎉 You Did It!

A real working IoT sensor that reads the physical world and acts on it. Add an ESP8266 WiFi module to post moisture readings to a spreadsheet or send a WhatsApp message when the plant needs water — the same hardware, just more code.

Found something wrong?

Spotted a bug, broken code, or something that doesn't look right? Tell us what's off and we'll fix it.