#define BLYNK_TEMPLATE_ID "TMPL3Dc0_Sn9y"
#define BLYNK_TEMPLATE_NAME "Smart Agriculture"
#define BLYNK_AUTH_TOKEN "lWXg0DUTJucl5cr-SQCTnAttaOOUch5N"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
// Pin definitions
#define DHTPIN 15
#define DHTTYPE DHT22
#define SOIL_PIN 34
#define LDR_PIN 35
#define BUZZER_PIN 25
#define RELAY_PIN 26
// Threshold values
#define SOIL_DRY 3000 // Calibrate these!
#define SOIL_WET 1000 // for your soil sensor
#define TEMP_HIGH 40.0
#define TEMP_LOW 5.0
#define HUM_HIGH 90.0
#define HUM_LOW 20.0
#define LIGHT_DARK 300
char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16, 2);
BlynkTimer timer;
// Alert tracking
bool lastTempAlert = false;
bool lastHumAlert = false;
bool lastSoilAlert = false;
bool lastLightAlert = false;
void setup() {
Serial.begin(115200);
// Initialize hardware
pinMode(BUZZER_PIN, OUTPUT);
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
digitalWrite(RELAY_PIN, LOW);
dht.begin();
lcd.init();
lcd.backlight();
lcd.clear();
lcd.print("System booting...");
// Connect to WiFi
Serial.println("Connecting to WiFi...");
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
// Connect to Blynk
Serial.println("Connecting to Blynk...");
Blynk.config(auth);
while (!Blynk.connect()) {
delay(1000);
Serial.print(".");
}
Serial.println("\nBlynk connected!");
timer.setInterval(2000L, checkConditions);
}
void checkConditions() {
// Read sensors
float temp = dht.readTemperature();
float hum = dht.readHumidity();
int soil = analogRead(SOIL_PIN);
int light = analogRead(LDR_PIN);
// Convert soil moisture
int soilPercent = map(soil, SOIL_DRY, SOIL_WET, 0, 100);
soilPercent = constrain(soilPercent, 0, 100);
// Check thresholds
bool currentTempAlert = (temp >= TEMP_HIGH || temp <= TEMP_LOW);
bool currentHumAlert = (hum >= HUM_HIGH || hum <= HUM_LOW);
bool currentSoilAlert = (soilPercent <= 30);
bool currentLightAlert = (light <= LIGHT_DARK);
// Temperature alerts
if (currentTempAlert && !lastTempAlert) {
String msg = "CRITICAL TEMP: " + String(temp,1) + "°C";
Serial.println(msg);
Blynk.logEvent("temp_alert", msg);
lastTempAlert = true;
} else if (!currentTempAlert && lastTempAlert) {
Serial.println("Temperature back to normal");
lastTempAlert = false;
}
// Humidity alerts
if (currentHumAlert && !lastHumAlert) {
String msg = "CRITICAL HUMIDITY: " + String(hum,0) + "%";
Serial.println(msg);
Blynk.logEvent("hum_alert", msg);
lastHumAlert = true;
} else if (!currentHumAlert && lastHumAlert) {
Serial.println("Humidity back to normal");
lastHumAlert = false;
}
// Soil alerts
if (currentSoilAlert && !lastSoilAlert) {
String msg = "CRITICAL SOIL: " + String(soilPercent) + "% (DRY)";
Serial.println(msg);
Blynk.logEvent("soil_alert", msg);
lastSoilAlert = true;
digitalWrite(RELAY_PIN, HIGH);
Serial.println("Water pump ACTIVATED");
} else if (!currentSoilAlert && lastSoilAlert) {
Serial.println("Soil moisture normalized");
lastSoilAlert = false;
digitalWrite(RELAY_PIN, LOW);
Serial.println("Water pump DEACTIVATED");
}
// Light alerts
if (currentLightAlert && !lastLightAlert) {
String msg = "CRITICAL LIGHT: " + String(light) + " (TOO DARK)";
Serial.println(msg);
Blynk.logEvent("light_alert", msg);
lastLightAlert = true;
} else if (!currentLightAlert && lastLightAlert) {
Serial.println("Light level normalized");
lastLightAlert = false;
}
// Control buzzer
bool anyAlert = currentTempAlert || currentHumAlert || currentSoilAlert || currentLightAlert;
digitalWrite(BUZZER_PIN, anyAlert ? HIGH : LOW);
// Update display
updateDisplay(temp, hum, soilPercent, light, anyAlert);
// Send data to Blynk
Blynk.virtualWrite(V0, temp);
Blynk.virtualWrite(V1, hum);
Blynk.virtualWrite(V2, soilPercent);
Blynk.virtualWrite(V3, light);
}
void updateDisplay(float temp, float hum, int soil, int light, bool alert) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("T:");
lcd.print(temp, 1);
lcd.print("C H:");
lcd.print(hum, 0);
lcd.print("%");
lcd.setCursor(0, 1);
lcd.print("S:");
lcd.print(soil);
lcd.print("% L:");
lcd.print(light);
if (alert) {
lcd.setCursor(15, 0);
lcd.print("!");
}
}
void loop() {
Blynk.run();
timer.run();
}