Smart Soil Moisture Based Irrigation System Using ESP8266 and Blynk
Build an IoT-based smart irrigation system using ESP8266, a soil moisture sensor, relay, DC water pump, and Blynk for automatic watering, live moisture monitoring, and manual pump control.
- ESP8266
- Nodemcu
- Soil Moisture Sensor
- Smart Irrigation
- Blynk
- Relay
- Water Pump
- IOT
- Automation
- Published
- Updated
- Reading time
- 12 min read
- Author
- Saroj Chaudhary
- Role
- IoT & Embedded Systems Engineer
Plants need an appropriate amount of water to grow properly, but checking soil moisture and watering plants manually is not always practical. Overwatering wastes water and can damage plants, while underwatering can make the soil too dry.
In this practical project, we will build a Smart Soil Moisture Based Irrigation System using ESP8266 and Blynk.
The ESP8266 continuously reads the soil moisture level. When the soil becomes dry, it automatically turns a water pump ON through a relay. When sufficient moisture is reached, the pump turns OFF.
The current moisture level and pump status are also sent to Blynk, allowing the user to monitor the system remotely. The user can switch between Automatic Mode and Manual Mode and manually control the pump from the Blynk dashboard.
One important part of this project is that the basic automatic irrigation logic runs locally on the ESP8266. Therefore, after the system has started, irrigation can continue even if the Internet or Blynk connection is temporarily unavailable.
1. Project Objectives
After completing this practical, students should be able to:
- interface a soil moisture sensor with ESP8266
- read an analog sensor using the ESP8266 ADC
- calibrate dry and wet soil readings
- convert raw sensor readings into moisture percentage
- create threshold-based control logic
- understand hysteresis using separate ON and OFF thresholds
- control a relay module from ESP8266
- operate a low-voltage DC water pump
- connect ESP8266 to Wi-Fi
- send sensor data to Blynk
- use Blynk Virtual Pins
- create automatic and manual operating modes
- understand how an IoT system can continue basic local control when the cloud connection is unavailable
2. Components Required
| Component | Quantity | Purpose |
|---|---|---|
| ESP8266 NodeMCU | 1 | Main controller and Wi-Fi communication |
| Soil Moisture Sensor Module | 1 | Measures soil moisture |
| Relay Module, 1-channel or 2-channel | 1 | Switches the water pump |
| 5V DC Water Pump | 1 | Supplies water to the plant |
| Water Pipe | 1 | Carries water from the pump |
| External 5V Supply for Pump | 1 | Powers the DC pump |
| Breadboard | 1 | Circuit prototyping |
| Jumper Wires | As required | Electrical connections |
| USB Data Cable | 1 | Programming and powering ESP8266 |
| 1N4007 Diode | 1, recommended | Helps suppress motor switching noise |
If you are using a 2-channel relay module, only one relay channel is required for this project.
3. System Block Diagram
The overall system can be represented as:
Soil Moisture Sensor
|
v
ESP8266
/ \
/ \
v v
Relay Module Wi-Fi
| |
v v
DC Water Blynk
Pump Dashboard
|
v
Manual / Auto Control
The soil sensor provides the input to the ESP8266.
The ESP8266 makes the irrigation decision locally and also communicates with Blynk through Wi-Fi.
4. Circuit Connections
Soil Moisture Sensor to ESP8266
| Soil Moisture Sensor | ESP8266 NodeMCU |
|---|---|
| VCC | 3.3V |
| GND | GND |
| AO | A0 |
For this project we use the analog output AO so that the ESP8266 can measure different moisture levels rather than receiving only a simple wet/dry digital signal.
ADC note: The ESP8266 chip itself has a 0-1.0V ADC input range, while many NodeMCU development boards include an onboard voltage divider that allows a higher voltage on A0. Board designs can differ, so verify the A0 input range of your specific ESP8266 development board before applying an analog voltage.
Relay Module to ESP8266
| Relay Module | ESP8266 NodeMCU |
|---|---|
| IN1 | D1 / GPIO5 |
| GND | GND |
| VCC | 5V / VIN, depending on the relay module |
If you are using a 2-channel relay module:
IN1 -> D1
IN2 -> Not used
Use a relay module whose input can be triggered reliably by the 3.3V GPIO signal from the ESP8266.
Water Pump Connection Through Relay
Use the relay contacts to switch the external pump supply.
External 5V Supply (+)
|
v
Relay COM
|
v
Relay NO
|
v
Pump Positive
Pump Negative
|
v
External 5V Supply (-)
Use the NO, Normally Open, contact so that the pump remains OFF when the relay is not activated.
A simplified connection is:
5V Supply + -> Relay COM
Relay NO -> Pump +
Pump - -> 5V Supply -
Do not power the water pump directly from an ESP8266 GPIO pin.
For classroom practicals, use a low-voltage DC pump. Do not use exposed AC mains wiring on a breadboard.
5. How the System Works
The system has two operating modes:
Automatic Mode
Manual Mode
Automatic Mode
In Automatic Mode:
- ESP8266 reads the analog value from the soil moisture sensor.
- The raw value is converted into a moisture percentage.
- If moisture becomes lower than the dry threshold, the pump turns ON.
- Water is supplied to the soil.
- ESP8266 continues checking the moisture level.
- When the moisture rises above the wet threshold, the pump turns OFF.
- Moisture percentage and pump status are sent to Blynk.
We will use two different thresholds:
Pump ON below: 35%
Pump OFF above: 55%
This creates hysteresis.
Without hysteresis, a system using only one threshold may repeatedly switch the relay ON and OFF when the sensor reading moves slightly around that value.
For example:
Moisture <= 35% -> Pump ON
Moisture >= 55% -> Pump OFF
Moisture 36-54% -> Keep previous pump state
This makes the irrigation control more stable.
Manual Mode
In Manual Mode, the automatic threshold decision is disabled.
The user controls the pump using a switch in Blynk:
Manual Pump Switch OFF -> Pump OFF
Manual Pump Switch ON -> Pump ON
This is useful when the user wants to test the pump or manually provide water.
6. Calibrating the Soil Moisture Sensor
Calibration is important because different soil sensors, soil types, sensor positions, and power-supply conditions can produce different analog values.
Do not assume that the example calibration values will exactly match your sensor.
For the example program, we will begin with:
const int DRY_VALUE = 800;
const int WET_VALUE = 350;
Your values may be different.
Step 1: Check the Dry Reading
Keep the sensor probe in dry soil or in the dry condition you want to consider as approximately 0% moisture.
Open Serial Monitor and note the raw value.
Example:
Raw ADC: 805
You could then use:
DRY_VALUE = 805;
Step 2: Check the Wet Reading
Place the sensor in sufficiently wet soil.
Wait a few seconds for the reading to become stable and note the raw value.
Example:
Raw ADC: 360
You could use:
WET_VALUE = 360;
Step 3: Update the Program
Update:
const int DRY_VALUE = 800;
const int WET_VALUE = 350;
with the values measured from your own sensor.
The program maps the calibrated range approximately as:
Dry calibration value -> 0%
Wet calibration value -> 100%
Then the result is limited between 0% and 100%.
Resistive soil moisture probes can corrode over long periods when continuously powered in wet soil. They are suitable for learning and short practical experiments, but a capacitive soil moisture sensor is usually a better choice for longer-term installations.
7. Blynk Dashboard Setup
Before uploading the complete code, create a Blynk Template and Device.
You will need:
BLYNK_TEMPLATE_ID
BLYNK_TEMPLATE_NAME
BLYNK_AUTH_TOKEN
Install the Blynk library from Arduino IDE Library Manager if it is not already installed.
Create the Datastreams
Create the following Virtual Pin datastreams.
| Datastream | Virtual Pin | Type | Suggested Range | Purpose |
|---|---|---|---|---|
| Soil Moisture | V0 | Integer | 0-100 | Displays moisture percentage |
| Pump Status | V1 | Integer | 0-1 | Displays whether pump is ON or OFF |
| Manual Pump | V2 | Integer | 0-1 | Manual pump switch |
| Automatic Mode | V3 | Integer | 0-1 | Selects Auto or Manual mode |
V0 - Soil Moisture
Create:
Name: Soil Moisture
Virtual Pin: V0
Data Type: Integer
Minimum: 0
Maximum: 100
Unit: %
You can connect this datastream to a:
- Gauge
- Value Display
- Chart
V1 - Pump Status
Create:
Name: Pump Status
Virtual Pin: V1
Data Type: Integer
Minimum: 0
Maximum: 1
You can use an LED or value widget.
The program sends:
0 -> Pump OFF
1 -> Pump ON
V2 - Manual Pump Control
Create:
Name: Manual Pump
Virtual Pin: V2
Data Type: Integer
Minimum: 0
Maximum: 1
Add a Switch widget.
This switch controls the pump only when the system is in Manual Mode.
V3 - Automatic Mode
Create:
Name: Automatic Mode
Virtual Pin: V3
Data Type: Integer
Minimum: 0
Maximum: 1
Add another Switch widget.
Use:
V3 = 1 -> Automatic Mode
V3 = 0 -> Manual Mode
A simple dashboard can therefore contain:
+---------------------------+
| Soil Moisture: 47% |
| |
| Pump Status: OFF |
| |
| Automatic Mode: ON |
| |
| Manual Pump: OFF |
+---------------------------+
8. Required Arduino Libraries
The project uses:
ESP8266WiFi.h
BlynkSimpleEsp8266.h
The ESP8266 Wi-Fi library is included with the ESP8266 Arduino board package.
Install the Blynk library using:
Arduino IDE
->
Sketch
->
Include Library
->
Manage Libraries
Search for:
Blynk
and install the Blynk library.
If ESP8266 board support is not already installed in Arduino IDE, first complete the ESP8266 board installation before continuing.
9. Complete ESP8266 Program
Replace the Blynk credentials and Wi-Fi credentials before uploading.
#define BLYNK_PRINT Serial
#define BLYNK_TEMPLATE_ID "YOUR_TEMPLATE_ID"
#define BLYNK_TEMPLATE_NAME "Smart Irrigation"
#define BLYNK_AUTH_TOKEN "YOUR_AUTH_TOKEN"
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
// ----------------------------------------------------
// Wi-Fi credentials
// ----------------------------------------------------
char ssid[] = "YOUR_WIFI_NAME";
char pass[] = "YOUR_WIFI_PASSWORD";
// ----------------------------------------------------
// Pin definitions
// ----------------------------------------------------
const int SOIL_PIN = A0;
const int RELAY_PIN = D1; // D1 = GPIO5
// Many relay modules are active LOW.
// Change this to false if your relay is active HIGH.
const bool RELAY_ACTIVE_LOW = true;
// ----------------------------------------------------
// Soil sensor calibration
// Replace these values after calibration.
// ----------------------------------------------------
const int DRY_VALUE = 800;
const int WET_VALUE = 350;
// ----------------------------------------------------
// Irrigation thresholds
// ----------------------------------------------------
const int PUMP_ON_BELOW = 35; // Pump starts at or below 35%
const int PUMP_OFF_ABOVE = 55; // Pump stops at or above 55%
// ----------------------------------------------------
// System variables
// ----------------------------------------------------
bool autoMode = true;
bool manualPumpRequest = false;
bool pumpOn = false;
int soilRaw = 0;
int moisturePercent = 0;
BlynkTimer timer;
// ----------------------------------------------------
// Apply relay output
// ----------------------------------------------------
void setPump(bool state)
{
pumpOn = state;
if (RELAY_ACTIVE_LOW)
{
digitalWrite(RELAY_PIN, state ? LOW : HIGH);
}
else
{
digitalWrite(RELAY_PIN, state ? HIGH : LOW);
}
if (Blynk.connected())
{
Blynk.virtualWrite(V1, pumpOn ? 1 : 0);
}
}
// ----------------------------------------------------
// Convert raw ADC reading to moisture percentage
// ----------------------------------------------------
int getMoisturePercent(int rawValue)
{
int percentage = map(
rawValue,
DRY_VALUE,
WET_VALUE,
0,
100
);
percentage = constrain(percentage, 0, 100);
return percentage;
}
// ----------------------------------------------------
// Read sensor and control irrigation
// ----------------------------------------------------
void readAndControlIrrigation()
{
soilRaw = analogRead(SOIL_PIN);
moisturePercent = getMoisturePercent(soilRaw);
// ------------------------------
// Automatic irrigation logic
// ------------------------------
if (autoMode)
{
if (moisturePercent <= PUMP_ON_BELOW && !pumpOn)
{
setPump(true);
}
else if (moisturePercent >= PUMP_OFF_ABOVE && pumpOn)
{
setPump(false);
}
}
else
{
// In manual mode, follow the Blynk manual switch.
setPump(manualPumpRequest);
}
// ------------------------------
// Send data to Blynk
// ------------------------------
if (Blynk.connected())
{
Blynk.virtualWrite(V0, moisturePercent);
Blynk.virtualWrite(V1, pumpOn ? 1 : 0);
}
// ------------------------------
// Serial Monitor output
// ------------------------------
Serial.print("Raw ADC: ");
Serial.print(soilRaw);
Serial.print(" | Moisture: ");
Serial.print(moisturePercent);
Serial.print("%");
Serial.print(" | Mode: ");
Serial.print(autoMode ? "AUTO" : "MANUAL");
Serial.print(" | Pump: ");
Serial.println(pumpOn ? "ON" : "OFF");
}
// ----------------------------------------------------
// Blynk V2 - Manual pump control
// ----------------------------------------------------
BLYNK_WRITE(V2)
{
manualPumpRequest = param.asInt();
if (!autoMode)
{
setPump(manualPumpRequest);
}
}
// ----------------------------------------------------
// Blynk V3 - Automatic / Manual mode
// ----------------------------------------------------
BLYNK_WRITE(V3)
{
autoMode = param.asInt();
if (autoMode)
{
// Immediately apply automatic control.
readAndControlIrrigation();
}
else
{
// Apply the current manual pump request.
setPump(manualPumpRequest);
}
}
// ----------------------------------------------------
// Called whenever Blynk reconnects
// ----------------------------------------------------
BLYNK_CONNECTED()
{
// Restore dashboard switch states.
Blynk.syncVirtual(V2);
Blynk.syncVirtual(V3);
// Send current local status.
Blynk.virtualWrite(V0, moisturePercent);
Blynk.virtualWrite(V1, pumpOn ? 1 : 0);
}
// ----------------------------------------------------
// Maintain Wi-Fi and Blynk connection
// This is separate from irrigation control so the
// automatic system can keep working locally.
// ----------------------------------------------------
void maintainConnection()
{
if (WiFi.status() != WL_CONNECTED)
{
Serial.println("Wi-Fi disconnected. Trying to reconnect...");
WiFi.reconnect();
return;
}
if (!Blynk.connected())
{
Serial.println("Blynk disconnected. Trying to reconnect...");
Blynk.connect(500);
}
}
void setup()
{
Serial.begin(115200);
delay(500);
// Relay output
pinMode(RELAY_PIN, OUTPUT);
// Start with pump safely OFF.
setPump(false);
// Start Wi-Fi connection without blocking
// the local irrigation logic indefinitely.
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
// Configure Blynk.
Blynk.config(BLYNK_AUTH_TOKEN);
// Read and control irrigation every second.
timer.setInterval(1000L, readAndControlIrrigation);
// Check connectivity every 5 seconds.
timer.setInterval(5000L, maintainConnection);
Serial.println();
Serial.println("Smart Irrigation System Started");
}
void loop()
{
// Run Blynk only when Wi-Fi is available.
if (WiFi.status() == WL_CONNECTED)
{
if (Blynk.connected())
{
Blynk.run();
}
}
// Local irrigation control continues through the timer.
timer.run();
}
10. Code Explanation
Instead of explaining every program line individually, we can divide the program into functional sections.
10.1 Blynk Configuration
At the beginning of the program:
#define BLYNK_TEMPLATE_ID "YOUR_TEMPLATE_ID"
#define BLYNK_TEMPLATE_NAME "Smart Irrigation"
#define BLYNK_AUTH_TOKEN "YOUR_AUTH_TOKEN"
These values identify the Blynk Template and Device.
Never publish your real device Auth Token in a public GitHub repository or public blog code example.
10.2 GPIO Definitions
The sensor uses the ESP8266 analog input:
const int SOIL_PIN = A0;
The relay uses:
const int RELAY_PIN = D1;
On NodeMCU:
D1 = GPIO5
10.3 Relay Logic
Many common relay modules use active-LOW inputs.
Therefore:
const bool RELAY_ACTIVE_LOW = true;
means:
Relay input LOW -> Relay ON
Relay input HIGH -> Relay OFF
If your relay behaves in the opposite way, change:
const bool RELAY_ACTIVE_LOW = true;
to:
const bool RELAY_ACTIVE_LOW = false;
10.4 Soil Sensor Calibration
The program uses:
const int DRY_VALUE = 800;
const int WET_VALUE = 350;
These values define the approximate sensor readings at dry and wet conditions.
They should be replaced after actual calibration.
10.5 Converting ADC to Percentage
The function:
int getMoisturePercent(int rawValue)
uses:
map()
to convert the calibrated ADC range to:
0% to 100%
The result is then limited using:
constrain()
so readings outside the calibration range do not produce values below 0% or above 100%.
10.6 Automatic Decision Making
The automatic control uses:
if (moisturePercent <= PUMP_ON_BELOW)
to start watering.
The pump is stopped using:
if (moisturePercent >= PUMP_OFF_ABOVE)
Using separate ON and OFF thresholds prevents rapid relay switching around a single threshold.
10.7 Manual Pump Control
Blynk Virtual Pin V2 receives the manual pump command:
BLYNK_WRITE(V2)
The manual command only controls the relay when:
Automatic Mode = OFF
10.8 Auto / Manual Selection
Virtual Pin V3 selects the operating mode:
BLYNK_WRITE(V3)
The program uses:
V3 = 1 -> Automatic Mode
V3 = 0 -> Manual Mode
10.9 Sending Data to Blynk
The moisture percentage is sent using:
Blynk.virtualWrite(V0, moisturePercent);
Pump status is sent using:
Blynk.virtualWrite(V1, pumpOn ? 1 : 0);
The ESP8266 therefore sends local sensor and actuator information to the dashboard.
10.10 Local Operation During Internet Failure
The irrigation function is executed by:
timer.setInterval(1000L, readAndControlIrrigation);
This function does not depend on receiving a command from Blynk.
Therefore, after startup, the sensor reading and automatic relay control can continue locally while the Wi-Fi/Blynk connection is temporarily unavailable.
The function:
maintainConnection()
periodically attempts to reconnect without making the main irrigation decision depend on the cloud.
11. Uploading the Program
Before uploading, update:
#define BLYNK_TEMPLATE_ID "YOUR_TEMPLATE_ID"
#define BLYNK_TEMPLATE_NAME "Smart Irrigation"
#define BLYNK_AUTH_TOKEN "YOUR_AUTH_TOKEN"
and:
char ssid[] = "YOUR_WIFI_NAME";
char pass[] = "YOUR_WIFI_PASSWORD";
Then select the ESP8266 board.
For a common NodeMCU board:
Tools
->
Board
->
ESP8266 Boards
->
NodeMCU 1.0 (ESP-12E Module)
Select the correct serial port:
Tools -> Port
Upload the program.
Open Serial Monitor at:
115200 baud
12. Expected Serial Monitor Output
After the system starts, output should look similar to:
Smart Irrigation System Started
Raw ADC: 792 | Moisture: 2% | Mode: AUTO | Pump: ON
Raw ADC: 710 | Moisture: 18% | Mode: AUTO | Pump: ON
Raw ADC: 590 | Moisture: 45% | Mode: AUTO | Pump: ON
Raw ADC: 510 | Moisture: 62% | Mode: AUTO | Pump: OFF
The exact raw values will depend on your sensor calibration.
In Manual Mode you may see:
Raw ADC: 515 | Moisture: 61% | Mode: MANUAL | Pump: ON
Even though the soil is already wet, the pump can remain ON because manual control has been selected.
This demonstrates the difference between:
Sensor-based automatic control
and:
User-based manual control
13. Testing the Project
Students should test the project systematically instead of only checking whether the pump moves.
Test 1 - Dry Soil
Place the sensor in dry soil.
Expected result:
Moisture <= 35%
Pump -> ON
Blynk Pump Status -> 1
Test 2 - Wet Soil
Place the sensor in sufficiently wet soil.
Expected result:
Moisture >= 55%
Pump -> OFF
Blynk Pump Status -> 0
Test 3 - Moisture Between the Two Thresholds
Create a condition where the moisture is between:
36% and 54%
Expected result:
The pump should keep its previous state rather than rapidly switching ON and OFF.
This demonstrates hysteresis.
Test 4 - Manual Mode
In Blynk:
Automatic Mode -> OFF
Now change:
Manual Pump -> ON
Expected result:
Pump -> ON
Change:
Manual Pump -> OFF
Expected result:
Pump -> OFF
Test 5 - Return to Automatic Mode
Set:
Automatic Mode -> ON
Expected result:
The ESP8266 should immediately return to moisture-based control.
Test 6 - Wi-Fi Disconnection
Keep the system running in Automatic Mode.
Disconnect the Wi-Fi router or temporarily make the Wi-Fi unavailable.
Expected result:
Blynk monitoring -> unavailable temporarily
Automatic moisture reading -> continues
Automatic pump control -> continues
Reconnect Wi-Fi.
Expected result:
The ESP8266 should attempt to reconnect and resume Blynk communication.
Test 7 - Relay Logic
If the relay behaves opposite to the program:
Expected OFF -> Relay ON
Expected ON -> Relay OFF
change:
const bool RELAY_ACTIVE_LOW = true;
to:
const bool RELAY_ACTIVE_LOW = false;
14. Expected Final Result
After completing the project, the system should provide:
- live soil moisture percentage
- automatic pump ON when the soil becomes dry
- automatic pump OFF when sufficient moisture is reached
- stable switching using separate ON and OFF thresholds
- pump status on Blynk
- manual pump control from Blynk
- Auto/Manual mode selection
- Serial Monitor output for debugging
- continued local automatic control during temporary Internet failure
A typical working sequence is:
Dry Soil
|
v
Moisture < 35%
|
v
Pump ON
|
v
Water Added
|
v
Moisture Increases
|
v
Moisture > 55%
|
v
Pump OFF
At the same time:
ESP8266
|
v
Wi-Fi
|
v
Blynk Cloud
|
v
Mobile / Web Dashboard
15. Common Problems and Troubleshooting
Soil Moisture Always Shows 0% or 100%
Possible causes:
- incorrect calibration values
- sensor AO not connected to A0
- sensor VCC or GND disconnected
- dry and wet calibration values entered incorrectly
- ADC voltage outside the supported range of the development board
First print and observe the raw ADC value before adjusting the percentage conversion.
Moisture Percentage Works in Reverse
Some sensors give:
Higher value -> Dry
Lower value -> Wet
while another sensor or circuit may behave differently.
Check your actual raw readings.
Set:
DRY_VALUE
WET_VALUE
according to the measurements from your own sensor.
Relay Works in Reverse
If the pump turns ON when it should be OFF, change:
const bool RELAY_ACTIVE_LOW = true;
to:
const bool RELAY_ACTIVE_LOW = false;
or vice versa.
Relay Does Not Trigger
Check:
- relay VCC
- relay GND
- D1 connection
- whether the relay module accepts a 3.3V input signal
- whether ESP8266 and relay-control ground are connected
- whether the relay needs a different supply arrangement
Pump Does Not Run
Check the pump separately with its rated DC supply.
Then check:
Supply + -> COM
NO -> Pump +
Pump - -> Supply -
Also verify that the relay actually clicks or changes state.
ESP8266 Restarts When Pump Turns ON
DC motors can create electrical noise and sudden current demand.
Possible improvements include:
- use a separate suitable power supply for the pump
- keep the pump current away from the ESP8266 power path
- add a suppression diode across the DC motor terminals
- use short, secure wiring
- add suitable supply decoupling
- ensure the USB supply for ESP8266 is stable
Do not try to power the pump directly from the ESP8266 board.
Blynk Does Not Connect
Check:
- Wi-Fi SSID
- Wi-Fi password
- BLYNK_TEMPLATE_ID
- BLYNK_TEMPLATE_NAME
- BLYNK_AUTH_TOKEN
- Internet connection
- Blynk library installation
- whether the device is correctly created in Blynk
The local automatic control can still be tested using Serial Monitor even before the Blynk dashboard is fully configured.
Blynk Manual Switch Does Nothing
Check:
Manual Pump -> V2
Automatic Mode -> V3
Remember that V2 controls the pump only when:
V3 = 0
which means Manual Mode.
Pump Repeatedly Turns ON and OFF
Check whether you accidentally changed the program to use only one threshold.
The example intentionally uses:
Pump ON <= 35%
Pump OFF >= 55%
The gap between these two values is what prevents rapid switching.
16. Practical Challenge
Now modify the project without copying a completed solution.
Challenge: Add a pump safety timer so that the water pump can run for a maximum of 10 seconds continuously. If the sensor still reports dry soil after 10 seconds, switch the pump OFF for a short waiting period before allowing another watering cycle.
Think about the following questions:
What variable will store the pump starting time?
Can millis() be used instead of delay()?
What should happen if the soil becomes wet before 10 seconds?
Should the timer also apply in Manual Mode?
How can the current safety state be shown in Blynk?
Extra Challenge
Add another Blynk datastream that allows the user to change the dry threshold from the dashboard.
For example:
V4 -> Dry Threshold
Then allow a range such as:
20% to 60%
The ESP8266 should use the value selected by the user instead of a fixed:
PUMP_ON_BELOW
This introduces students to remote configuration, not only remote monitoring.
17. Improvements for a Real Deployment
The classroom version is useful for learning the complete IoT control flow, but a longer-term irrigation system can be improved further.
Possible improvements include:
- replace the resistive soil probe with a capacitive moisture sensor
- add a water-level sensor to detect an empty tank
- add maximum pump run-time protection
- add a minimum waiting time between watering cycles
- store calibration values in EEPROM or another non-volatile storage method
- add Blynk notifications for dry soil or low water level
- add multiple soil sensors for different plant zones
- control multiple pumps using a multi-channel relay
- add temperature and humidity monitoring
- record moisture history for analysis
- add a local LCD display
- add physical push buttons for manual control when Wi-Fi is unavailable
A more advanced version can eventually become a complete smart greenhouse or multi-zone irrigation system.
18. What Students Learned
This project combines several concepts that are important in IoT and embedded-system development:
Analog Sensor Reading
|
v
Sensor Calibration
|
v
Percentage Conversion
|
v
Threshold Decision
|
v
Hysteresis
|
v
Relay Control
|
v
DC Pump Control
|
v
Wi-Fi Communication
|
v
Blynk Virtual Pins
|
v
Remote Monitoring
|
v
Manual + Automatic Modes
|
v
Local + Cloud IoT Control
Rather than simply reading a sensor, the ESP8266 is now making a decision, controlling a physical actuator, communicating with a cloud dashboard, and accepting remote commands.
That is the basic architecture used in many practical IoT automation systems.
Safety Note
Use only a low-voltage DC water pump for normal student laboratory work.
Keep water away from the ESP8266, breadboard, USB connection, relay-control electronics, and exposed conductors.
If a future project uses an AC-powered pump or AC light, mains wiring should be enclosed and handled only under proper instructor supervision. Do not place exposed mains wiring on a student breadboard.
Official References
For current documentation, refer to:
