#include <DHT.h>
#include <PubSubClient.h>
#include <WiFi.h>
#define DHTPIN 32
#define DHTTYPE DHT22
#define MQ2PIN 33
#define ALARME_SONORO 4
#define COIFA 17
#define AR_CONDICIONADO 16
DHT dht(DHTPIN, DHTTYPE);
enum statusCozinha {
NOMINAL,
GAS,
TEMP_ALTA,
UMIDADE_ALTA
};
int alarmStatus = NOMINAL;
float umidade = 0;
float temperatura = 0;
int iqAR = 0;
const int GAS_ON = 940; // 1000ppm
const int GAS_OFF = 916; // 500ppm
float UMIDADE_ON = 70.0;
float UMIDADE_OFF = UMIDADE_ON - 5;
float TEMP_ON = 30.0;
float TEMP_OFF = TEMP_ON - 2;
const char* WIFI_SSID = "Wokwi-GUEST";
const char* WIFI_PASSWORD = "";
const char* MQTT_BROKER = "77.37.69.84";
const int MQTT_PORT = 1883;
char MQTT_CLIENTID[32] = { 0 };
const char* MQTT_SUB_TOPICS[] = { "cozinha/max_tmp", "cozinha/max_umi" };
const char* MQTT_PUB_TOPIC = "cozinha";
char msg[255];
const int MQTT_SUB_COUNT = sizeof(MQTT_SUB_TOPICS) / sizeof(MQTT_SUB_TOPICS[0]);
void mqttCallback(char* topic, byte* payload, unsigned int length)
{
Serial.print("[MQTT] Mensagem em [");
Serial.print(topic);
Serial.println("]");
char buf[64];
int n = (length < (sizeof(buf) - 1)) ? length : (sizeof(buf) - 1);
memcpy(buf, payload, n);
buf[n] = '\0';
// show payload for debugging
Serial.print("[MQTT] payload: ");
Serial.println(buf);
if (strcmp(topic, "cozinha/max_tmp") == 0) {
float v = atof(buf);
if (!isnan(v)) {
TEMP_ON = v;
TEMP_OFF = TEMP_ON - 2;
Serial.print("[MQTT] TEMP_ON definido para ");
Serial.println(TEMP_ON);
} else {
Serial.println("[MQTT] Temperatura inválida");
}
} else if (strcmp(topic, "cozinha/max_umi") == 0) {
float v = atof(buf);
if (!isnan(v)) {
UMIDADE_ON = v;
UMIDADE_OFF = UMIDADE_ON - 5;
Serial.print("[MQTT] UMIDADE_ON definido para ");
Serial.println(UMIDADE_ON);
} else {
Serial.println("[MQTT] Umidade inválida");
}
}
}
WiFiClient espClient;
PubSubClient mqtt(espClient);
void connectWiFi()
{
Serial.print("[WiFi] Conectando...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\r\n[WiFi] Conectado!");
}
void connectMQTT()
{
mqtt.setServer(MQTT_BROKER, MQTT_PORT);
mqtt.setCallback(mqttCallback);
while (!mqtt.connected()) {
Serial.println("[MQTT] Conectando...");
if (mqtt.connect(MQTT_CLIENTID)) {
Serial.println("[MQTT] Conectado!");
for (int i = 0; i < MQTT_SUB_COUNT; ++i) {
if (mqtt.subscribe(MQTT_SUB_TOPICS[i])) {
Serial.print("[MQTT] Tópico assinado: ");
Serial.println(MQTT_SUB_TOPICS[i]);
} else {
Serial.print("[MQTT] Assinatura falhou: ");
Serial.println(MQTT_SUB_TOPICS[i]);
}
}
break;
} else {
Serial.print(" ERRO! (rc=");
Serial.print(mqtt.state());
Serial.println("). Tentando novamente em 2s...");
delay(2000);
}
}
}
void read_DHT()
{
umidade = dht.readHumidity();
temperatura = dht.readTemperature();
if (isnan(umidade) || isnan(temperatura)) {
Serial.println("Erro na leitura");
}
}
void check_alarm()
{
if (alarmStatus == GAS) {
if (iqAR > GAS_OFF)
return;
} else {
if (iqAR > GAS_ON) {
alarmStatus = GAS;
return;
}
}
if (alarmStatus == UMIDADE_ALTA) {
if (umidade > UMIDADE_OFF)
return;
} else {
if (umidade > UMIDADE_ON) {
alarmStatus = UMIDADE_ALTA;
return;
}
}
if (alarmStatus == TEMP_ALTA) {
if (temperatura > TEMP_OFF)
return;
} else {
if (temperatura > TEMP_ON) {
alarmStatus = TEMP_ALTA;
return;
}
}
alarmStatus = NOMINAL;
}
void refresh_sensors()
{
read_DHT();
iqAR = analogRead(MQ2PIN);
sprintf(msg, "{\"tmp\": %3.2f, \"umi\": %3.2f, \"gas\": %d}", temperatura, umidade, iqAR);
mqtt.publish(MQTT_PUB_TOPIC, msg);
check_alarm();
}
void setup()
{
Serial.begin(115200);
dht.begin();
Serial.println("DHT iniciado");
snprintf(MQTT_CLIENTID, sizeof(MQTT_CLIENTID), "esp32_%08X", (uint32_t)(ESP.getEfuseMac() & 0xFFFFFFFF));
analogReadResolution(10);
pinMode(ALARME_SONORO, OUTPUT);
pinMode(COIFA, OUTPUT);
pinMode(AR_CONDICIONADO, OUTPUT);
pinMode(MQ2PIN, INPUT);
pinMode(DHTPIN, INPUT);
digitalWrite(ALARME_SONORO, LOW);
digitalWrite(COIFA, LOW);
digitalWrite(AR_CONDICIONADO, LOW);
connectWiFi();
connectMQTT();
}
void loop()
{
if (!mqtt.connected()) {
connectMQTT();
}
mqtt.loop();
digitalWrite(ALARME_SONORO, LOW);
digitalWrite(COIFA, LOW);
digitalWrite(AR_CONDICIONADO, LOW);
refresh_sensors();
int alarmCounter = 0;
unsigned long start = millis();
while (millis() - start < 2000UL) {
mqtt.loop();
delay(10);
}
while (alarmStatus != NOMINAL) {
switch (alarmStatus) {
case GAS:
digitalWrite(ALARME_SONORO, HIGH);
case UMIDADE_ALTA:
digitalWrite(COIFA, HIGH);
break;
case TEMP_ALTA:
digitalWrite(AR_CONDICIONADO, HIGH);
break;
default:
Serial.println("STATUS DESCONHECIDO");
}
alarmCounter++;
delay(500);
if (alarmCounter > 5) {
refresh_sensors();
alarmCounter = 0;
}
}
}COIFA
AR CONDICIONADO
ALARME SONORO