#include <WiFi.h>
#include <PubSubClient.h>
#include <math.h>
#include <HTTPClient.h>
const int MQ4_PIN = 35;
const int LED_VERMELHO = 25;
const int BUZZER_PIN = 33;
const int LED_VERDE = 26;
// Para Wokwi: ssid = "Wokwi-GUEST", password = ""
// Para ESP32 físico: use o SSID e a senha da sua rede doméstica
const char* ssid = "";
const char* password = "";
const char* mqtt_server = "test.mosquitto.org";
const int mqtt_port = 1883;
const char* mqtt_user = "";
const char* mqtt_password = "";
const char* mqtt_topic_alerta = "seguranca/alerta";
const char* mqtt_client_id = "ESP32_Gas_Detector";
WiFiClient espClient;
PubSubClient client(espClient);
bool alarmeAtivo = false;
unsigned long ultimaAtivacaoBuzzer = 0;
const long TEMPO_BUZZER_LIGADO = 2000;
const long TEMPO_INTERVALO_BUZZER = 3000;
const long TEMPO_ENTRE_ALERTAS_MQTT = 30000;
unsigned long ultimoAlertaMQTT = 0;
float ultimoGLP = 0;
const float DELTA_PPM = 50.0;
const char* ifttt_webhook_url = "https://maker.ifttt.com/trigger/gas_alerta/with/key/d2imDNpypMjhtzyWoaFI9k";
void setup_wifi() {
delay(10);
Serial.println("\n");
Serial.print("Conectando a ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
unsigned long startTime = millis();
const long TIMEOUT_WIFI = 20000;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
if (millis() - startTime > TIMEOUT_WIFI) {
Serial.println("\nFalha ao conectar ao WiFi. Verifique as credenciais e a rede.");
return;
}
}
Serial.println("");
Serial.println("WiFi conectado!");
Serial.print("Endereço IP: ");
Serial.println(WiFi.localIP());
}
void reconnect_mqtt() {
while (!client.connected()) {
Serial.print("Tentando conexão MQTT...");
if (client.connect(mqtt_client_id, mqtt_user, mqtt_password)) {
Serial.println("conectado!");
} else {
Serial.print("falha, rc=");
Serial.print(client.state());
Serial.println(" tentando novamente em 5 segundos");
delay(5000);
}
}
}
void enviarAlertaIFTTT() {
HTTPClient http;
http.begin(ifttt_webhook_url);
int code = http.GET();
http.end();
Serial.print("IFTTT HTTP Response: ");
Serial.println(code);
}
void setup() {
Serial.begin(115200);
pinMode(MQ4_PIN, INPUT);
pinMode(LED_VERMELHO, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(LED_VERDE, OUTPUT);
digitalWrite(LED_VERMELHO, LOW);
digitalWrite(BUZZER_PIN, LOW);
digitalWrite(LED_VERDE, HIGH);
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
}
void loop() {
if (!client.connected()) {
reconnect_mqtt();
}
client.loop();
int leitura = analogRead(MQ4_PIN);
float Vout = leitura * (3.3 / 4095.0);
float RL = 10.0;
float Rs = (3.3 - Vout) * RL / Vout;
// Valor padrão de Rs em ar limpo
float R0 = 46.5;
float ratio = Rs / R0;
// Estimativa de GLP (gás de cozinha)
float a_glp = -0.31;
float b_glp = 0.71;
float ppm_glp = pow(10, ((log10(ratio) - b_glp) / a_glp));
if (abs(ppm_glp - ultimoGLP) > DELTA_PPM) {
Serial.print("GLP: ");
Serial.print(ppm_glp, 1);
Serial.println(" ppm");
Serial.println("---------");
ultimoGLP = ppm_glp;
}
const float LIMIAR_PPM_GLP = 350;
if (ppm_glp > LIMIAR_PPM_GLP) {
if (!alarmeAtivo) {
alarmeAtivo = true;
digitalWrite(LED_VERMELHO, HIGH);
digitalWrite(LED_VERDE, LOW);
String mensagem = "ALERTA: GLP detectado! " + String(ppm_glp, 1) + " ppm";
client.publish(mqtt_topic_alerta, mensagem.c_str());
enviarAlertaIFTTT();
ultimoAlertaMQTT = millis();
}
if (millis() - ultimaAtivacaoBuzzer >= TEMPO_INTERVALO_BUZZER) {
digitalWrite(BUZZER_PIN, HIGH);
ultimaAtivacaoBuzzer = millis();
}
if (millis() - ultimaAtivacaoBuzzer >= TEMPO_BUZZER_LIGADO) {
digitalWrite(BUZZER_PIN, LOW);
}
if (millis() - ultimoAlertaMQTT >= TEMPO_ENTRE_ALERTAS_MQTT) {
String mensagem = "ALERTA CONTINUO: GLP persistente! " + String(ppm_glp, 1) + " ppm";
client.publish(mqtt_topic_alerta, mensagem.c_str());
enviarAlertaIFTTT();
ultimoAlertaMQTT = millis();
}
} else {
if (alarmeAtivo) {
alarmeAtivo = false;
digitalWrite(LED_VERMELHO, LOW);
digitalWrite(BUZZER_PIN, LOW);
client.publish(mqtt_topic_alerta, "STATUS: GLP resolvido. Alarme desativado.");
}
digitalWrite(LED_VERDE, HIGH);
}
delay(500);
}