🌱 Smart Plant Monitoring + Automatic Watering System
Using ESP32 + Soil Moisture Sensor + Relay + Water Pump
ESP32 Blynk IOT + VERY detailed line-by-line explanation.
✅ Full ESP32 + Blynk IoT Code (Copy Paste)
✅ Moisture % + Pump ON/OFF on Blynk Dashboard
✅ Auto Mode (Moisture < 10% pump ON)
✅ Manual Pump Button in Blynk
✅ VERY detailed code explanation
✅ Full step-by-step Blynk setup
✅ 1) What You Will See in Blynk App
Blynk Dashboard (Mobile)
You will get:
✅ Moisture % (Gauge)
✅ Soil Status (DRY / OK) (Label)
✅ Pump Status (ON / OFF) (Label)
✅ Manual Pump Button (Switch)
✅ Auto/Manual Mode Button (Switch)
✅ 2) Blynk Virtual Pins Used
| Data | Virtual Pin |
|---|---|
| Moisture % | V0 |
| Soil Status | V1 |
| Pump Status | V2 |
| Manual Pump Button | V3 |
| Auto Mode Switch | V4 |
✅ 3) ESP32 + Blynk IoT Code (COPY-PASTE)
⚡ Connections:
-
Soil Sensor AO → GPIO34
-
Relay IN → GPIO26
/************************************************************
SMART PLANT MONITORING + AUTO WATERING SYSTEM (BLYNK IoT)
Board: ESP32
Sensor: Soil Moisture Sensor (Analog)
Relay: 1 Channel Relay
Pump: DC Water Pump
Auto Condition:
Moisture < 10% -> Pump ON
Moisture >= 10% -> Pump OFF
Blynk Dashboard:
V0 -> Moisture %
V1 -> Soil Status (DRY/OK)
V2 -> Pump Status (ON/OFF)
V3 -> Manual Pump Button
V4 -> Auto Mode Switch
************************************************************/
#define BLYNK_TEMPLATE_ID "YOUR_TEMPLATE_ID"
#define BLYNK_TEMPLATE_NAME "Plant Monitor"
#define BLYNK_AUTH_TOKEN "YOUR_AUTH_TOKEN"
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
// ----------- WiFi Credentials -----------
char ssid[] = "YOUR_WIFI_NAME";
char pass[] = "YOUR_WIFI_PASSWORD";
// ----------- Pin Definitions -----------
#define SOIL_SENSOR_PIN 34
#define RELAY_PIN 26
// ----------- Calibration Values -----------
int dryValue = 3500; // Dry soil ADC (calibrate)
int wetValue = 1500; // Wet soil ADC (calibrate)
// ----------- Moisture Threshold -----------
int pumpThreshold = 10;
// ----------- Variables -----------
int sensorValue = 0;
int moisturePercent = 0;
String soilStatus = "";
String pumpStatus = "";
// ----------- Modes -----------
bool autoMode = true; // true = Auto mode ON
bool manualPump = false; // manual pump state
BlynkTimer timer;
// ----------- Function: Pump ON -----------
void pumpON()
{
digitalWrite(RELAY_PIN, LOW); // Active LOW relay
pumpStatus = "ON";
}
// ----------- Function: Pump OFF -----------
void pumpOFF()
{
digitalWrite(RELAY_PIN, HIGH); // Relay OFF
pumpStatus = "OFF";
}
// ----------- Blynk Manual Pump Button (V3) -----------
BLYNK_WRITE(V3)
{
manualPump = param.asInt();
// Manual pump works only if autoMode is OFF
if (!autoMode)
{
if (manualPump == 1)
pumpON();
else
pumpOFF();
}
}
// ----------- Blynk Auto Mode Switch (V4) -----------
BLYNK_WRITE(V4)
{
autoMode = param.asInt();
// If autoMode is turned ON, manual pump button should not control pump
if (autoMode)
{
manualPump = false;
Blynk.virtualWrite(V3, 0); // Reset manual button in app
}
}
// ----------- Main Function: Read Sensor + Control Pump -----------
void sendSensorData()
{
// Step 1: Read sensor ADC
sensorValue = analogRead(SOIL_SENSOR_PIN);
// Step 2: Convert ADC to moisture %
moisturePercent = map(sensorValue, dryValue, wetValue, 0, 100);
// Step 3: Clamp moisture %
if (moisturePercent > 100) moisturePercent = 100;
if (moisturePercent < 0) moisturePercent = 0;
// Step 4: Soil status
if (moisturePercent < pumpThreshold)
soilStatus = "DRY";
else
soilStatus = "OK";
// Step 5: Auto pump control
if (autoMode)
{
if (moisturePercent < pumpThreshold)
pumpON();
else
pumpOFF();
}
// Step 6: Send values to Blynk
Blynk.virtualWrite(V0, moisturePercent);
Blynk.virtualWrite(V1, soilStatus);
Blynk.virtualWrite(V2, pumpStatus);
// Step 7: Print on Serial Monitor also
Serial.print("ADC: ");
Serial.print(sensorValue);
Serial.print(" | Moisture: ");
Serial.print(moisturePercent);
Serial.print("% | Soil: ");
Serial.print(soilStatus);
Serial.print(" | Pump: ");
Serial.print(pumpStatus);
Serial.print(" | Mode: ");
Serial.println(autoMode ? "AUTO" : "MANUAL");
}
void setup()
{
Serial.begin(115200);
pinMode(RELAY_PIN, OUTPUT);
// Pump OFF initially
pumpOFF();
// Start Blynk
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
// Timer: send data every 1 second
timer.setInterval(1000L, sendSensorData);
Serial.println("Blynk Plant Monitoring Started!");
}
void loop()
{
Blynk.run();
timer.run();
}
✅ 4) Step-by-Step Blynk IoT Setup (Very Easy)
Follow carefully:
✅ Step 1: Install Blynk App
Download:
📱 Blynk IoT (Official)
✅ Step 2: Create Account
-
Sign up with email
-
Login
✅ Step 3: Create New Template
-
Open Blynk app
-
Go to Developer Zone
-
Click New Template
-
Template Name:
Plant Monitor -
Hardware:
ESP32 -
Connection Type:
WiFi -
Click Done
✅ Step 4: Get Template ID + Auth Token
After creating template:
Go to template page and you will see:
-
Template ID
-
Template Name
-
Auth Token
Copy and paste in code:
✅ Step 5: Create Datastreams
Inside Template:
Go to:
Datastreams → New Datastream
Create these 5 datastreams:
✅ Datastream 1 (Moisture %)
-
Name: Moisture
-
Virtual Pin: V0
-
Data Type: Integer
-
Min: 0
-
Max: 100
✅ Datastream 2 (Soil Status)
-
Name: Soil
-
Virtual Pin: V1
-
Data Type: String
✅ Datastream 3 (Pump Status)
-
Name: Pump
-
Virtual Pin: V2
-
Data Type: String
✅ Datastream 4 (Manual Pump)
-
Name: Manual Pump
-
Virtual Pin: V3
-
Data Type: Integer
-
Min: 0
-
Max: 1
✅ Datastream 5 (Auto Mode)
-
Name: Auto Mode
-
Virtual Pin: V4
-
Data Type: Integer
-
Min: 0
-
Max: 1
✅ Step 6: Create Dashboard Widgets
Go to:
Web Dashboard OR Mobile Dashboard
Add these widgets:
✅ Widget 1: Gauge (Moisture)
-
Widget: Gauge
-
Datastream: V0
-
Title: Moisture %
✅ Widget 2: Label (Soil Status)
-
Widget: Label
-
Datastream: V1
-
Title: Soil Status
✅ Widget 3: Label (Pump Status)
-
Widget: Label
-
Datastream: V2
-
Title: Pump Status
✅ Widget 4: Switch (Manual Pump)
-
Widget: Switch
-
Datastream: V3
-
Title: Pump ON/OFF
✅ Widget 5: Switch (Auto Mode)
-
Widget: Switch
-
Datastream: V4
-
Title: Auto Mode
Set default value:
-
Auto Mode = ON
✅ Step 7: Add Device
Now:
-
Go to Devices
-
Click Add New Device
-
Select your template:
Plant Monitor -
Click Create
Now you will get new Auth Token for device.
Copy it and paste into code.
✅ Step 8: Upload Code to ESP32
Replace WiFi details:
Upload code.
✅ Step 9: Open Serial Monitor
Set:
-
Baud rate: 115200
You will see:
✅ Step 10: Run Project
Now open Blynk App dashboard.
You will see:
-
Live moisture %
-
Pump ON/OFF status
-
Soil DRY/OK
-
Manual control
✅ 5) FULL CODE EXPLANATION (Every Logic)
Now full explanation.
✅ A) Blynk Credentials
These connect ESP32 to your Blynk project.
✅ B) Libraries
-
WiFi library connects ESP32 to router
-
Blynk library connects ESP32 to Blynk cloud
✅ C) WiFi Credentials
ESP32 uses these to connect to internet.
✅ D) Pins
✅ E) Calibration Values
Used for moisture percentage.
✅ F) Threshold
Auto watering threshold.
✅ G) Modes
-
autoMode = automatic watering ON/OFF
-
manualPump = manual pump button state
✅ H) BlynkTimer
Used to run function every 1 second.
✅ I) Pump ON Function
Turns pump ON and updates status string.
✅ J) Pump OFF Function
Turns pump OFF.
✅ K) Manual Pump Control from Blynk (V3)
This runs automatically when you press button in app.
If autoMode OFF:
Manual button controls pump.
✅ L) Auto Mode Switch (V4)
This runs when Auto Mode switch is changed.
If auto mode ON:
-
manual button reset
✅ M) sendSensorData() Main Function
This runs every 1 second.
It does:
-
Read sensor
-
Convert to moisture %
-
Decide DRY/OK
-
Control pump automatically
-
Send values to Blynk
-
Print on serial monitor
✅ N) setup()
-
Connects to Blynk cloud
-
Starts timer
✅ O) loop()
This is required for Blynk to work.
✅ 6) FINAL RESULT
Auto Mode ON:
-
moisture < 10% → pump ON
-
moisture ≥ 10% → pump OFF
Auto Mode OFF:
-
manual button controls pump