#include "DHTesp.h"
#include <ESP32Servo.h>
#include <LiquidCrystal_I2C.h>
#include <PubSubClient.h>
#include <WiFi.h>
#include <ArduinoJson.h>
// Configurações de WiFi
const char *SSID = "Wokwi-GUEST";
const char *PASSWORD = ""; // Substitua pela sua senha
// Configurações de MQTT
const char *BROKER_MQTT = "broker.hivemq.com";
const int BROKER_PORT = 1883;
const char *ID_MQTT = "esp32_mqtt";
const char *TOPIC_SUBSCRIBE_LED = "fiap/iot/tdsa/devtype/esp/devid/11/led";
const char *TOPIC_SUBSCRIBE_VALVULA = "fiap/iot/tdsa/devtype/esp/devid/11/valvula";
const char *TOPIC_PUBLISH_TEMP_HUMI = "fiap/iot/tdsa/devtype/esp/devid/11/temphumi";
// Configurações de Hardware
const int DHT_PIN = 15;
const int LDR_PIN = 2;
const int LedPin = 12;
const int servoPin = 14;
const int umidadelimite = 50;
const int valvulaAberta = 90;
const int valvulaFechada = 180;
// Variáveis globais
WiFiClient espClient;
PubSubClient MQTT(espClient);
LiquidCrystal_I2C lcd(0x27, 16, 2);
DHTesp dhtSensor;
Servo servo;
unsigned long lastPublishTime = 0;
const unsigned long PUBLISH_INTERVAL = 2000;
// Protótipos de funções
void reconnectWiFi();
void reconnectMQTT();
void callbackMQTT(char* topic, byte* payload, unsigned int length);
void checkWiFiAndMQTT();
void updateSensorValues();
// Função para configurar o WiFi
void reconnectWiFi() {
if (WiFi.status() == WL_CONNECTED) return;
Serial.print("Conectando ao WiFi...");
WiFi.begin(SSID, PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println();
Serial.print("Conectado com sucesso ao WiFi, IP: ");
Serial.println(WiFi.localIP());
}
// Função para configurar o MQTT
void reconnectMQTT() {
while (!MQTT.connected()) {
Serial.print("Tentando conectar ao Broker MQTT...");
if (MQTT.connect(ID_MQTT)) {
Serial.println("Conectado ao Broker MQTT!");
MQTT.subscribe(TOPIC_SUBSCRIBE_LED);
MQTT.subscribe(TOPIC_SUBSCRIBE_VALVULA);
} else {
Serial.println("Falha na conexão com o MQTT. Tentando novamente...");
delay(2000);
}
}
}
// Função de callback para lidar com mensagens recebidas
void callbackMQTT(char* topic, byte* payload, unsigned int length) {
String msg = String((char*)payload).substring(0, length);
Serial.printf("Mensagem recebida no tópico: %s\n", topic);
// Processar mensagem do LED
if (String(topic) == TOPIC_SUBSCRIBE_LED) {
if (msg == "ON") {
digitalWrite(LedPin, HIGH);
Serial.println("LED ligado via MQTT");
} else if (msg == "OFF") {
digitalWrite(LedPin, LOW);
Serial.println("LED desligado via MQTT");
}
}
// Processar mensagem para a válvula
if (String(topic) == TOPIC_SUBSCRIBE_VALVULA) {
if (msg == "ABERTA") {
servo.write(valvulaAberta);
Serial.println("Válvula aberta via MQTT");
} else if (msg == "FECHADA") {
servo.write(valvulaFechada);
Serial.println("Válvula fechada via MQTT");
}
}
}
// Função para atualizar os dados do sensor
void updateSensorValues() {
TempAndHumidity data = dhtSensor.getTempAndHumidity();
StaticJsonDocument<200> doc;
doc["temperatura"] = data.temperature;
doc["umidade"] = data.humidity;
char buffer[200];
serializeJson(doc, buffer);
// Publicar os dados de temperatura e umidade
MQTT.publish(TOPIC_PUBLISH_TEMP_HUMI, buffer);
Serial.println(buffer);
}
void setup() {
Serial.begin(115200);
pinMode(LedPin, OUTPUT);
pinMode(LDR_PIN, INPUT);
servo.attach(servoPin, 500, 2400);
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
lcd.init();
lcd.backlight();
reconnectWiFi();
MQTT.setServer(BROKER_MQTT, BROKER_PORT);
MQTT.setCallback(callbackMQTT);
}
void loop() {
checkWiFiAndMQTT();
MQTT.loop();
// Atualizar os sensores a cada intervalo
if (millis() - lastPublishTime >= PUBLISH_INTERVAL) {
lastPublishTime = millis();
updateSensorValues();
}
// Lógica para Ligar/desligar o LED com base no LDR
if (digitalRead(LDR_PIN) == LOW) {
digitalWrite(LedPin, LOW); // Ligar LED
} else {
digitalWrite(LedPin, HIGH); // Desligar LED
}
// Lógica para abrir ou fechar a válvula com base na umidade
TempAndHumidity data = dhtSensor.getTempAndHumidity();
if (data.humidity < umidadelimite) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Umidade baixa!");
lcd.setCursor(0, 1);
lcd.print("Válvula Aberta");
servo.write(valvulaAberta);
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Umidade Certa!");
lcd.setCursor(0, 1);
lcd.print("Válvula Fechada");
servo.write(valvulaFechada);
}
delay(1000); // Delay para evitar loop rápido demais
}
// Função para verificar se WiFi e MQTT estão conectados
void checkWiFiAndMQTT() {
if (WiFi.status() != WL_CONNECTED) {
reconnectWiFi();
}
if (!MQTT.connected()) {
reconnectMQTT();
}
}