/*
* ================================================================
* TRABALHO DE CASA — Código-base para o simulador Wokwi
* Curso: Eletrônica para IoT · Biopark · Prof. Marcelo Hickmann
* ================================================================
*
* Este é o seu PONTO DE PARTIDA para a Parte 1 do trabalho.
* Ele é a estação completa da aula (DHT22 + LED + servo + alarme
* com histerese + publicação MQTT), já adaptada para rodar no
* simulador Wokwi (wokwi.com) — nenhuma placa é necessária.
*
* O QUE MUDOU EM RELAÇÃO AO CÓDIGO DA AULA (etapa 6)?
* ---------------------------------------------------
* Na aula usamos o HiveMQ CLOUD: conexão cifrada (TLS, porta
* 8883) com usuário e senha. Em casa, para simplificar, usamos
* o broker PÚBLICO de testes da HiveMQ. Quatro diferenças:
*
* 1) WiFiClient no lugar de WiFiClientSecure (sem TLS)
* 2) porta 1883 no lugar de 8883
* 3) mqtt.connect() SÓ com o nome — sem usuário e sem senha
* 4) some o setInsecure() (ele só existia por causa do TLS)
*
* Reflexo para o seu relatório: num broker público, QUALQUER
* pessoa no mundo pode ler (e publicar!) no seu tópico. Ótimo
* para aprender; inaceitável em produção. É exatamente por isso
* que a aula usou TLS + credenciais.
*
* Wi-Fi NO SIMULADOR
* ------------------
* O Wokwi tem uma rede especial, sem senha, com acesso real à
* internet: "Wokwi-GUEST". Já está configurada abaixo.
*
* BIBLIOTECAS (aba "Library Manager" do projeto Wokwi):
* -----------------------------------------------------
* DHT sensor library (Adafruit)
* Adafruit Unified Sensor
* ESP32Servo
* PubSubClient
*
* LIGAÇÕES NO DIAGRAMA (mesmas da aula):
* --------------------------------------
* DHT22: VCC->3V3 DATA->GPIO 4 GND->GND
* LED : anodo (perna longa) -> resistor 220R -> GPIO 2
* catodo -> GND
* (no simulador o LED e externo; na placa era o embutido)
* Servo: GND->GND V+->5V(VIN) PWM/sinal->GPIO 13
*
* NÃO ESQUEÇA: troque SEUNOME no tópico e no ID do cliente!
* ================================================================
*/
#include <WiFi.h>
#include <PubSubClient.h>
#include "DHT.h"
#include <ESP32Servo.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C LCD = LiquidCrystal_I2C(0x27, 16, 2);
// ---------------- REDE E BROKER (Wokwi + broker público) ----------------
#define WIFI_SSID "Wokwi-GUEST" // rede do simulador (sem senha)
#define WIFI_SENHA ""
#define BROKER "broker.hivemq.com" // broker publico de testes
#define PORTA 1883 // sem TLS no broker publico
// TROQUE "SEUNOME" pelo seu nome (sem espacos e sem acentos):
#define TOPICO "biopark/casa/Leandro/ambiente"
#define ID_CLIENTE "esp32-casa-Leandro" // nome UNICO no broker
// ---------------- HARDWARE ----------------
#define rele_temp 14
#define rele_umidade 12
#define PINO_LED 15
#define PINO_DHT 4
#define PINO_SERVO 13
#define LIMITE 28.0 // liga o alarme acima disso (graus C)
#define FOLGA 1.0 // histerese: desliga abaixo de 27.0
// ---------------- OBJETOS ----------------
DHT dht(PINO_DHT, DHT22);
Servo registro;
WiFiClient canal; // conexao comum (o publico nao usa TLS)
PubSubClient mqtt(canal);
// ---------------- VARIAVEIS ----------------
float temperatura = 0.0;
float umidade = 0.0;
bool alarme = false;
// ============ Conectar ao Wi-Fi ============
void conectaWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_SENHA);
Serial.print("Conectando ao Wi-Fi");
while (WiFi.status() != WL_CONNECTED) {
delay(400);
Serial.print(".");
}
Serial.println(" conectado!");
}
// ============ Conectar ao broker ============
void conectaMQTT() {
mqtt.setServer(BROKER, PORTA);
while (!mqtt.connected()) {
Serial.print("Conectando ao broker MQTT... ");
// Broker publico: so o nome do cliente, sem usuario e sem senha
if (mqtt.connect(ID_CLIENTE)) {
Serial.println("conectado!");
} else {
// rc=-2: endereco/porta errados ou sem internet no simulador
Serial.print("falhou, rc=");
Serial.println(mqtt.state());
delay(2000);
}
}
}
// ================= setup() =================
void setup() {
Serial.begin(115200);
pinMode(PINO_LED, OUTPUT);
digitalWrite(PINO_LED, LOW);
dht.begin();
registro.attach(PINO_SERVO);
registro.write(0);
Serial.println();
Serial.println("=== TRABALHO DE CASA: estacao no Wokwi ===");
Serial.println("Dica: clique no DHT22 durante a simulacao para");
Serial.println("'esquentar' e 'esfriar' o sensor e testar o alarme.");
Serial.println();
conectaWiFi();
conectaMQTT();
}
// ================= loop() =================
void loop() {
if (WiFi.status() != WL_CONNECTED) conectaWiFi();
if (!mqtt.connected()) conectaMQTT();
mqtt.loop();
// -------- LER --------
temperatura = dht.readTemperature();
umidade = dht.readHumidity();
if (isnan(temperatura) || isnan(umidade)) {
Serial.println("Falha na leitura do DHT22. Confira a fiacao no diagrama.");
delay(2000);
return;
}
// -------- DECIDIR (alarme + histerese, como na aula) --------
bool alarmeAntes = alarme;
if (alarme == false && temperatura > LIMITE) {
alarme = true;
}
else if (alarme == true && temperatura < LIMITE - FOLGA) {
alarme = false;
}
// -------- AGIR --------
digitalWrite(PINO_LED, alarme ? HIGH : LOW);
if (alarme != alarmeAntes) {
registro.write(alarme ? 90 : 0);
Serial.println(alarme ? ">>> ALARME! Registro ABERTO (90 graus)"
: ">>> Normalizado. Registro FECHADO (0 graus)");
}
// -------- PUBLICAR --------
char mensagem[40];
snprintf(mensagem, sizeof(mensagem), "%.1f;%.0f;%d",
temperatura, umidade, alarme ? 1 : 0);
bool enviou = mqtt.publish(TOPICO, mensagem);
Serial.printf("Publicado em %s -> %s (%s)\n",
TOPICO, mensagem, enviou ? "ok" : "ERRO");
// ================================================================
// >>> SEU RECURSO ENTRA AQUI (ou onde fizer sentido!) <<<
// Ideias do enunciado: segundo estagio de alarme (LED piscando
// acima de 32), botao de silenciar, topico de status, LED verde
// de "sistema saudavel", limite ajustavel por mensagem MQTT...
// Comente o que voce criou: os comentarios valem nota.
// ================================================================
delay(5000);
}