#define BLYNK_TEMPLATE_ID "TMPL6GzdM1BTs"
#define BLYNK_TEMPLATE_NAME "ESP32 for Gas Sensor Monitoring"
#define BLYNK_AUTH_TOKEN "2nPzhXmkZhH3wetwSj5Hfv8C2HFLBF8e"
#define BLYNK_PRINT Serial
#define BUTTON_PIN 26
#define RELAY_PIN 22
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include "DHT.h"
#include <Wire.h> // I2C library for LCD
#include <LiquidCrystal_I2C.h> // LCD library for I2C LCD
// Blynk authentication token
char auth[] = BLYNK_AUTH_TOKEN; // Auth Token
// Your network credentials
char ssid[] = "Wokwi-GUEST"; // WiFi SSID
char pass[] = ""; // WiFi password
BlynkTimer timer;
// DHT sensor setup
#define DHTPIN 15 // DHT22 data pin
#define DHTTYPE DHT22 // DHT sensor type
// Potentiometer setup
#define METHANE_PIN 34 // Potentiometer pin (use this to simulate methane level)
#define CO2_PIN 35 // New Pin for CO2 level
#define LED1_RED 16 // First LED pin (indicates high gas levels)
#define LED2_GREEN 4 // Second LED pin (indicates safe levels)
#define VALVE_LED_PIN 17 // Valve LED pin (open/closed)
DHT dht(DHTPIN, DHTTYPE); // Create a DHT object
// LCD setup
LiquidCrystal_I2C lcd(0x27, 20, 4); // I2C address of the LCD, 20 columns and 4 rows
// Blynk virtual pins
#define VIRTUAL_METHANE V0 // Virtual pin for methane percentage
#define VIRTUAL_CO2 V1 // Virtual pin for CO2 percentage
#define VIRTUAL_TEMP V2 // Virtual pin for temperature
#define VIRTUAL_IDEAL V3 // Virtual pin for ideal range status
#define VIRTUAL_OUT_OF_RANGE V4 // Virtual pin for out of range status
#define VIRTUAL_VALVE V5 // Virtual pin for valve status
#define VIRTUAL_BUTTON V6 // Virtual button pin for valve control
const int buttonPin = BUTTON_PIN; // Pin for push button
const int relayPin = RELAY_PIN; // Pin for relay
bool valveState = false; // Track the state of the valve
unsigned long lastButtonPress = 0; // For debouncing button presses
void setup() {
Serial.begin(115200); // Initialize serial communication
dht.begin(); // Initialize the DHT sensor
pinMode(LED1_RED, OUTPUT); // Set LED1 as output
pinMode(LED2_GREEN, OUTPUT); // Set LED2 as output
pinMode(VALVE_LED_PIN, OUTPUT); // Set Valve LED as output
pinMode(buttonPin, INPUT_PULLUP); // Set button pin as input with pull-up
pinMode(relayPin, OUTPUT); // Set relay pin as output
digitalWrite(relayPin, LOW); // Initialize relay to OFF
// Initialize LCD
lcd.init();
lcd.setBacklight(1); // Turn on backlight
lcd.clear();
// Connect to WiFi
Blynk.begin(auth, ssid, pass);
}
// Function to toggle valve state
void toggleValve() {
valveState = !valveState; // Toggle the valve state
// Activate the relay based on valve state
if (valveState) {
digitalWrite(relayPin, HIGH); // Open valve (turn relay ON)
digitalWrite(VALVE_LED_PIN, HIGH); // Turn on Valve LED
} else {
digitalWrite(relayPin, LOW); // Close valve (turn relay OFF)
digitalWrite(VALVE_LED_PIN, LOW); // Turn off Valve LED
}
// Send valve status to Blynk
Blynk.virtualWrite(VIRTUAL_VALVE, valveState);
Serial.print("Valve State: ");
Serial.println(valveState ? "Open" : "Closed");
}
// Blynk function to handle virtual button press
BLYNK_WRITE(VIRTUAL_BUTTON) {
toggleValve(); // Toggle the valve when the button is pressed in Blynk
}
void loop() {
// Blynk.run() handles communication with Blynk servers
Blynk.run();
// Read methane percentage from potentiometer
int methaneLevel = analogRead(METHANE_PIN);
float methanePercentage = map(methaneLevel, 0, 4095, 0, 100); // Map to percentage
// Read CO2 percentage from another potentiometer
int co2Level = analogRead(CO2_PIN);
float co2Percentage = map(co2Level, 0, 4095, 0, 100); // Map to percentage
// Read temperature from DHT sensor
float t = dht.readTemperature(); // Read temperature in Celsius
// Check if DHT sensor reading is valid
if (isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
// Send data to Blynk app
Blynk.virtualWrite(VIRTUAL_METHANE, methanePercentage); // Send methane percentage
Blynk.virtualWrite(VIRTUAL_CO2, co2Percentage); // Send CO2 percentage
Blynk.virtualWrite(VIRTUAL_TEMP, t); // Send temperature
// Print the values to the Serial Monitor
Serial.print("Methane Percentage: ");
Serial.print(methanePercentage);
Serial.print(" CO2 Percentage: ");
Serial.print(co2Percentage);
Serial.print(" Temperature: ");
Serial.print(t);
Serial.println(" °C");
// Update the LCD every second to avoid flickering
static unsigned long lastLcdUpdate = 0;
if (millis() - lastLcdUpdate >= 1000) {
lastLcdUpdate = millis(); // Update time
// Display temperature on the first row
lcd.setCursor(0, 0); // Set cursor to the first row
lcd.print("Temp: ");
lcd.print(t);
if (t > 35) { // Temperature warning (above 35°C)
lcd.print(" !!HIGH!!");
} else if (t < 30) { // Temperature warning (below 30°C)
lcd.print(" !!LOW!!");
} else { // Ideal range
lcd.print(" --OK--");
}
// Display CO2 on the second row
lcd.setCursor(0, 1); // Set cursor to the second row
lcd.print("CO2: ");
lcd.print(co2Percentage);
if (co2Percentage > 40) { // CO2 warning (above 40%)
lcd.print(" !!HIGH!!");
} else if (co2Percentage < 30) { // CO2 warning (below 30%)
lcd.print(" !!LOW!!");
} else { // Ideal range
lcd.print(" --OK--");
}
// Display methane on the third row
lcd.setCursor(0, 2); // Set cursor to the third row
lcd.print("CH4: ");
lcd.print(methanePercentage);
if (methanePercentage > 75) { // Methane warning (above 75%)
lcd.print(" !!HIGH!!");
} else if (methanePercentage < 50) { // Methane warning (below 50%)
lcd.print(" !!LOW!!");
} else { // Ideal range
lcd.print(" --OK--");
}
// Display valve state on the fourth row
lcd.setCursor(0, 3); // Set cursor to the fourth row
lcd.print("Valve: ");
if (valveState) {
lcd.print("Open");
} else {
lcd.print("Closed");
}
}
// Define the thresholds for gas levels and temperature
float methaneThresholdHigh = 75.0; // Methane high threshold
float methaneThresholdLow = 50.0; // Methane low threshold
float co2ThresholdHigh = 40.0; // CO2 high threshold
float co2ThresholdLow = 30.0; // CO2 low threshold
float tempThresholdHigh = 35.0; // Temperature high threshold
float tempThresholdLow = 30.0; // Temperature low threshold
// Control LEDs based on methane, CO2, and temperature values
if (methanePercentage >= methaneThresholdLow && methanePercentage <= methaneThresholdHigh &&
co2Percentage >= co2ThresholdLow && co2Percentage <= co2ThresholdHigh &&
t >= tempThresholdLow && t <= tempThresholdHigh) {
// All conditions met for green LED (safe state)
digitalWrite(LED1_RED, LOW); // Turn off Red LED
digitalWrite(LED2_GREEN, HIGH); // Turn on Green LED
} else {
// Conditions violated, turn on red LED (alarm state)
digitalWrite(LED1_RED, HIGH); // Turn on Red LED
digitalWrite(LED2_GREEN, LOW); // Turn off Green LED
}
// Check if the button is pressed (with debouncing)
if (digitalRead(buttonPin) == LOW && (millis() - lastButtonPress) > 300) {
toggleValve(); // Toggle the valve when the physical button is pressed
lastButtonPress = millis(); // Update the time of last press
Serial.println("Physical button pressed.");
}
delay(100); // Wait for a small amount of time to reduce CPU load
}