Smart Plant Monitoring System
1. Abstract:
This project introduces a Smart Plant Monitoring System that uses current soil moisture levels to automate plant watering. The Arduino Uno microcontroller, soil moisture sensor, 16x2 LCD display with I2C module, 5V relay module, and 5V water pump are used in the construction of the system. The Arduino receives data from the soil sensor, which continually checks the moisture content. The Arduino decides if the soil is dry, medium, or wet based on pre-established thresholds. The mechanism automatically turns on the pump through the relay to water the plant if the soil is dry.
1. The
LCD display makes user monitoring simple by displaying real-time soil condition
and pump operation. A 3.7V Li-ion battery that has been increased to 5V powers
the complete arrangement, making it portable and energy-efficient. This
initiative promotes smart gardening by providing an affordable, dependable, and
automated watering system.
Authors:
o Shubham
Das (Bioscience Student, Class-XII)
o Rupam
Das (M.Sc. Electronics, Guest Lecturer)
Date: 8th July, 2025
Place: Barrackpore, Kolkata
2. Introduction
II. Smart gardening and automated irrigation systems can solve this problem by monitoring soil conditions and watering plants only when necessary.
III. This project focuses on building a Smart Plant Monitoring System using Arduino Uno, which automatically detects soil moisture and controls a water pump accordingly.
IV. The system uses a soil moisture sensor to measure the water content in the soil. Based on the moisture level, the Arduino controls a relay module to turn the water pump ON or OFF.
V. A 16x2 LCD display with an I2C module is used to display the real-time status of the soil (Dry, Medium, or Wet) and the pump (ON/OFF).
VI. The setup is powered by a 3.7V Li-ion battery boosted to 5V, making it portable and energy-efficient.
VII. The project aims to promote smart and sustainable farming practices, reduce water waste, and minimize the need for manual intervention.
3. Required
Components:
·
Arduino Uno
·
Soil Moisture Sensor
·
LCD Display
·
I2C Sensor
·
5volt Relay Module
·
Breadboard
·
5volt water pump
·
Jumper Wire
Note: For knowing the details of the components of this project visit the
component section in our website
·
Soil Moisture Sensor
The Soil Moisture Sensor
is a simple and reliable tool used to detect the moisture level in the soil. It
is widely used in smart irrigation systems, automatic plant watering projects,
and DIY gardening setups. This sensor helps determine whether the soil is dry,
moist, or wet by measuring the resistance between two metal probes.
It provides both analog
output (for real-time moisture values) and digital output (with an adjustable
threshold). The analog pin reads varying moisture levels, while the digital pin
sends a HIGH or LOW signal based on soil conditions.
This sensor is compatible
with Arduino, ESP32, NodeMCU, and other microcontrollers, making it ideal for
home automation and IoT-based plant care systems.
Parameter |
Value |
Operating
Voltage |
3.3V – 5V DC |
Output Type |
Analog &
Digital |
Analog Output
Range |
0 – 1023 (10-bit
ADC) |
Digital Output
Level |
HIGH (wet), LOW
(dry) |
Probe Material |
Nickel-plated /
Copper |
Dimensions |
60mm x 20mm
(sensor part) |
Interface |
3 Pins (VCC,
GND, A0/D0) |
4.
Circuit diagram
This system involves two
representations of the electronic layout: the simplified block diagram and the
detailed original circuit diagram. Both serve different purposes in
understanding and implementing the system.
A. Block Diagram Overview
·
The block diagram
is a high-level representation that shows how each component connects logically
and functionally.
·
It includes the
major parts: Arduino Uno, Soil Moisture Sensor, Relay Module, Water Pump, LCD
Display, and Battery.
·
Arrows represent
the flow of data (sensor readings), control signals (relay switching), and
power.
·
This diagram is
useful for conceptual understanding, presentations, and planning.
Key Blocks:
·
Soil Moisture
Sensor → Arduino Uno → Relay Module → Water Pump
·
Arduino Uno → LCD
Display
·
Battery → Powers
all modules
B. Original Circuit Design
· The actual circuit
diagram includes specific electrical connections, pin numbers, and wiring
routes on a breadboard or PCB.
·
It shows how each
component is physically wired to the Arduino and to each other.
·
The soil sensor’s
analog output connects to pin A0 of Arduino.
·
The LCD (with I2C)
connects to SDA (A4) and SCL (A5).
·
The relay IN pin
is connected to digital pin D7.
·
The water pump
connects to the normally open (NO) terminal of the relay and to the battery
through the relay's switch.
·
All VCC and GND
lines are properly distributed via the breadboard using the 5V supply (boosted
from 3.7V Li-ion).
Highlights of the Circuit:
·
Analog signal →
Digital decision → Electromechanical actuation
·
Uses I2C for
efficient LCD connection
·
Relay isolates
Arduino from pump’s higher current
Summary of
circuitry:
·
The block diagram
is abstract and used for logic representation.
·
The original
circuit is detailed and used for physical implementation.
·
Both are necessary
to move from planning to building a functional project.
5. Working
Principle
The Smart Plant Monitoring System functions by continuously monitoring
the soil moisture level and controlling the water pump based on real-time data.
It uses a combination of sensor input, microcontroller logic, and actuator
control, all powered by a compact portable power source. The working is based
on the principles of electrical conductivity, signal processing, and
electromechanical switching.
A. Key Functional Components
1.
Soil Moisture
Sensor
o
Working Principle:
The sensor measures the volumetric water content of the soil by determining its
electrical conductivity. Wet soil conducts electricity better than dry soil due
to the presence of water and dissolved salts.
o
Output: An analog
voltage signal (typically 0–1023) sent to the Arduino’s analog pin (A0).
o
Physics Concept:
Ohm’s Law and resistivity (R = ρL/A). As moisture increases, resistance
decreases, and current flow improves, resulting in a lower analog value (for
resistive sensors).
2.
Arduino Uno
o
Role: Acts as the
brain of the system. It reads the analog signal from the soil sensor, processes
the value using pre-set thresholds, and sends control signals to other
components.
o
Internal
Mechanism: Converts analog voltage from the sensor to a digital value using a
10-bit ADC (Analog to Digital Converter).
o
Thresholds:
§
950 → Dry soil →
Turn pump ON
§
400–950 → Medium
moisture → Pump OFF
§
<400 → Wet soil
→ Pump OFF
3.
LCD Display with
I2C Module
o
Displays real-time
feedback such as soil status (Dry/Medium/Wet) and Pump status (ON/OFF).
o
I2C reduces the
number of pins needed (uses only SDA and SCL).
o
Based on liquid
crystal polarization controlled by electric current.
4.
5V Relay Module
o
A relay is an
electrically operated switch that isolates the Arduino from the higher current
required by the water pump.
o
When the Arduino
sends a HIGH signal (5V) to the relay, it activates an internal electromagnetic
coil.
o
This coil
generates a magnetic field, attracting a switch and closing the circuit between
the pump and power supply.
5.
5V Water Pump
o
A small DC pump
used for irrigation.
o
Activated via the
relay, it pulls water from a reservoir to the plant when the soil is dry.
o
Based on Bernoulli’s
principle and fluid dynamics: pressure created by the rotating impeller pushes
water through the outlet.
6.
3.7V Li-ion
Battery (Boosted to 5V)
o
Supplies power to
the entire circuit via a boost converter.
o
Physics: Chemical
energy stored in lithium ions is converted into electrical energy during
discharge.
o
The boost
converter steps up voltage using inductive switching
(V = L di/dt).
B. Overall
System Process
1.
The soil sensor
continuously measures moisture levels and sends analog signals to the Arduino.
2.
Arduino converts
and compares the input to thresholds to determine the soil’s state.
3.
The system decides
whether to activate the water pump through a relay module.
4.
The LCD displays
the moisture level category (Dry/Medium/Wet) and the pump’s state (ON/OFF).
5.
The pump irrigates
the soil when dry, powered by the Li-ion battery.
6.
The process
repeats at fixed intervals (can be improved with time delays or sleep mode for
power efficiency).
Summary of Physics & Electronics Concepts Used
- Electrical conductivity & resistance (moisture sensing)
- Analog to digital conversion (Arduino ADC)
- Electromagnetism (relay activation)
- Liquid crystal optics (LCD display)
- Fluid dynamics (pump operation)
- Energy conversion (Li-ion battery)
6. How the Smart
Plant Monitoring System Works:
1. Soil
Moisture Detection
- The soil moisture sensor is placed in the soil near the plant.
- It detects how much water is present in the soil using electrical
conductivity.
- The drier the soil, the higher the sensor reading (closer to 1023); the
wetter the soil, the lower the reading (closer to 300).
2. Sensor
Sends Data to Arduino
- The sensor sends an analog signal to the Arduino Uno on pin A0.
- The Arduino reads the sensor value (between 0–1023) and processes it.
3. Arduino
Makes a Decision
Based on the sensor value:
- If the value > 950 → Soil is dry → Turn ON pump
- If 400 ≤ value ≤ 950 → Soil is medium → Keep pump OFF
- If value < 400 → Soil is wet → Keep pump OFF
4. Display
the Status
- The 16x2 LCD (with I2C module) shows the soil condition (Dry / Medium / Wet)
- It also displays the status of the pump (ON / OFF)
5. Control
the Pump Using Relay
- If the soil is dry, the Arduino sends a signal to the 5V relay module
(connected to pin D7).
- The relay activates and allows current to flow to the 5V water pump.
- The pump starts and waters the plant.
6. Power
Supply
- The entire system is powered by a 3.7V Li-ion battery.
- A boost converter increases this voltage to 5V to power the Arduino, relay,
and pump.
7.
Continuous Monitoring
- The system runs continuously, checking the soil at regular intervals (e.g.,
every few seconds or minutes).
- As soon as the soil becomes wet enough, the Arduino turns off the pump.
🛠
Optional Enhancements:
·
Add a delay so the
pump doesn’t turn on/off too quickly.
·
Add Wi-Fi or
Bluetooth for remote monitoring.
·
Log data for
analysis (CSV or cloud)
7.
Arduino Code (With Comments)
Below is a compact and functional version of the
Arduino code used in the project:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,
16, 2); // I2C address 0x27, 16 columns,
2 rows
const int soilSensorPin = A0;
// Soil moisture sensor input pin
const int relayPin = 7; // Relay control pin
voidsetup()
{
lcd.begin();
lcd.backlight();
pinMode(soilSensorPin, INPUT);
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, LOW); //Initially turn OFF pump
}
void loop()
{
int moistureValue = analogRead(soilSensorPin);
lcd.setCursor(0, 0);
lcd.print("Moisture: ");
lcd.print(moistureValue);
if (moistureValue > 950) {
lcd.setCursor(0, 1);
lcd.print("Soil: DRY PUMP ON ");
digitalWrite(relayPin, HIGH);
}
else if (moistureValue >= 400 && moistureValue <= 950) {
lcd.setCursor(0, 1);
lcd.print("Soil: MED PUMP OFF");
digitalWrite(relayPin, LOW);
}
else {
lcd.setCursor(0, 1);
lcd.print("Soil: WET PUMP OFF");
digitalWrite(relayPin, LOW);
}
delay(2000); // Delay to allow
LCD update
}
Explanation:
- The soil moisture sensor provides an analog
reading from 0 to 1023.
- The code determines whether soil is Dry
(>950), Medium (400–950), or Wet (<400).
- The LCD displays both moisture reading and pump
status.
- The relay is triggered only when the soil is dry.
8.
Result and Output:
After
uploading the code and assembling the circuit, the system behaves as follows:
A. System Behaviour:
- When soil is dry (sensor value > 950):
- LCD shows “Soil: DRY PUMP ON”
- Relay activates the pump, watering the plant.
- When soil is medium moist (400–950):
- LCD shows “Soil: MED PUMP OFF”
- Pump remains off.
- When soil is sufficiently wet (< 400):
- LCD shows “Soil: WET PUMP OFF”
- Pump stays off to avoid overwatering.
B. Observed Output (Examples):
Time |
Moisture
Value |
Soil Status |
Pump Status |
10:00 AM |
987 |
Dry |
ON |
11:30 AM |
875 |
Medium |
OFF |
12:45 PM |
345 |
Wet |
OFF |
C. LCD Display Example:
Line 1: Moisture: 987
Line 2: Soil: DRY PUMP ON
D. Performance:
- The system reliably maintains correct pump control.
- LCD provides clear real-time feedback.
- Battery lasts well under optimized duty cycles.
9. Advantage:
·
Automated
Irrigation: The system waters the plant automatically based on real-time soil
moisture data, reducing manual effort.
·
Water
Conservation: Prevents overwatering by activating the pump only when the soil
is dry.
·
Energy Efficient:
Uses a low-power Arduino and battery-based supply, making it suitable for
remote areas.
·
Real-Time
Monitoring: Displays moisture levels and pump status live on the LCD.
·
Low Cost: Built
with inexpensive and widely available components.
·
Easy to Build and
Expand: Beginner-friendly and modular design allows for upgrades.
·
Promotes Smart
Agriculture: Encourages adoption of technology in small-scale farming and home
gardening.
·
Portable Setup:
The Li-ion battery makes it suitable for use in areas without constant power.
·
Customizable
Thresholds: Soil moisture thresholds can be tuned to different plant needs.
10.
Future Scope:
·
IoT Integration: Add Wi-Fi (ESP8266/ESP32) or
GSM modules for remote control and mobile app connectivity.
·
Cloud Data Logging: Store moisture data online
(e.g., Google Sheets, Firebase) for analysis and alerts.
·
Solar Charging: Use solar panels to recharge
the battery and make the system fully self-sustaining.
·
Additional Sensors: Include temperature,
humidity, and light sensors for comprehensive environmental monitoring.
·
Smart App Interface: Develop a companion
mobile app to control thresholds and view real-time data.
·
AI-Based Irrigation: Implement machine
learning to optimize watering schedules based on weather predictions and plant
type.
·
Multi-Zone Monitoring: Extend the system to
monitor and control irrigation for multiple plants or zones.
11.
Conclusion
The Smart Plant Monitoring System using Arduino provides a practical solution for automatic plant irrigation based on soil moisture levels. It is a cost-effective, energy-efficient, and easily deployable system for home gardening, small-scale agriculture, and educational purposes. The system successfully monitors soil moisture and activates a water pump when the soil is dry, displaying live data through an LCD interface. Although the current version is basic, it offers vast potential for expansion into a fully automated, connected, and intelligent plant care platform. This project lays a strong foundation for future smart farming innovations.
12.
Data Analysis
#IMPORTING NECESSARY
LIBRARIES
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
df=pd.read_csv("smart_plant_monitoring_data.csv")
#IMPORTING NECESSARY LIBRARIES
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
df.head() #returns first 5 entries
Timestamp Soil_Moisture Soil_Status Pump_Status Battery_Voltage
0 2025-06-23 00:00:00 774 Medium OFF 3.98
1 2025-06-23 01:00:00 679 Medium OFF 3.92
2 2025-06-23 02:00:00 797 Medium OFF 3.91
3 2025-06-23 03:00:00 928 Medium OFF 3.92
4 2025-06-23 04:00:00 664 Medium OFF 3.99
df.tail() #returns first 5 entries
Timestamp Soil_Moisture Soil_Status Pump_Status Battery_Voltage
163 2025-06-29 19:00:00 576 Medium OFF
\ 3.91
164 2025-06-29 20:00:00 844 Medium OFF 4.01
165 2025-06-29 21:00:00 761 Medium OFF 3.93
166 2025-06-29 22:00:00 823 Medium OFF 4.10
167 2025-06-29 23:00:00 984 Dry ON 3.99
(168, 5)
df.isnull().sum()
Timestamp 0
Soil_Moisture 0
Soil_Status 0
Pump_Status 0
Battery_Voltage 0
dtype: int64
Timestamp object
Soil_Moisture int64
Soil_Status object
Pump_Status object
Battery_Voltage float64
dtype: object
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 168 entries, 0 to 167
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Timestamp 168 non-null object
1 Soil_Moisture 168 non-null int64
2 Soil_Status 168 non-null object
3 Pump_Status 168 non-null object
4 Battery_Voltage 168 non-null float64
dtypes: float64(1), int64(1), object(3)
memory usage: 6.7+ KB
data=df.groupby('Soil_Status')
Timestamp Soil_Moisture Soil_Status Pump_Status Battery_Voltage
0 2025-06-23 00:00:00 774 Medium OFF 3.98
1 2025-06-23 01:00:00 679 Medium OFF 3.92
2 2025-06-23 02:00:00 797 Medium OFF 3.91
3 2025-06-23 03:00:00 928 Medium OFF 3.92
4 2025-06-23 04:00:00 664 Medium OFF 3.99
Timestamp Soil_Moisture Soil_Status Pump_Status Battery_Voltage
0 2025-06-23 00:00:00 774 Medium OFF 3.98
1 2025-06-23 01:00:00 679 Medium OFF 3.92
2 2025-06-23 02:00:00 797 Medium OFF 3.91
3 2025-06-23 03:00:00 928 Medium OFF 3.92
4 2025-06-23 04:00:00 664 Medium OFF 3.99
df['Timestamp'] = pd.to_datetime(df['Timestamp'])
print("Dataset Summary:")
print(df.describe())
Dataset Summary:
Timestamp Soil_Moisture
Battery_Voltage
count 168 168.000000 168.000000
mean 2025-06-26 11:30:00 693.333333 4.007798
min 2025-06-23 00:00:00 307.000000 3.680000
25% 2025-06-24 17:45:00 597.750000 3.930000
50% 2025-06-26 11:30:00 698.500000 4.010000
75% 2025-06-28 05:15:00 778.750000 4.070000
max 2025-06-29 23:00:00 1023.000000 4.390000
std NaN 140.841809 0.098385
soil_counts = df['Soil_Status'].value_counts()
print("\nSoil Status Counts:")
print(soil_counts)
Soil Status Counts:
Soil_Status
Medium 161
Dry 6
Wet 1
Name: count, dtype: int64
plt.figure(figsize=(10, 5))
sns.histplot(df['Soil_Moisture'])
plt.title("Soil Moisture Distribution")
plt.xlabel("Soil Moisture")
plt.ylabel("Frequency")
plt.grid(True)
plt.tight_layout()
plt.show()
plt.boxplot(df['Soil_Moisture'])
{'whiskers': [<matplotlib.lines.Line2D at 0x2d5de68ab20>,
<matplotlib.lines.Line2D at
0x2d5de68aeb0>],
'caps':
[<matplotlib.lines.Line2D at 0x2d5de69b280>,
<matplotlib.lines.Line2D at
0x2d5de69b610>],
'boxes':
[<matplotlib.lines.Line2D at 0x2d5de68a760>],
'medians':
[<matplotlib.lines.Line2D at 0x2d5de69b9a0>],
'fliers':
[<matplotlib.lines.Line2D at 0x2d5de69bd30>],
'means': []}
df['Soil_Moisture'].hist()
<AxesSubplot:>
df['Battery_Voltage'].hist()
<AxesSubplot:>
plt.figure(figsize=(10, 6))
plt.scatter(df['Soil_Moisture'], df['Battery_Voltage'], alpha=0.5, color='blue')
plt.title('Battery Voltage vs Soil
Moisture')
plt.xlabel('Soil Moisture (Sensor
Value)')
plt.ylabel('Battery Voltage (V)')
plt.grid(True)
plt.tight_layout()
plt.show()
sns.pairplot(df, hue='Soil_Moisture')
<seaborn.axisgrid.PairGrid at 0x2d5dc838d60>
sns.pairplot(df, hue='Battery_Voltage')
<seaborn.axisgrid.PairGrid at 0x2d5dc85a3d0>
plt.figure(figsize=(8, 6))
sns.boxplot(x='Pump_Status', y='Battery_Voltage', data=df, palette='Set2')
plt.title('Battery Voltage vs Pump Status')
plt.xlabel('Pump Status')
plt.ylabel('Battery Voltage (V)')
plt.grid(True)
plt.tight_layout()
plt.show()
plt.figure(figsize=(8, 6))
sns.boxplot(x='Soil_Status', y='Soil_Moisture', data=df, palette='Set3')
plt.title('Soil Moisture vs Soil Status')
plt.xlabel('Soil Status')
plt.ylabel('Soil Moisture (Sensor Value)')
plt.grid(True)
plt.tight_layout()
plt.show()
sns.violinplot(x='Soil_Status', y='Soil_Moisture', data=df, palette='Set2')
<AxesSubplot:xlabel='Soil_Status', ylabel='Soil_Moisture'>
plt.figure(figsize=(10, 6))
sns.stripplot(x='Soil_Status', y='Soil_Moisture', hue='Pump_Status', data=df, jitter=True, palette='coolwarm')
plt.title('Soil Moisture vs Soil
Status and Pump Status')
plt.legend(title='Pump Status')
plt.grid(True)
plt.show()
sns.violinplot(x='Soil_Status', y='Soil_Moisture', hue='Pump_Status', data=df, split=True, palette='muted')
plt.title('Soil Moisture Distribution by Soil Status and Pump Status')
plt.grid(True)
plt.show()
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn.preprocessing import LabelEncoder
le_soil = LabelEncoder()
le_pump = LabelEncoder()
df['Soil_Status_Code'] = le_soil.fit_transform(df['Soil_Status'])
df['Pump_Status_Code'] = le_pump.fit_transform(df['Pump_Status'])
fig = plt.figure(figsize=(10, 7))
ax = fig.add_subplot(111, projection='3d')
ax.scatter(df['Soil_Moisture'],
df['Soil_Status_Code'],
df['Pump_Status_Code'],
c=df['Pump_Status_Code'], cmap='coolwarm', alpha=0.6)
ax.set_xlabel('Soil Moisture')
ax.set_ylabel('Soil Status')
ax.set_zlabel('Pump Status')
ax.set_title('3D Plot: Soil Moisture vs Soil Status vs Pump Status')
Text(0.5, 0.92, '3D Plot: Soil Moisture vs Soil Status vs Pump Status')
ax.set_yticks([0, 1, 2])
ax.set_yticklabels(le_soil.inverse_transform([0, 1, 2]))
ax.set_zticks([0, 1])
ax.set_zticklabels(le_pump.inverse_transform([0, 1]))
plt.tight_layout()
plt.show()
<Figure size 640x480 with 0 Axes>
pd.crosstab(df['Soil_Status'], df['Pump_Status'])
Pump_Status 0 1
Soil_Status
Dry 0 6
Medium 161 0
Wet 1 0
0 Comments