Soil moisture detection is essential in agriculture, gardening, and environmental monitoring. In modern agricultural practices, efficient water usage can improve crop yields while reducing water waste. A Soil Moisture Detection System can help monitor soil moisture content, ensuring plants receive the right amount of water at the right time. This project uses an Arduino Nano for microcontroller tasks, an RGB LED to indicate different moisture levels, and operates using a Lithium-ion battery for portability, making it compact and ideal for field use. The project is designed to offer a simple, effective solution for monitoring soil moisture in real-time.
Circuit Diagram
Components Required
- Arduino Nano
- Soil Moisture Sensor
- RGB LED
- Lithium-ion Battery (3.7V)
- TP4056 Lithium Battery Charging Module
- Resistors (220Ω, 330Ω)
- Jumper Wires
- Breadboard or PCB
- Switch
Parts Specification
Arduino Nano
- Microcontroller: ATmega328P
- Operating Voltage: 5V
- Analog Pins: A0-A7 (used to connect the soil moisture sensor to
A0
) - Digital Pins: D2-D13 (used for controlling the RGB LED)
- USB Port: For power and programming
Soil Moisture Sensor
- Type: Analog Soil Moisture Sensor
- Pinout:
- VCC: Power supply (typically 3.3V or 5V)
- GND: Ground
- A0: Analog output pin (connected to
A0
of Arduino Nano)
- Function: Measures the water content in the soil. The output voltage varies based on the moisture level—higher voltage for dry soil, and lower voltage for wet soil.
RGB LED (Common Cathode)
- Type: Common Cathode RGB LED (3 separate LEDs in one package: Red, Green, Blue)
- Pins:
- Cathode (GND): Common ground for all three LEDs
- Red Pin (connected to pin 9): Controls the red LED
- Green Pin (connected to pin 10): Controls the green LED
- Blue Pin (connected to pin 11): Controls the blue LED
- Function: Displays different colours based on the moisture level. By adjusting the intensity of each LED using PWM, it can create various colours:
- Red: Indicates dry soil.
- Green: Indicates optimal moisture.
- Blue: Indicates wet soil.
Resistors (220Ω)
- Purpose: Current limiting resistors for each colour channel of the RGB LED to prevent excessive current from damaging the LEDs.
- Resistor Value: 220Ω for each pin (connected between Arduino pins 9, 10, and 11, and the RGB LED’s corresponding red, green, and blue pins).
Power Supply
- Battery or USB Power: You can power the Arduino Nano using a USB connection or an external battery pack (5V).
Breadboard and Jumper Wires
- Breadboard: Used for prototyping and making connections between the Arduino Nano, sensor, and RGB LED.
- Jumper Wires: Connect components on the breadboard.
Optional Components:
- Enclosure: To house the Arduino Nano, soil moisture sensor, and RGB LED for field deployment.
- Lithium-Ion Battery: If using a portable setup, you can power the system using a 3.7V-5V lithium-ion battery with a battery management system.
Circuit Connections of Soil Moisture Detection System
The soil moisture sensor measures resistance between two probes inserted into the soil. The moisture content determines the level of resistance. This Analog data is processed by the Arduino Nano, which converts it into a moisture percentage and then drives the RGB LED to indicate the moisture level.
Arduino Nano to Soil Moisture Sensor:
- Sensor VCC → Arduino 5V
- Sensor GND → Arduino GND
- Sensor A0 (Analog Pin) → Arduino A0 (Analog Input)
RGB LED to Arduino Nano:
- Red Pin → Arduino D9 (with 330Ω resistor)
- Green Pin → Arduino D10 (with 330Ω resistor)
- Blue Pin → Arduino D11 (with 220Ω resistor)
RGB LED GND → Arduino GND
Lithium-ion Battery:
- Battery +ve → TP4056 IN+
- Battery -ve → TP4056 IN-
- TP4056 OUT+ → Arduino 5V
- TP4056 OUT- → Arduino GND
Power Switch:
Connected between the TP4056 output and Arduino Nano for power control.
The RGB LED changes colour based on the soil moisture level:
- Red: Low moisture (below 30%)
- Green: Optimal moisture (30% to 60%)
- Blue: High moisture (above 60%)
Working Principle of Soil Moisture Detection System
The soil moisture detection system operates by measuring the moisture content of the soil and displaying its status through an RGB LED. It uses an Arduino Nano microcontroller, a soil moisture sensor, and a common cathode RGB LED. The soil moisture sensor, which consists of two conductive probes, is inserted into the soil to detect changes in moisture levels. As the moisture increases, the sensor’s conductivity increases, causing its output voltage to decrease. This Analog output, ranging from 0 to 1023, is read by the Arduino through its Analog pin A0.
The Arduino Nano processes the sensor’s reading by converting the Analog value into a corresponding moisture percentage. This conversion is done using the map() function, which translates the sensor output into a scale from 0% (completely dry) to 100% (fully saturated). Once the moisture level is determined, the system uses the RGB LED to visually indicate the condition of the soil. If the moisture level is below 30%, the red light of the RGB LED is turned on, signalling that the soil is too dry and requires watering. If the moisture level is between 30% and 70%, the green light lights up, indicating that the soil is in optimal condition. When the moisture exceeds 70%, the blue light is activated, indicating that the soil is overly wet.
The RGB LED is controlled through pulse width modulation (PWM) signals from the Arduino’s digital pins, allowing each colour (red, green, and blue) to be adjusted independently. The system continuously monitors the soil’s moisture, updates the LED status every second, and prints the moisture readings to the serial monitor for real-time monitoring. This ensures that users are constantly informed of the soil’s condition, whether it is dry, optimal, or too wet, making it a useful tool for efficient plant care.
Source Code Explanation
1 2 3 4 | #define SENSOR_PIN A0 // Analog pin connected to the soil moisture sensor #define RED_PIN 9 // Red pin of RGB LED #define GREEN_PIN 10 // Green pin of RGB LED #define BLUE_PIN 11 // Blue pin of RGB LED |
- SENSOR_PIN is defined as A0, the Analog input pin connected to the soil moisture sensor.
- RED_PIN, GREEN_PIN, and BLUE_PIN are defined as pins 9, 10, and 11, respectively. These are the PWM-capable digital pins connected to the red, green, and blue channels of the RGB LED.
1 2 3 4 5 6 7 | void setup() { pinMode(RED_PIN, OUTPUT); pinMode(GREEN_PIN, OUTPUT); pinMode(BLUE_PIN, OUTPUT); Serial.begin(9600); // For debugging purposes } |
Setup Function:
pinMode()
is used to configure the RGB LED pins (RED_PIN
,GREEN_PIN
,BLUE_PIN
) as outputs. This is necessary to control the RGB LED.Serial.begin(9600)
initializes serial communication at a baud rate of 9600 bps. This allows you to print the soil moisture sensor readings to the Serial Monitor for debugging purposes.
1 2 3 | void loop() { int sensorValue = analogRead(SENSOR_PIN); // Read the sensor value from A0 Serial.println(sensorValue); // For debugging purposes |
Reading the Sensor:
analogRead(SENSOR_PIN)
reads the analog voltage from the soil moisture sensor connected toA0
. The sensor returns a value between 0 and 1023, corresponding to the soil’s moisture content.Serial.println(sensorValue)
prints the raw sensor value to the Serial Monitor for real-time observation. This is useful during debugging to see how the sensor values change as the moisture level changes.
1 2 | // Convert the sensor value to a moisture level percentage int moistureLevel = map(sensorValue, 1023, 0, 0, 100); |
Mapping Sensor Values:
- The
map()
function converts the raw sensor value (ranging from 0 to 1023) into a percentage representing the soil moisture level. The range is inverted (1023 to 0
mapped to0 to 100%
), so that 1023 (dry) corresponds to 0% moisture, and 0 (wet) corresponds to 100% moisture. moistureLevel
stores the percentage value that will be used to determine the LED colour.
1 2 3 4 5 6 7 8 | // Set RGB LED color based on moisture level if (moistureLevel < 30) { setColor(255, 0, 0); // Red for dry soil } else if (moistureLevel >= 30 && moistureLevel <= 70) { setColor(0, 255, 0); // Green for optimal moisture } else { setColor(0, 0, 255); // Blue for wet soil } |
Colour-logic:
- This block of code determines the colour of the RGB LED based on the moisture level:
- If the moisture level is less than 30% (dry soil), the
setColor(255, 0, 0)
function is called, turning on the red LED. - If the moisture level is between 30% and 70% (optimal moisture),
setColor(0, 255, 0)
is called, turning on the green LED. - If the moisture level exceeds 70% (wet soil),
setColor(0, 0, 255)
is called, activating the blue LED.
- If the moisture level is less than 30% (dry soil), the
- This provides a simple visual cue for the soil condition.
1 2 | delay(1000); // Wait for a second before the next reading } |
Loop Delay:
- After setting the LED colour, the system waits for 1 second before repeating the loop. This ensures that the soil moisture level is checked and the LED is updated every second.
1 2 3 4 5 6 | // Function to set RGB LED color void setColor(int red, int green, int blue) { analogWrite(RED_PIN, red); analogWrite(GREEN_PIN, green); analogWrite(BLUE_PIN, blue); } |
setColor Function:
- This function controls the RGB LED by setting the intensity of the red, green, and blue channels using
analogWrite()
. analogWrite()
generates a PWM signal on the given pin, allowing you to control the brightness of each colour (0 for OFF and 255 for full brightness).- The function takes three parameters (
red
,green
,blue
), which represent the intensity values for the red, green, and blue LEDs. - For example,
setColor(255, 0, 0)
will turn on the red LED fully, while the green and blue LEDs remain off, creating a red light.
Source Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | // Pin Definitions #define SENSOR_PIN A0 // Analog pin connected to the soil moisture sensor #define RED_PIN 9 // Red pin of RGB LED #define GREEN_PIN 10 // Green pin of RGB LED #define BLUE_PIN 11 // Blue pin of RGB LED void setup() { // Set RGB LED pins as output pinMode(RED_PIN, OUTPUT); pinMode(GREEN_PIN, OUTPUT); pinMode(BLUE_PIN, OUTPUT); // Initialize serial communication for debugging Serial.begin(9600); } void loop() { // Read the sensor value from the analog pin A0 int sensorValue = analogRead(SENSOR_PIN); // Print the sensor value to the Serial Monitor for debugging Serial.println(sensorValue); // Convert the sensor value to a moisture level percentage (0% to 100%) int moistureLevel = map(sensorValue, 1023, 0, 0, 100); // Set RGB LED color based on moisture level if (moistureLevel < 30) { setColor(255, 0, 0); // Red for dry soil } else if (moistureLevel >= 30 && moistureLevel <= 70) { setColor(0, 255, 0); // Green for optimal moisture } else { setColor(0, 0, 255); // Blue for wet soil } // Wait for 1 second before the next reading delay(1000); } // Function to set RGB LED color by adjusting PWM for each color channel void setColor(int red, int green, int blue) { analogWrite(RED_PIN, red); // Set red brightness analogWrite(GREEN_PIN, green); // Set green brightness analogWrite(BLUE_PIN, blue); // Set blue brightness } |