0% found this document useful (0 votes)
9 views8 pages

Updates Smoke Monitoring

The document is a code implementation for an ESP32 smoke detector system that connects to WiFi and sends alerts via a Google Apps Script webhook. It includes functionalities for smoke level detection, alarm activation, component testing, and WiFi management. The system features visual and auditory indicators for alarms and can reset automatically when smoke levels drop below a certain threshold.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views8 pages

Updates Smoke Monitoring

The document is a code implementation for an ESP32 smoke detector system that connects to WiFi and sends alerts via a Google Apps Script webhook. It includes functionalities for smoke level detection, alarm activation, component testing, and WiFi management. The system features visual and auditory indicators for alarms and can reset automatically when smoke levels drop below a certain threshold.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 8

#include <WiFi.

h>
#include <HTTPClient.h>
#include <ESP32Servo.h>

// WiFi Credentials - DOUBLE CHECK THESE


const char* ssid = "STARLINK";
const char* password = "Oakley4021?!";

// Webhook URL from your deployed Google Apps Script


// Make sure this URL is correct and the script is deployed as a web app with
proper permissions
const char* webhookUrl =
"https://script.google.com/macros/s/AKfycbysMSPlXFlmhyxnisxoabmkypvkQDI8U8G_idc64xQ
jkVErBS0QMvDWy96JeTNBARKNCw/exec";

// Uncomment and use this alternate URL for testing connectivity with a reliable
endpoint
// const char* webhookUrl = "https://httpbin.org/get";

// Pin Definitions
#define MQ2_PIN 34 // MQ-2 Smoke Sensor analog output connected to GPIO 34
#define RED_LED 4 // Red LED connected to GPIO 4
#define GREEN_LED 2 // Green LED connected to GPIO 2
#define BUZZER 15 // Buzzer connected to GPIO 15
#define SERVO_PIN 13 // Servo Motor control connected to GPIO 13

Servo myServo;
int sensorThreshold = 2000;
int resetThreshold; // Will be set to half of sensorThreshold
unsigned long lastWiFiAttempt = 0;
const unsigned long wifiRetryInterval = 10000; // Try WiFi reconnection every 10
seconds (reduced from 30s)

// Testing variables
bool testModeActive = false;
unsigned long testModeStartTime = 0;
const unsigned long testModeDuration = 10000; // 10 seconds test

// Buzzer variables
unsigned long buzzerToggleTime = 0;
bool buzzerState = false;
const unsigned long buzzerToggleInterval = 500; // Toggle every 500ms for more
noticeable sound

// System state variables


bool alarmActive = false;
bool emailSent = false;
unsigned long alarmStartTime = 0;
unsigned long lastEmailTime = 0;
const unsigned long emailCooldown = 300000; // 5 minutes between emails

// Function to send HTTP GET request to your webhook URL


void sendEmailWebhook() {
if (WiFi.status() == WL_CONNECTED) {
Serial.print("Attempting to connect to webhook at: ");
Serial.println(webhookUrl);
Serial.print("Current IP address: ");
Serial.println(WiFi.localIP());
HTTPClient http;
http.begin(webhookUrl); // Start connection to webhook
http.setTimeout(10000); // Increase timeout to 10 seconds

Serial.println("Sending HTTP request...");


int httpResponseCode = http.GET();

if (httpResponseCode > 0) {
Serial.print("Webhook response code: ");
Serial.println(httpResponseCode);
String payload = http.getString();
Serial.println("Response: " + payload);
lastEmailTime = millis(); // Update last email timestamp on success
emailSent = true;
} else {
Serial.print("Error sending webhook: ");
Serial.println(http.errorToString(httpResponseCode));
Serial.println("Possible reasons for connection refused:");
Serial.println("1. Incorrect webhook URL");
Serial.println("2. Google Apps Script permissions issue");
Serial.println("3. Network firewall blocking the connection");
Serial.println("4. Network requires proxy configuration");
}
http.end(); // Close connection
} else {
Serial.println("WiFi not connected!");
connectToWiFi(); // Try to reconnect immediately
}
}

bool connectToWiFi() {
Serial.println("\n------------------------------");
Serial.print("Connecting to WiFi SSID: ");
Serial.println(ssid);

WiFi.disconnect(true);
delay(1000);
WiFi.begin(ssid, password);

// Add timeout for this single connection attempt


int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) { // 10 second timeout for
this attempt
delay(500);
Serial.print(".");
attempts++;
}

if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nConnected to WiFi!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
digitalWrite(GREEN_LED, HIGH); // Show connected status
digitalWrite(RED_LED, LOW); // Ensure RED LED is off
return true;
} else {
Serial.println("\nFailed to connect to WiFi!");
Serial.print("WiFi status code: ");
Serial.println(WiFi.status());
digitalWrite(RED_LED, HIGH); // Indicate failed connection
delay(500);
digitalWrite(RED_LED, LOW);
return false;
}
}

// Persistent WiFi connection function - will keep trying until connected


void ensureWiFiConnection() {
Serial.println("Ensuring WiFi connection...");

// Blink both LEDs to show we're in connection mode


for(int i = 0; i < 3; i++) {
digitalWrite(RED_LED, HIGH);
digitalWrite(GREEN_LED, LOW);
delay(300);
digitalWrite(RED_LED, LOW);
digitalWrite(GREEN_LED, HIGH);
delay(300);
}
digitalWrite(RED_LED, LOW);
digitalWrite(GREEN_LED, LOW);

int connectionAttempts = 0;

// Keep trying until connected


while (WiFi.status() != WL_CONNECTED) {
connectionAttempts++;
Serial.print("Connection attempt #");
Serial.println(connectionAttempts);

// Show RED LED when trying to connect


digitalWrite(RED_LED, HIGH);

if (connectToWiFi()) {
// Connection successful
digitalWrite(RED_LED, LOW);
digitalWrite(GREEN_LED, HIGH);
Serial.println("WiFi connected successfully!");
return;
}

// If connection failed, wait before retry


Serial.println("Connection failed, retrying in 5 seconds...");
digitalWrite(RED_LED, HIGH);
delay(2000);
digitalWrite(RED_LED, LOW);
delay(3000); // Total 5 second wait between attempts
}
}

// Function to activate alarm state


void activateAlarm() {
if (!alarmActive) {
alarmActive = true;
alarmStartTime = millis();
Serial.println("🚨 ALARM ACTIVATED! Opening window for ventilation");
myServo.write(15); // Open window
}
}

// Function to reset alarm state


void resetAlarm() {
if (alarmActive) {
alarmActive = false;
emailSent = false;
Serial.println("✓ Smoke levels have dropped below reset threshold");
Serial.println("✓ SYSTEM RESET - Closing window");
myServo.write(150); // Close window

// Turn off alarm indicators


digitalWrite(RED_LED, LOW);
digitalWrite(BUZZER, LOW);
buzzerState = false;

// Turn on green LED if WiFi connected


if (WiFi.status() == WL_CONNECTED) {
digitalWrite(GREEN_LED, HIGH);
}
}
}

// Function to test all components


void testComponents() {
// Test Green LED
Serial.println("Testing GREEN LED...");
digitalWrite(GREEN_LED, HIGH);
delay(1000);
digitalWrite(GREEN_LED, LOW);
delay(500);

// Test Red LED


Serial.println("Testing RED LED...");
digitalWrite(RED_LED, HIGH);
delay(1000);
digitalWrite(RED_LED, LOW);
delay(500);

// Test Buzzer - FIXED for tone generation


Serial.println("Testing BUZZER...");

// Configure buzzer pin as output


pinMode(BUZZER, OUTPUT);

// Create a basic beep sound using manual PWM


for (int i = 0; i < 3; i++) {
for (int j = 0; j < 50; j++) { // Manual PWM cycle
digitalWrite(BUZZER, HIGH);
delayMicroseconds(500); // Half period of 1kHz tone
digitalWrite(BUZZER, LOW);
delayMicroseconds(500);
}
delay(200);
}

// Test Servo
Serial.println("Testing SERVO...");
myServo.write(15);
delay(1000);
myServo.write(150);
delay(500);

Serial.println("Component test complete!");


}

void setup() {
Serial.begin(115200);
delay(1000); // Give serial monitor time to start up
Serial.println("\n\n===== ESP32 SMOKE DETECTOR SYSTEM =====");
Serial.println("Production-Ready Version with Auto-Reset");

// Set reset threshold to fixed value of 1500


resetThreshold = 1500;
Serial.print("Alarm Threshold: ");
Serial.println(sensorThreshold);
Serial.print("Reset Threshold: ");
Serial.println(resetThreshold);

// Initialize pins before WiFi connection


pinMode(MQ2_PIN, INPUT);
pinMode(RED_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
pinMode(BUZZER, OUTPUT);

// Initialize all outputs to LOW


digitalWrite(RED_LED, LOW);
digitalWrite(GREEN_LED, LOW);
digitalWrite(BUZZER, LOW);

// Initialize servo
myServo.attach(SERVO_PIN);
myServo.write(150); // Default position (window closed)

// Run component test


Serial.println("Running component test...");
testComponents();

// Connect to WiFi - persistently try until successful


Serial.println("Starting WiFi connection process...");
ensureWiFiConnection();

Serial.println("Setup complete. Starting main loop...");


Serial.println("===== TEST MODE INSTRUCTIONS =====");
Serial.println("Send 'T' over Serial to trigger a 10-second smoke detection
test");
Serial.println("Send 'C' to run component test again");
Serial.println("Send 'W' to force WiFi reconnection");
Serial.println("Send 'R' to manually reset the system");
Serial.println("=================================");
}

// Manual tone function for buzzer


void playTone(int pin, int duration) {
unsigned long startTime = millis();
while (millis() - startTime < duration) {
digitalWrite(pin, HIGH);
delayMicroseconds(500); // Adjust this for different frequencies
digitalWrite(pin, LOW);
delayMicroseconds(500); // Together with the above = ~1kHz tone
}
}

void loop() {
// Check for Serial commands
if (Serial.available() > 0) {
char command = Serial.read();
if (command == 'T' || command == 't') {
testModeActive = true;
testModeStartTime = millis();
Serial.println("TEST MODE ACTIVATED - Simulating smoke detection for 10
seconds");
} else if (command == 'C' || command == 'c') {
Serial.println("Running component test...");
testComponents();
} else if (command == 'W' || command == 'w') {
Serial.println("Forcing WiFi reconnection...");
ensureWiFiConnection();
} else if (command == 'R' || command == 'r') {
Serial.println("Manual system reset initiated");
resetAlarm();
}
}

// Read actual sensor value


int actualSmokeLevel = analogRead(MQ2_PIN);

// Determine smoke level (actual or simulated)


int smokeLevel;
if (testModeActive) {
// In test mode, simulate high smoke reading
smokeLevel = 9000; // Value above threshold

// Check if test mode should end


if (millis() - testModeStartTime >= testModeDuration) {
testModeActive = false;
Serial.println("TEST MODE ENDED");
}
} else {
// Normal mode - use actual readings
smokeLevel = actualSmokeLevel;
}

// Log the values


Serial.print("Actual Smoke Level: ");
Serial.print(actualSmokeLevel);
if (testModeActive) {
Serial.print(" | TEST MODE: Simulated Level: ");
Serial.print(smokeLevel);
}
if (alarmActive) {
Serial.print(" | ALARM ACTIVE");
}
Serial.println();

// Check WiFi status periodically and reconnect if disconnected


unsigned long currentMillis = millis();
if (WiFi.status() != WL_CONNECTED && (currentMillis - lastWiFiAttempt >
wifiRetryInterval)) {
Serial.println("WiFi disconnected, attempting to reconnect...");
ensureWiFiConnection(); // Use persistent connection function
lastWiFiAttempt = currentMillis;
}

// ALARM ACTIVATION LOGIC


if (smokeLevel >= sensorThreshold) {
// Activate alarm if not already active
activateAlarm();

// Set visual indicators


digitalWrite(RED_LED, HIGH);
digitalWrite(GREEN_LED, LOW);

// Improved buzzer control - using manual PWM approach


if (currentMillis - buzzerToggleTime >= buzzerToggleInterval) {
buzzerState = !buzzerState;
buzzerToggleTime = currentMillis;
}

// Generate tone if buzzer should be on


if (buzzerState) {
// Quick manual PWM pulse
digitalWrite(BUZZER, HIGH);
delayMicroseconds(500);
digitalWrite(BUZZER, LOW);
delayMicroseconds(500);
}

// Email sending logic with cooldown


bool shouldSendEmail = !emailSent || (currentMillis - lastEmailTime >
emailCooldown);

if (shouldSendEmail) {
if (testModeActive) {
Serial.println("🚨 [TEST] Smoke Detected! Sending actual email alert...");
} else {
Serial.println("🚨 Smoke Detected! Sending Email via Webhook...");
}

// If WiFi is not connected, try to reconnect before sending email


if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi disconnected, attempting to reconnect before sending
alert...");
connectToWiFi(); // Try a quick reconnect
}

// Send email if WiFi is connected (even in test mode)


if (WiFi.status() == WL_CONNECTED) {
sendEmailWebhook(); // Call the webhook function to trigger email
} else {
Serial.println("Cannot send email - WiFi not connected!");
}
}
}
// AUTO-RESET LOGIC
else if (alarmActive && smokeLevel <= resetThreshold) {
// Auto-reset the system when smoke levels drop below reset threshold
resetAlarm();
}
else if (!alarmActive) {
// Normal operation - no alarm
digitalWrite(RED_LED, LOW);
digitalWrite(BUZZER, LOW); // Ensure buzzer is off
buzzerState = false;

if (WiFi.status() == WL_CONNECTED) {
digitalWrite(GREEN_LED, HIGH); // Keep green LED on when connected
} else {
digitalWrite(GREEN_LED, LOW);
}
}

delay(50); // Shorter main loop delay for better responsiveness


}

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy