ESP32-Based Smart Plant Monitoring System with Wi-Fi Control
View and Edit Project In Cirkit Designer
Circuit Documentation
Summary
The circuit is designed to monitor environmental parameters for plant growth, including temperature, humidity, soil moisture, and motion detection. It uses an ESP32 microcontroller as the central processing unit, interfacing with various sensors and output devices. The system can be controlled and monitored remotely via the Blynk platform.
Component List
- ESP32 - Expansion Board: A microcontroller board based on the ESP32 chip, featuring Wi-Fi and Bluetooth connectivity, along with multiple digital and analog I/O pins.
- I2C LCD 16x2 Screen: A 16-character by 2-line display that communicates with the ESP32 over the I2C bus.
- DHT22: A sensor for measuring ambient temperature and humidity.
- Humidity YL-69: A soil moisture sensor that outputs an analog signal corresponding to the moisture level in the soil.
- PIR/Motion Sensor: A passive infrared sensor that detects motion by measuring changes in the infrared levels emitted by surrounding objects.
- Relay module 1 channel: An electrically operated switch that allows the ESP32 to control high power devices, such as a water pump.
- Pushbutton: A simple switch that allows for user input to the system.
- Water pump: An actuator that can be turned on or off by the relay to water plants.
- 2x 18650: A power source consisting of two 18650 lithium-ion batteries.
Wiring Details
ESP32 - Expansion Board
- D27: Connected to Pushbutton (input)
- G: Connected to Pushbutton (output), Humidity YL-69 (GND), Relay module (GND), I2C LCD Screen (GND), DHT22 (-), PIR/Motion Sensor (GND)
- VP: Connected to Humidity YL-69 (A0)
- D23: Connected to Relay module (S)
- D22: Connected to I2C LCD Screen (SCL)
- D21: Connected to I2C LCD Screen (SDA)
- D19: Connected to DHT22 (Out)
- D18: Connected to PIR/Motion Sensor (OUTPUT)
- VCC: Connected to 2x 18650 (vcc)
- V: Connected to Humidity YL-69 (VCC), Relay module (5V), I2C LCD Screen (VCC (5V)), DHT22 (+), PIR/Motion Sensor (VCC)
I2C LCD 16x2 Screen
- SCL: Connected to ESP32 (D22)
- SDA: Connected to ESP32 (D21)
- VCC (5V): Connected to ESP32 (V)
- GND: Connected to ESP32 (G)
DHT22
- Out: Connected to ESP32 (D19)
- +: Connected to ESP32 (V)
- -: Connected to ESP32 (G)
Humidity YL-69
- A0: Connected to ESP32 (VP)
- D0: Not connected
- GND: Connected to ESP32 (G)
- VCC: Connected to ESP32 (V)
PIR/Motion Sensor
- GND: Connected to ESP32 (G)
- OUTPUT: Connected to ESP32 (D18)
- VCC: Connected to ESP32 (V)
Relay module 1 channel
- S: Connected to ESP32 (D23)
- 5V: Connected to ESP32 (V)
- GND: Connected to ESP32 (G)
- NC: Not connected
- COM: Connected to Water pump (positive)
- NO: Connected to 2x 18650 (vcc)
Pushbutton
- Pin 1 (in): Connected to ESP32 (D27)
- Pin 3 (out): Connected to ESP32 (G)
- Pin 2 (in) and Pin 4 (out): Not connected
Water pump
- Positive: Connected to Relay module (COM)
- Negative: Connected to 2x 18650 (gnd)
2x 18650
- Vcc: Connected to ESP32 (VCC), Relay module (NO)
- Gnd: Connected to Water pump (negative)
Documented Code
// Define Blynk template ID and Name
#define BLYNK_TEMPLATE_ID "TMPL6rlQf3Kxk"
#define BLYNK_TEMPLATE_NAME "plant monitoring sistem"
/* Connections
Relay: GPIO23
Btn: GPIO27
Soil: GPIO36 (VP)
PIR: GPIO18
SDA: GPIO21
SCL: GPIO22
Temp: GPIO19
*/
// Include the library files
#include <LiquidCrystal_I2C.h>
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <DHT.h>
// Initialize the LCD display
LiquidCrystal_I2C lcd(0x3F, 16, 2);
char auth[] = "YourAuthToken"; // Enter your Blynk Auth token
char ssid[] = "YourNetworkName"; // Enter your WIFI SSID
char pass[] = "YourPassword"; // Enter your WIFI Password
DHT dht(19, DHT22); // (DHT sensor pin, sensor type) GPIO19 DHT22 Temperature Sensor
BlynkTimer timer;
// Define component pins
#define soil 36 // GPIO36 (VP) for Soil Moisture Sensor
#define PIR 18 // GPIO18 for PIR Motion Sensor
int PIR_ToggleValue;
void checkPhysicalButton();
int relay1State = LOW;
int pushButton1State = HIGH;
#define RELAY_PIN_1 23 // GPIO23 for Relay
#define PUSH_BUTTON_1 27 // GPIO27 for Button
#define VPIN_BUTTON_1 V12
// Create three variables for pressure
double T, P;
char status;
void setup() {
Serial.begin(9600);
lcd.begin(16, 2); // Initialize the LCD with 16 columns and 2 rows
lcd.backlight();
pinMode(PIR, INPUT);
pinMode(RELAY_PIN_1, OUTPUT);
digitalWrite(RELAY_PIN_1, LOW);
pinMode(PUSH_BUTTON_1, INPUT_PULLUP);
digitalWrite(RELAY_PIN_1, relay1State);
Blynk.begin(auth, ssid, pass, "blynk.cloud", 80);
dht.begin();
lcd.setCursor(0, 0);
lcd.print(" Initializing ");
for (int a = 5; a <= 10; a++) {
lcd.setCursor(a, 1);
lcd.print(".");
delay(500);
}
lcd.clear();
lcd.setCursor(11, 1);
lcd.print("W:OFF");
// Call the function
timer.setInterval(100L, soilMoistureSensor);
timer.setInterval(100L, DHT22sensor);
timer.setInterval(500L, checkPhysicalButton);
}
// Get the DHT22 sensor values
void DHT22sensor() {
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
Blynk.virtualWrite(V0, t);
Blynk.virtualWrite(V1, h);
lcd.setCursor(0, 0);
lcd.print("T:");
lcd.print(t);
lcd.setCursor(8, 0);
lcd.print("H:");
lcd.print(h);
}
// Get the soil moisture values
void soilMoistureSensor() {
int value = analogRead(soil);
value = map(value, 0, 4095, 0, 100); // ESP32 has a 12-bit ADC
value = (value - 100) * -1;
Blynk.virtualWrite(V3, value);
lcd.setCursor(0, 1);
lcd.print("S:");
lcd.print(value);
lcd.print(" ");
}
// Get the PIR sensor values
void PIRsensor() {
bool value = digitalRead(PIR);
if (value) {
Blynk.logEvent("pirmotion", "WARNING! Motion Detected!"); // Enter your Event Name
WidgetLED LED(V5);
LED.on();
} else {
WidgetLED LED(V5);
LED.off();
}
}
BLYNK_WRITE(V6)
{
PIR_ToggleValue = param.asInt();
}
BLYNK_CONNECTED() {
// Request the latest state from the server
Blynk.syncVirtual(VPIN_BUTTON_1);
}
BLYNK_WRITE(VPIN_BUTTON_1) {
relay1State = param.asInt();
digitalWrite(RELAY_PIN_1, relay1State);
}
void checkPhysicalButton() {
if (digitalRead(PUSH_BUTTON_1) == LOW) {
// pushButton1State is used to avoid sequential toggles
if (pushButton1State != LOW) {
// Toggle Relay state
relay1State = !relay1State;
digitalWrite(RELAY_PIN_1