/*
Include -> Incluí bibliotecas (códigos prontos) para o funcionamento
dos módulos especificos.
*/
#include <DHTesp.h> // Bibliote do Sensor de Temperatura e Umidade
#include <PubSubClient.h> // Biblioteca para a Comunicação MQTT
#include <WiFi.h> // Bilbioteca para Módulo WiFi
#include <ESP32Servo.h> // Bilibioteca para o Servo Motor
/*
Defines -> definição de constantes que serão utilizadas pelas
bibliotecas.
*/
#define pinoLampada 12 // GPIO que está ligado o LED
#define pinoRele 19 // GPIO que está ligado o Relé
#define pinoMotor 15 // GPIO que está ligado Servo Motor
#define pinoSensor 25 // GPIO que está ligado a Leitura do Sensor
#define pinoLedWifi 13 // GPIO esta ligado led para indicar conexao com Wifi
/* Configura os tópicos do MQTT */
#define TOPIC_SUBSCRIBE_LED "topic_on_off_led"
#define TOPIC_SUBSCRIBE_MOTOR "topic_on_off_motor"
#define TOPIC_PUBLISH_TEMPERATURA "topic_sensor_temperatura"
#define TOPIC_PUBLISH_UMIDADE "topic_sensor_umidade"
#define TOPIC_PUBLISH_LED "topic_status_lampada"
#define TOPIC_PUBLISH_MOTOR "topic_status_motor"
#define PUBLISH_DELAY 500 // Atraso da publicação (1 segundos)
/*
IMPORTANTE: Este deve ser único no broker, ou seja, se um client MQTT
tentar entrar com o mesmo id de outro já conectado ao broker,
o broker irá fechar a conexão de um deles.
*/
#define ID_MQTT "PietroVito29" // id mqtt (para identificação de sessão)
/* Variaveis, constantes e objetos globais */
// URL do broker MQTT que se deseja utilizar
const char *BROKER_MQTT = "mqtt-dashboard.com";
int BROKER_PORT = 1883; // Porta do Broker MQTT
DHTesp dht; // Instancia um objeto do Sensot
Servo servo; // Instancia um objeto do Motor
WiFiClient espClient; // Instancia o objeto espClient
PubSubClient MQTT(espClient); // Instancia o Cliente MQTT passando o objeto espClient
/* Variaveis de Controle */
bool statusLampada = 0;
bool statusMotor = 0;
bool statusConexao = 0;
int posicaoMotor = 0; // Variavel para controlar o Giro do Motor
/* Variaveis para transmissão de conteúdos */
static char textoTemperatura[10] = {0};
static char textoUmidade[10] = {0};
static char textoConexao[10] = {0};
/* Variáveis para Conexao com WiFi */
const char *SSID = "Wokwi-GUEST"; // SSID / nome da rede WI-FI que deseja se conectar
const char *PASSWORD = ""; // Senha da rede WI-FI que deseja se conectar
const int CHANNEL = 6; // Canal da rede WI-FI que deseja se conectar
unsigned long publishUpdate; // Ultima Atualizacao para controlar tempo.
/* Funcoes para implementação */
float lerTemperatura(void);
float lerUmidade(void);
void iniciaWiFi(void);
void iniciaMQTT(void);
void callbackMQTT(char *topic, byte *payload, unsigned int length);
void reconectaMQTT(void);
void reconectaWiFi(void);
void checkWiFIeMQTT(void);
void alternaLampada(void);
void alternaMotor(void);
void setup() {
// Comunicação Serial
Serial.begin(115200);
Serial.println("Hello, ESP32!");
// Configura os pinos como Entradas ou Saídas
pinMode(pinoLampada, OUTPUT);
pinMode(pinoRele, OUTPUT);
pinMode(pinoLedWifi, OUTPUT);
pinMode(pinoSensor, INPUT);
// Inicializa o Servo Motor
servo.attach(pinoMotor, 500, 2400);
servo.write(posicaoMotor);
digitalWrite(pinoRele, HIGH);
statusMotor = 1;
// Inicializacao do sensor de temperatura
dht.setup(pinoSensor, DHTesp::DHT22);
// Inicializa a conexao Wi-Fi
digitalWrite(pinoLedWifi, LOW);
iniciaWiFi();
// Inicializa a conexao ao broker MQTT
iniciaMQTT();
MQTT.publish(TOPIC_PUBLISH_LED, "0");
MQTT.publish(TOPIC_PUBLISH_MOTOR, "1");
}
void loop() {
/* Repete o ciclo após 0,5 segundos */
if ((millis() - publishUpdate) >= PUBLISH_DELAY) {
publishUpdate = millis();
// Verifica o funcionamento das conexões WiFi e ao broker MQTT
checkWiFIeMQTT();
// Formata as strings a serem enviadas para o dashboard (campos texto)
sprintf(textoTemperatura, "%.1f", lerTemperatura());
sprintf(textoUmidade, "%.1f", lerUmidade());
// Envia as strings ao dashboard MQTT
MQTT.publish(TOPIC_PUBLISH_TEMPERATURA, textoTemperatura);
MQTT.publish(TOPIC_PUBLISH_UMIDADE, textoUmidade);
// Keep-alive da comunicação com broker MQTT
MQTT.loop();
}
}
/********************************************************************/
void alternaLampada(){
statusLampada = !statusLampada;
digitalWrite(pinoLampada, statusLampada);
if(statusLampada){
MQTT.publish(TOPIC_PUBLISH_LED, "1");
Serial.println("Comando Recebido >> Lampada Ligada!");
}else{
Serial.println("Comando Recebido >> Lampada Desligada!");
MQTT.publish(TOPIC_PUBLISH_LED, "0");
}
}
/********************************************************************/
void alternaMotor(){
// Alterna os Leds Indicadores
statusMotor = !statusMotor;
digitalWrite(pinoRele, statusMotor);
if(statusMotor){
posicaoMotor = 0;
servo.write(posicaoMotor);
MQTT.publish(TOPIC_PUBLISH_MOTOR, "1");
Serial.println("Comando Recebido >> Trava Fechada");
}else{
posicaoMotor = 90;
servo.write(posicaoMotor);
MQTT.publish(TOPIC_PUBLISH_MOTOR, "0");
Serial.println("Comando Recebido >> Trava Aberta");
}
}
/********************************************************************/
/* Faz a leitura da temperatura (sensor DHT22)
Retorno: temperatura (graus Celsius) */
float lerTemperatura()
{
TempAndHumidity dados = dht.getTempAndHumidity();
if (!(isnan(dados.temperature))){
return dados.temperature;
}else{
return -99.99;
}
}
/********************************************************************/
/* Faz a leitura da umidade relativa do ar (sensor DHT22)
Retorno: umidade (0 - 100%) */
float lerUmidade()
{
TempAndHumidity dados = dht.getTempAndHumidity();
if (!(isnan(dados.humidity))){
return dados.humidity;
}else{
return -99.99;
}
}
/********************************************************************/
/* Inicializa e conecta-se na rede WI-FI desejada */
void iniciaWiFi()
{
delay(10);
Serial.println("------Conexao WI-FI------");
Serial.print("Conectando-se na rede: ");
Serial.println(SSID);
Serial.println("Aguarde");
digitalWrite(pinoLedWifi, LOW);
reconectaWiFi();
}
/********************************************************************/
void reconectaWiFi(void)
{
// se já está conectado a rede WI-FI, nada é feito.
// Caso contrário, são efetuadas tentativas de conexão
if (WiFi.status() == WL_CONNECTED){
digitalWrite(pinoLedWifi, HIGH); // Ligar o LED
return;
}
WiFi.begin(SSID, PASSWORD, CHANNEL); // Conecta na rede WI-FI
while (WiFi.status() != WL_CONNECTED) {
digitalWrite(pinoLedWifi, LOW); // Ligar o LED
delay(100);
Serial.print(".");
}
digitalWrite(pinoLedWifi, HIGH); // Ligar o LED
Serial.println();
Serial.print("Conectado com sucesso na rede ");
Serial.print(SSID);
Serial.println("IP obtido: ");
Serial.println(WiFi.localIP());
}
/********************************************************************/
/* Inicializa os parâmetros de conexão MQTT(endereço do broker, porta e seta
função de callback) */
void iniciaMQTT(void)
{
MQTT.setServer(BROKER_MQTT, BROKER_PORT); // Informa qual broker e porta
// deve ser conectado
MQTT.setCallback(callbackMQTT); // Atribui função de callback
//(função chamada quando qualquer informação de um dos tópicos subescritos chega)
}
/********************************************************************/
/* Função de callback esta função é chamada toda vez que uma informação
de um dos tópicos subescritos chega */
void callbackMQTT(char *topic, byte *payload, unsigned int length)
{
String msg;
// Obtem a string do payload recebido
for (int i = 0; i < length; i++) {
char c = (char)payload[i];
msg += c;
}
Serial.printf("Chegou a seguinte string via MQTT: %s do topico: %s\n", msg, topic);
if(String(topic) == TOPIC_SUBSCRIBE_LED){
Serial.println(String(msg));
alternaLampada();
}
if(String(topic) == TOPIC_SUBSCRIBE_MOTOR){
Serial.println(String(msg));
alternaMotor();
}
}
/********************************************************************/
/* Reconecta-se ao broker MQTT (caso ainda não esteja conectado ou em caso de a conexão cair)
em caso de sucesso na conexão ou reconexão, o subscribe dos tópicos é refeito. */
void reconectaMQTT(void)
{
while (!MQTT.connected()) {
Serial.print("* Tentando se conectar ao Broker MQTT: ");
Serial.println(BROKER_MQTT);
if (MQTT.connect(ID_MQTT)) {
statusConexao = 1;
Serial.println("Conectado com sucesso ao broker MQTT!");
MQTT.subscribe(TOPIC_SUBSCRIBE_LED);
MQTT.subscribe(TOPIC_SUBSCRIBE_MOTOR);
} else {
statusConexao = 0;
Serial.println("Falha ao reconectar no broker.");
Serial.println("Nova tentativa de conexao em 2 segundos.");
delay(2000);
}
}
}
/********************************************************************/
/* Verifica o estado das conexões WiFI e ao broker MQTT.
Em caso de desconexão (qualquer uma das duas), a conexão é refeita. */
void checkWiFIeMQTT(void)
{
if (!MQTT.connected())
reconectaMQTT(); // se não há conexão com o Broker, a conexão é refeita
reconectaWiFi(); // se não há conexão com o WiFI, a conexão é refeita
}
/********************************************************************/