#include <ESP32Servo.h>
#include <DHT.h>
#include <LiquidCrystal_I2C.h>
#include <WiFi.h>
#include <WiFiClientSecure.h> //Biblioteca para conexão segura
#include <PubSubClient.h> //para conexão com o Broker
#include <HTTPClient.h>;
#include <ArduinoJson.h>;
String nome_wifi = "Wokwi-GUEST";
String senha = "";
// String nome_wifi = "WIFI_DEV_CONVIDADO";
// String senha = "aula0411";
//Criando objeto para conectar com o Broker, com conexão segura
WiFiClientSecure espClient;
PubSubClient MQTT(espClient);
char* broker = "ef221ffa9a1c45ba9f94570aae0aeb9e.s1.eu.hivemq.cloud";
int ledVerde1 = 13;
int ledAmarelo1 = 12;
int ledVermelho1 = 14;
int ledVermPed = 27;
int ledVerdPed = 26;
int ledVerde2 = 25;
int ledAmarelo2 = 33;
int ledVermelho2 = 32;
int ledLDR = 2;
int pinoLDR = 35;
int pinoTrig = 18;
int pinoEcho = 19;
int pinoServo = 5;
Servo meuServo;
int pinoDHT = 4;
DHT sensorDHT(pinoDHT, DHT22);
LiquidCrystal_I2C lcd(0x27, 16, 2);
//variáveis globais
int tempo_vermelho = 5000;
int tempo_verde = 4000;
bool amarelo_piscante = false;
bool iluminacao_publica = false;
void setup() {
pinMode(ledVerde1, OUTPUT);
pinMode(ledAmarelo1, OUTPUT);
pinMode(ledVermelho1, OUTPUT);
pinMode(ledVerde2, OUTPUT);
pinMode(ledAmarelo2, OUTPUT);
pinMode(ledVermelho2, OUTPUT);
pinMode(ledVermPed, OUTPUT);
pinMode(ledVerdPed, OUTPUT);
pinMode(ledLDR, OUTPUT);
pinMode(pinoLDR, INPUT);
pinMode(pinoTrig, OUTPUT);
pinMode(pinoEcho, INPUT);
meuServo.attach(pinoServo);
sensorDHT.begin();
lcd.init();
lcd.backlight();
Serial.begin(9600);
espClient.setInsecure();
MQTT.setServer(broker, 8883);
// Criando a tarefa do Semáforo
xTaskCreate(
TarefaSemaforo, // Função da Tarefa
"Semaforo", // Nome da Tarefa (para debug)
10000, // Tamanho da Pilha (stack size) em palavras
NULL, // Parâmetro da Tarefa
1, // Prioridade da Tarefa (0 é a mais baixa)
NULL // Handle da Tarefa (opcional)
);
// Criando a tarefa do LDR e LED
xTaskCreate(
TarefaLDRLed, // Função da Tarefa
"LDR_LED", // Nome da Tarefa
10000, // Tamanho da Pilha
NULL, // Parâmetro
1, // Prioridade
NULL // Handle
);
// Criando a tarefa do sensor
xTaskCreate(
TarefaCancela, // Função da Tarefa
"Cancela", // Nome da Tarefa
10000, // Tamanho da Pilha
NULL, // Parâmetro
1, // Prioridade
NULL // Handle
);
// Criando a tarefa da temperatura
xTaskCreate(
TarefaTemperatura,// Função da Tarefa
"Temperatura", // Nome da Tarefa
10000, // Tamanho da Pilha
NULL, // Parâmetro
1, // Prioridade
NULL // Handle
);
//Cria a tarefa que verifica os dados do WS
xTaskCreate(
BuscarDadosWS, // Função que implementa a tarefa
"TaskLoopWS", // Nome da tarefa
10000, // Tamanho da pilha em bytes
NULL, // Parâmetro para a função
1, // Prioridade da tarefa
NULL // Handle da tarefa
);
Serial.println("Tarefas criadas");
}
void loop() {
vTaskDelay(pdMS_TO_TICKS(1000));
}
// Implementação da Tarefa do Semáforo
void TarefaSemaforo(void *parametros) {
Serial.println("Tarefa Semáforo iniciada");
while (true) { // Loop infinito da tarefa
if (amarelo_piscante == true) {
digitalWrite(ledAmarelo1, HIGH);
digitalWrite(ledAmarelo2, HIGH);
vTaskDelay(pdMS_TO_TICKS(1000));
digitalWrite(ledAmarelo1, LOW);
digitalWrite(ledAmarelo2, LOW);
vTaskDelay(pdMS_TO_TICKS(1000));
} else {
digitalWrite(ledVerde1, HIGH);
digitalWrite(ledAmarelo1, LOW);
digitalWrite(ledVermelho1, LOW);
digitalWrite(ledVerde2, LOW);
digitalWrite(ledAmarelo2, LOW);
digitalWrite(ledVermelho2, HIGH);
digitalWrite(ledVermPed, HIGH);
digitalWrite(ledVerdPed, LOW);
vTaskDelay(pdMS_TO_TICKS(tempo_vermelho));
digitalWrite(ledVerde1, LOW);
digitalWrite(ledAmarelo1, HIGH);
vTaskDelay(pdMS_TO_TICKS(2000));
digitalWrite(ledVermPed, LOW);
digitalWrite(ledVerdPed, HIGH);
digitalWrite(ledAmarelo1, LOW);
digitalWrite(ledVermelho1, HIGH);
digitalWrite(ledVerde2, HIGH);
digitalWrite(ledVermelho2, LOW);
vTaskDelay(pdMS_TO_TICKS(tempo_verde));
digitalWrite(ledVerde2, LOW);
digitalWrite(ledAmarelo2, HIGH);
vTaskDelay(pdMS_TO_TICKS(2000));
}
}
}
// Implementação da Tarefa do LDR e LED
void TarefaLDRLed(void *parametros) {
Serial.println("Tarefa LDR/LED iniciada");
while (true) { // Loop infinito da tarefa
if (iluminacao_publica == true) {
digitalWrite(ledLDR, HIGH);
} else {
int valorLDR = analogRead(pinoLDR);
Serial.print("Valor LDR: ");
Serial.println(valorLDR);
if (valorLDR < 1500) {
digitalWrite(ledLDR, HIGH);
} else {
digitalWrite(ledLDR, LOW);
}
}
vTaskDelay(pdMS_TO_TICKS(2000)); // Verifica o LDR a cada 0.5 segundos
}
}
// Implementação da Tarefa da cancela
void TarefaCancela(void *parametros) {
Serial.println("Tarafa Cancela iniciada");
while (true) {
//antes de fazer uma nova leitura preciso garantir que o pino esteja desligado
digitalWrite(pinoTrig, LOW);
delayMicroseconds(2);
//disparando um pulso de 10 microsegundos para o sensor
digitalWrite(pinoTrig, HIGH);
delayMicroseconds(10);
digitalWrite(pinoTrig, LOW);
long duracao = pulseIn(pinoEcho, HIGH);
int distancia = (duracao * 0.0343) / 2;
Serial.println("Distância: " + String(distancia) + "cm");
if (distancia <= 40) {
meuServo.write(90); //move para a posição 0°
} else {
meuServo.write(0); //move para a posição 0°
}
vTaskDelay(pdMS_TO_TICKS(2000));
}
}
// Implementação da Tarefa da temperatura e umidade
void TarefaTemperatura(void *parametros) {
Serial.println("Tarefa Temperatura iniciada");
while (true) {
float temperatura = sensorDHT.readTemperature();
float umidade = sensorDHT.readHumidity();
Serial.println("Temp: " + String(temperatura) + "ºC / Umid.: " + String(umidade) + "%");
lcd.setCursor(0, 0);
lcd.print("Temp. " + String(temperatura) + "oC");
lcd.setCursor(0, 1);
lcd.print("Umid. " + String(umidade) + "%");
char tempStr[10]; //Variavel char para converter a temperatura
dtostrf(temperatura, 1, 2, tempStr); //Convertendo para char
MQTT.publish("semaforo/08/temperatura", tempStr);
char umidStr[10]; //Variavel char para converter a umidade
dtostrf(umidade, 1, 2, umidStr); //Convertendo para char
MQTT.publish("semaforo/08/umidade", umidStr);
vTaskDelay(pdMS_TO_TICKS(2000));
}
}
void ConectarMQTT() {
Serial.println("Conectando ao MQTT... ");
//Tentando conectar ao Broker
if (MQTT.connect("EspConexao", "douglascamata", "TesteMQTT123")) {
Serial.println("Conectado no MQTT");
} else {
Serial.println("Erro ao conectar");
}
}
void conectarWiFi() {
WiFi.begin(nome_wifi, senha);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.print("WiFi conectado..! IP obtido ");
Serial.println(WiFi.localIP());
}
//Loop para Buscar dados do WS
void BuscarDadosWS(void* parametros) {
conectarWiFi();
while (true) {
if (WiFi.status() == WL_CONNECTED) {
//Verificando se o servidor MQTT esta conectado
if (MQTT.connected() == false) ConectarMQTT();
MQTT.loop();
HTTPClient client;
client.begin("https://api-semaforo.vercel.app/obterDados");
int httpCode = client.GET();
if (httpCode > 0) {
String payload = client.getString();
// Processar o JSON recebido
StaticJsonDocument<200> doc;
DeserializationError error = deserializeJson(doc, payload);
if (!error) {
// Atualizar as variáveis de tempo com os valores recebidos
tempo_verde = doc["tempo_verde"];
tempo_verde = tempo_verde * 1000;
tempo_vermelho = doc["tempo_vermelho"];
tempo_vermelho = tempo_vermelho * 1000;
amarelo_piscante = doc["amarelo_piscante"];
iluminacao_publica = doc["iluminacao_publica"];
} else {
Serial.print("Erro ao analisar JSON: ");
Serial.println(error.c_str());
}
// Serial.println("Tempos VD " + String(tempo_verde) + " VM " + String(tempo_vermelho) + " Pisc. " + String(amarelo_piscante));
} else {
Serial.print("Erro ao conectar: ");
Serial.println(httpCode);
}
client.end();
} else {
Serial.println("Sem conexão");
}
vTaskDelay(pdMS_TO_TICKS(2000));
}
}