ESP32-Based Smart Irrigation System with Soil Moisture Sensing and Wi-Fi Connectivity
View and Edit Project In Cirkit Designer
Circuit Documentation
Summary
This circuit is designed to monitor soil moisture levels and control a water pump based on the moisture data. It also measures temperature and humidity using a DHT11 sensor. The system is controlled by an ESP32 microcontroller, which is capable of Wi-Fi connectivity to send sensor data to a server. The circuit includes a relay module to control the water pump, soil moisture sensor, DHT11 sensor, and multiple LEDs to indicate the status of the sensors and the relay. Power is supplied by two 5V batteries.
Component List
Soil Moisture Sensor
- Pins: VCC, GND, SIG
- Description: Measures the moisture level in the soil.
Water Pump
- Pins: VCC, GND
- Description: Pumps water when activated by the relay module.
DHT11 Humidity and Temperature Sensor
- Pins: VDD, DATA, NULL, GND
- Description: Measures the ambient temperature and humidity.
LEDs (Red)
- Pins: cathode, anode
- Description: Indicates various statuses in the circuit.
Resistors
- Pins: pin1, pin2
- Description: Limits current to protect LEDs.
- Value: 200 Ohms
ESP32
- Pins: Multiple GPIOs, GND, VIN, 3V3, EN, etc.
- Description: Microcontroller with Wi-Fi capability for controlling the circuit and communicating with a server.
5V Batteries
- Pins: positive, negative
- Description: Provides power to the circuit.
1 Channel 5V Relay Module
- Pins: VCC+, VCC- (GND), IN, N.O., COM, N.C.
- Description: Controls the water pump, allowing it to turn on or off.
Wiring Details
Soil Moisture Sensor
- VCC connected to 3V3 of ESP32
- GND connected to common ground
- SIG connected to GPIO D4 of ESP32
Water Pump
- VCC connected to N.O. of Relay Module
- GND connected to common ground
DHT11 Humidity and Temperature Sensor
- VDD connected to 3V3 of ESP32
- DATA connected to GPIO D5 of ESP32
- GND connected to common ground
LEDs (Red)
- Each LED has its anode connected to a GPIO on the ESP32 and its cathode connected to a resistor, which is then connected to common ground.
Resistors
- Each resistor is connected in series with an LED to limit the current.
ESP32
- VIN connected to the positive of the 5V battery
- GND connected to common ground
- 3V3 provides power to sensors
- Multiple GPIOs are used for sensor data and control signals.
5V Batteries
- One battery provides power to the ESP32 (VIN and GND).
- The other battery provides power to the Relay Module (VCC+ and COM).
1 Channel 5V Relay Module
- VCC+ connected to the positive of the second 5V battery
- VCC- (GND) connected to common ground
- IN connected to GPIO D18 of ESP32
- N.O. connected to VCC of Water Pump
- COM connected to the positive of the second 5V battery
Documented Code
#include <DHT.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <EEPROM.h>
// Pin definitions for sensors and relay
#define SOIL_MOISTURE_PIN 4 // Soil Moisture Sensor on GPIO 4
#define DHT_PIN 5 // DHT11 Sensor on GPIO 5
#define RELAY_PIN 18 // Relay Module for Water Pump on GPIO 18
#define DHT_TYPE DHT11 // DHT Sensor Type
// LED pin definitions
#define LED_SOIL_MOISTURE_PIN 25 // LED for Soil Moisture Sensor on GPIO 25
#define LED_DHT_PIN 27 // LED for DHT11 Sensor on GPIO 27
#define LED_RELAY_PIN 32 // LED for Relay Module on GPIO 32
#define LED_ERROR_PIN 33 // LED for error indication on GPIO 33
// DHT sensor instance
DHT dht(DHT_PIN, DHT_TYPE);
// Variables for Wi-Fi credentials (use secure storage or environment variables in real scenarios)
String ssid;
String password;
String serverUrl = "https://yourserver.com/api/sensor-data"; // Use HTTPS for secure communication (configurable)
// Variables for adaptive threshold adjustment
int soilMoistureThreshold = 300; // Default threshold for soil moisture
int soilMoistureReadings[10]; // Array to store soil moisture readings
int soilMoistureAverage = 0; // Average soil moisture value
int previousReading = 0; // Previous reading for comparison
unsigned long lastThresholdUpdate = 0; // Time of last threshold update
const unsigned long thresholdUpdateInterval = 60000; // Update threshold every minute (60 seconds)
// Variables for non-blocking soil moisture threshold adjustment
unsigned long thresholdReadMillis = 0; // Store the time of the last read
int thresholdReadIndex = 0; // To track the number of readings taken
// Variables for non-blocking LED feedback
unsigned long lastErrorBlinkTime = 0;
unsigned long lastDHTErrorBlinkTime = 0;
unsigned long errorBlinkInterval = 500; // Time interval for LED blinking
bool ledState = false; // LED state for blink control
// Setup function
void setup() {
Serial.begin(115200);
// Initialize pins
pinMode(SOIL_MOISTURE_PIN, INPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(LED_SOIL_MOISTURE_PIN, OUTPUT);
pinMode(LED_DHT_PIN, OUTPUT);
pinMode(LED_RELAY_PIN, OUTPUT);
pinMode(LED_ERROR_PIN, OUTPUT); // Initialize error LED
// Initialize DHT sensor
dht.begin();
// Initialize EEPROM for secure storage
EEPROM.begin(512);
loadWiFiCredentials(); // Load Wi-Fi credentials from EEPROM
// Initialize Wi-Fi connection
connectToWiFi();
// Initialize threshold update logic
lastThresholdUpdate = millis(); // Set the last update time to the current time
}
// Loop function
void loop() {
unsigned long currentMillis = millis();
// Update soil moisture threshold every minute
if (currentMillis - lastThresholdUpdate >= thresholdUpdateInterval) {
calculateThreshold(); // Directly call calculateThreshold() without redundancy
lastThresholdUpdate = currentMillis; // Update threshold only every minute
}
// Read sensors and control system
readSensors();
// Blink error LED if Wi-Fi is not connected
if (WiFi.status() != WL_CONNECTED) {
blinkLED(LED_ERROR_PIN, lastErrorBlinkTime, 1); // Pattern 1 for Wi-Fi error
}
}
// --- Modularized Sensor Reading Function ---
void readSensors() {
int soilMoistureValue = readSoilMoisture();
float humidity, temperature;
bool dhtError = readDHT(humidity, temperature);
// Print sensor values to Serial Monitor
Serial.print("Soil Moisture: "); Serial.println(soilMoistureValue);
Serial.print("Humidity: "); Serial.print(humidity);
Serial.print(" % Temperature: "); Serial.println(temperature);
// Control water pump based on soil moisture value
controlWaterPump(soilMoistureValue);
// Control LEDs based on sensor values
controlLEDs(soilMoistureValue);
// Blink DHT error LED if there's a sensor reading error
if (dhtError) {
blinkLED(LED_DHT_PIN, lastDHTErrorBlinkTime, 2); // Pattern 2 for DHT error
}
// Send sensor data to server
sendDataToServer(soilMoistureValue, temperature, humidity);
}
// --- Modularized Soil Moisture Reading ---
int readSoilMoisture() {
return analogRead(SOIL_MOISTURE_PIN);
}
// --- Modularized DHT Reading ---
bool readDHT(float &humidity, float &temperature) {
humidity = dht.readHumidity();
temperature = dht.readTemperature();
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Error: Could not read DHT sensor data.");
return true; // Return error flag
}
return false; // No error
}
// --- Modularized Control Functions ---
void controlWaterPump(int soilMoistureValue) {
if (soilMoistureValue < soilMoistureThreshold) {
digitalWrite(RELAY_PIN, HIGH); // Turn on water pump
digitalWrite(LED_RELAY_PIN, HIGH); // Turn on Relay LED
} else {
digitalWrite(RELAY_PIN, LOW); // Turn off water pump
digitalWrite(LED_RELAY_PIN, LOW); // Turn off Relay LED
}
}
void controlLEDs(int soilMoistureValue) {
if (soilMoistureValue < soilMoistureThreshold) {
digitalWrite