/*
Module name and code: Emerging Technologies (SWE6206)
Student Name and ID Darshan Patel - 2109302
Tutor: Dr Mohammed Benmubarak
Assignment Number: 2
Assignment Title: Emerging Technologies based Industry Solutions
*/
/*
ESP32 Advance Greenhouse
https://wokwi.com/projects/386619061354859521
Copyright (C) 2024, Darshan Patel
*/
// Blynk Template Information
#define BLYNK_TEMPLATE_ID "TMPL5ehCDwZAZ"
#define BLYNK_TEMPLATE_NAME "Advance Greenhouse"
#define BLYNK_AUTH_TOKEN "S5lFMBmJzii6C5QlFyApPU2z_7btBHn8"
// Include Libraries
#include <DHTesp.h>
#include <Wire.h>
#include <ESP32Servo.h>
#include <LiquidCrystal_I2C.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
// Blynk Authentication and Wi-Fi Credentials
char auth[] = "S5lFMBmJzii6C5QlFyApPU2z_7btBHn8";
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
// Pin Definitions
#define SOIL_MOISTURE_PIN 34
#define RAIN_SENSOR_PIN 35
#define DHT_PIN 17
#define BUZZER_PIN 5
#define RELAY_PIN 4
#define RELAYHEATER_PIN 18
#define WATERSPRINKLER_SERVO_PIN 14
// Servo Object for Watersprinkler
Servo watersprinklerServo;
// Thresholds and Intervals
const int buzzerThreshold = 20;
const float temperatureThreshold = 27;
const int soilMoistureThreshold = 30;
const int readInterval = 1000;
// DHT Sensor Object
DHTesp dht;
// LCD Display Objects
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 8);
LiquidCrystal_I2C lcd2 = LiquidCrystal_I2C(0x27, 20, 8);
// Blynk Timer
BlynkTimer timer;
// Global Variables
float temperature, humidity, soilMoisture; // Declare variables at global scope
static unsigned long lastReadTime = 0; // Add this line to declare lastReadTime
// Setup Function
void setup() {
Serial.begin(9600);
dht.setup(DHT_PIN, DHTesp::DHT22);
lcd.init();
lcd.backlight();
lcd2.init();
lcd2.backlight();
watersprinklerServo.attach(WATERSPRINKLER_SERVO_PIN);
ledcSetup(0, 1000, 10);
pinMode(RELAY_PIN, OUTPUT);
pinMode(RELAYHEATER_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
Serial.print("Connecting to WiFi");
WiFi.begin("Wokwi-GUEST", "");
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println(" Connected!");
Blynk.begin(auth, ssid, pass);
timer.setInterval(2500L, sendSensor);
}
// Loop Function
void loop() {
Blynk.run();
timer.run();
if (millis() - lastReadTime >= readInterval) {
float temperature, humidity;
float soilMoisture, rainSensor;
temperature = dht.getTemperature();
humidity = dht.getHumidity();
soilMoisture = analogRead(SOIL_MOISTURE_PIN);
rainSensor = analogRead(RAIN_SENSOR_PIN);
soilMoisture = map(soilMoisture, 0, 4095, 0, 100);
rainSensor = map(rainSensor, 0, 4095, 0, 100);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Humidity: ");
lcd.print(humidity);
lcd.print("%");
lcd.setCursor(0, 1);
lcd.print("Temperature: ");
lcd.print(temperature);
lcd.print("C");
lcd.setCursor(0, 2);
lcd.print("SoilMoisture: ");
lcd.print(soilMoisture);
lcd.print("%");
lcd.setCursor(0, 3);
lcd.print("Rain Sensor: ");
lcd.print(rainSensor);
lcd.print("%");
if (temperature > temperatureThreshold || soilMoisture < soilMoistureThreshold) {
activateRelayAndAlert(soilMoisture);
} else if (temperature <= 15 ) {
turnonHeaters();
lcd2.clear();
lcd2.setCursor(0, 0);
lcd2.print("Heaters are ON");
} else {
turnOffRelayAndAlert();
turnoffHeaters();
}
lastReadTime = millis();
}
delay(10);
}
// Function to Send Sensor Data to Blynk
void sendSensor() {
TempAndHumidity data = dht.getTempAndHumidity();
temperature = data.temperature;
humidity = data.humidity;
soilMoisture = analogRead(SOIL_MOISTURE_PIN);
soilMoisture = map(soilMoisture, 0, 4095, 0, 100); // Map the soil moisture value
Blynk.virtualWrite(V0, temperature);
Blynk.virtualWrite(V1, humidity);
Blynk.virtualWrite(V2, soilMoisture);
Blynk.virtualWrite(V3, digitalRead(RELAY_PIN));
Blynk.virtualWrite(V4, digitalRead(RELAY_PIN));
}
// Function to Activate Relay and Trigger Alerts
void activateRelayAndAlert(float soilMoisture) {
digitalWrite(RELAY_PIN, LOW);
if (soilMoisture < buzzerThreshold || temperature > 33 ) {
beepBuzzer(5); // Five short beeps for low soil moisture
activateWatersprinkler();
} else {
beepBuzzer(1); // One short beep for other conditions
}
}
// Function to Turn Off Relay and Stop Alerts
void turnOffRelayAndAlert() {
digitalWrite(RELAY_PIN, HIGH);
noTone(BUZZER_PIN);
}
// Function to Turn On Heaters
void turnonHeaters() {
digitalWrite(RELAYHEATER_PIN, LOW);
beepBuzzer(2); // Two short beep for temperature less or equal to 15
}
// Function to Turn Off Heaters
void turnoffHeaters() {
digitalWrite(RELAYHEATER_PIN, HIGH);
noTone(BUZZER_PIN);
}
// Function to Generate Beep Patterns
void beepBuzzer(int pattern) {
for (int i = 0; i < pattern; i++) {
tone(BUZZER_PIN, 1000);
delay(200);
noTone(BUZZER_PIN);
delay(200);
}
delay(500); // Pause between patterns
}
// Function to Activate Watersprinkler
void activateWatersprinkler() {
watersprinklerServo.attach(WATERSPRINKLER_SERVO_PIN);
watersprinklerServo.write(180);
delay(10);
}
// Function to Deactivate Watersprinkler
void deactivateWatersprinkler() {
watersprinklerServo.detach();
}