#define ledA 26
#define ledV 25
#include "WiFi.h"
#include <PubSubClient.h>
//Biblioteca necessária para fazer a conexão com o ubidots. Porém o wokwi não está aceitando o uso dessa biblioteca
//Em uma ambiente arduino ide com a biblioteca enviada de forma zip, o código fará o envio dos dados para o ubidots
// Todas as funções e objetos comentados são devidos a esse erro que ocorre
//#include "UbidotsEsp32Mqtt.h"
// Definições de rede para poder acessar o wifi do wokwi e um broker mqtt
#define ssid "Wokwi-GUEST"
#define password ""
#define clientId "Rodrigo" //Idealmente coloca algo que ninguém vai repetir, pois se usar o mesmo client-id desconecta
// Constantes para a definição das portas que serão utilizadas pelo esp32
//Portas dos itens
const int ldrPin = 34;
const int button = 27;
const int pinoRele = 16;
// Intervalo entre leituras realizadas pelo esp
const int tempoLeitura = 1000;
// Variável de controle se está de noite (Ou seja, qual led deve acender)
bool isNight = false;
long ldrValue; // Variáevl para a leitura do relé
unsigned long tempoAtual; // Variável para armazenar o tempo já percorrido
// Eu preferi usar o hivemq pq ele é consideravelmente mais estável q o ubidots
const char *mqttBroker = "broker.hivemq.com";
// Objetos da classe de Wifi, que permitiram interagir com o broker
WiFiClient wiFiClient;
PubSubClient mqttClient(wiFiClient);
// Verifica se o Wifi foi conectado e fica tentando reconectar caso não tenha dado certo até 30000 milisegundos
bool conectarWiFi()
{
const unsigned long tempoInicial = millis();
WiFi.begin(ssid, password);
do
{
if (WiFi.status() == WL_CONNECTED)
{
Serial.println("Conexao Wi-Fi estabelecida!");
return true;
}
delay(1000);
} while ((millis() - tempoInicial) < 30000L);
Serial.println("Erro na conexão WIFI");
return false;
}
// Bool que verifica se o wifi tá conectado
bool verificarWiFi()
{
if (WiFi.status() == WL_CONNECTED)
return true;
Serial.println("Conexao Wi-Fi perdida.");
WiFi.disconnect(true);
delay(5000);
return conectarWiFi();
}
// Assim como o conecta wifi, esse código tenta conectar no broker mqtt fornecido
bool conectarMQTT()
{
Serial.println("Tentando estabelecer uma conexao com o broker MQTT...");
const unsigned long tempoInicial = millis();
// const char clientId = "Rodrigo";
do
{
if (mqttClient.connect(clientId))
{
Serial.print("Conectado ao broker MQTT utilizando o client id ");
Serial.print(clientId);
return true;
}
delay(1000);
if (!verificarWiFi())
break;
} while ((millis() - tempoInicial) < 30000L);
Serial.println("Não foi possivel estabelecer a conexão com MQTT");
return false;
}
bool verificarMQTT()
{
if (!verificarWiFi())
return false;
if (mqttClient.connected())
return true;
Serial.println("Conexao com o broker perdida.");
mqttClient.disconnect();
delay(5000);
return conectarMQTT();
}
// Classe leds para manipular os leds existentes no projeto
class Leds{
public:
int output_port;
//Construtor da classe
Leds(int porta){
output_port = porta;
Serial.println(porta);
pinMode(output_port , OUTPUT);
};
//Void para ligar o led Azul
void piscaLed(){
digitalWrite(output_port, HIGH);
delay(500);
digitalWrite(output_port, LOW);
delay(500);
};
//Void para ligar o led vermelho
void changeState(bool state){
digitalWrite(output_port, state ? HIGH : LOW);
}
private:
};
// Instâncias das classes de led de forma global, para que possam ser usadas em quaisquer funções
Leds ledAzul = Leds(ledA);
Leds ledVermelho = Leds(ledV);
void setup() {
// Inicialização do Wifi e do mqtt
WiFi.mode(WIFI_STA);
conectarWiFi();
mqttClient.setBufferSize(256);
mqttClient.setKeepAlive(60);
mqttClient.setSocketTimeout(15);
mqttClient.setServer(mqttBroker, 1883);
Serial.begin(115200); //Inicializa o monitor serial
pinMode(button, INPUT_PULLDOWN); // Define o botão como de pull down
pinMode(pinoRele, OUTPUT); //Define o pino do relé como output
}
void loop() {
//Inicializa e verifica se o mqtt está conectado
if (!verificarMQTT())
return;
mqttClient.loop();
//Verificação se o botão está pressionado
if(digitalRead(button) == HIGH){
//Caso esteja liga o relé e mostra uma mensagem no serial Monitor
digitalWrite(pinoRele, HIGH);
Serial.println("Botão Pressionado");
}
// Caso não esteja pressionado o botão
else{
//Desliga o relé e manda uma mensagem no serial
Serial.println("Botão não está pressionado");
digitalWrite(pinoRele, LOW);
}
// Verifica se o tempo que o código está rodando é superior ao tempo em que a leitura deve ser realizada
if((millis()- tempoAtual) >= tempoLeitura){
tempoAtual = millis();
verificaLDR();
}
// Caso a leitura seja maior do que 2031, led azul é ligado, caso contrário, led Vermelho é ligado.
if(isNight){
ledAzul.piscaLed();
}
delay(100);
}
void verificaLDR(){
// reads the input on analog pin (value between 0 and 4095)
int analogValue = analogRead(ldrPin);
// Define a mensagem a ser enviada
char payload[16];
Serial.print("Analog Value = ");
// Coloca no array do payload os valores a serem enviados
sprintf(payload, "%.2f", analogValue);
Serial.println(analogValue); // the raw analog reading
// Publica no topico Luminosidade/Prova
//Preferencialmente usar seu nome no lugar de prova, para evitar confundir com alguém!!
if (mqttClient.publish("Luminosidade/Prova", payload))
{
Serial.println("Dados de luminosidade enviados!");
}
// De acordo com a docs do wokwi, o módulo ldr varia entre 0.1 e 100000lux
// Porem, a leitura do nosso sensor é feita em volts e após isso, mapeada entre 0 a 4095.
// Dessa forma, a metade desse valor é 2048
// * Correção: Apesar de normalmente a variação corereta ser essa, o software varia entre 4063 e 32, sendo assim 50% = 2032
if(analogValue >= 2032){
// Apaga o led vermelho
ledVermelho.changeState(false);
isNight = true;
mqttClient.publish("LedA/Prova", "LED A está piscando");
}
else{
// Acende o led vermelho
ledVermelho.changeState(true);
mqttClient.publish("LedB/Prova", "LED B está aceso");
isNight = false;
}
}