Cirkit Designer LogoCirkit DesignerYour all-in-one circuit design IDE Launch Cirkit Designer App

ESP32-Based Plant Monitoring System with Wi-Fi Control and Relay Switching

View and Edit Project In Cirkit DesignerImage of ESP32-Based Plant Monitoring System with Wi-Fi Control and Relay Switching

Circuit Documentation

Summary

This circuit is designed for a plant monitoring system that interfaces with various sensors to measure environmental conditions such as temperature, humidity, and light intensity. It also controls a water pump via a relay module. The system is built around an ESP32 microcontroller, which is programmed to communicate with the Blynk platform for remote monitoring and control. The ESP32 reads sensor data, controls the relay, and updates the Blynk server with the sensor values. An LCD display provides local readouts of the sensor data.

Component List

Humidity YL-69 Sensor

Photosensitive Sensor Module

Water Pump

Relay Module (1 Channel)

ESP32 - Expansion Board

2x 18650 Battery Holder

DHT11 Humidity and Temperature Sensor

Wiring Details

Humidity YL-69 Sensor

Photosensitive Sensor Module

Water Pump

Relay Module (1 Channel)

ESP32 - Expansion Board

2x 18650 Battery Holder

DHT11 Humidity and Temperature Sensor

Documented Code

#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[] = "U_LC-vFWsz-x6y7oXznm5YBllNn1oHhU";  // Enter your Blynk Auth token
char ssid[] = "Redmi K50 Ultra";  // Enter your WIFI SSID
char pass[] = "12345678";  // 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