#include <ESP32Servo.h> // Biblioteca para controlar servos motores
#include <Wire.h> // Biblioteca para comunicação I2C
#include <LiquidCrystal_I2C.h> // Biblioteca para o display LCD via I2C
#include <DHT.h> // Biblioteca para o sensor DHT22
#include <WiFi.h> // Biblioteca para comunicação Wi-Fi
#include <PubSubClient.h> // Biblioteca para cliente MQTT
#include <ArduinoJson.h> // Biblioteca para manipulação de JSON
// Definição de pinos para os componentes
#define TRIG_PIN 33 // Pino para o trigger do sensor ultrassônico
#define ECHO_PIN 32 // Pino para o echo do sensor ultrassônico
#define SERVO_PIN_1 5 // Pino para o servo motor 1
#define SERVO_PIN_2 17 // Pino para o servo motor 2
#define BUZZER_PIN 14 // Pino para o buzzer
#define DIST_THRESHOLD 10 // Limiar de distância em centímetros
#define LCD_ADDR 0x27 // Endereço I2C do display LCD
#define LCD_COLS 16 // Número de colunas no LCD
#define LCD_ROWS 2 // Número de linhas no LCD
#define WIFI_SSID "Wokwi-GUEST" // SSID da rede Wi-Fi
#define WIFI_PASSWORD "" // Senha da rede Wi-Fi
#define MQTT_SERVER "mqtt-dashboard.com" // Servidor MQTT
#define MQTT_PORT 1883 // Porta do servidor MQTT
#define TEMP_TOPIC "esp32/" // Tópico MQTT para temperatura
#define DIST_TOPIC "esp32/" // Tópico MQTT para distância
#define SERVO_CTRL_TOPIC "esp32/servoControl" // Novo tópico MQTT para controle de servos
Servo servo1; // Objeto do servo motor 1
Servo servo2; // Objeto do servo motor 2
LiquidCrystal_I2C lcd(LCD_ADDR, LCD_COLS, LCD_ROWS); // Objeto do display LCD
DHT dht(25, DHT22); // Objeto do sensor DHT22
WiFiClient espClient; // Objeto do cliente Wi-Fi
PubSubClient client(espClient); // Objeto do cliente MQTT
void setup() {
Serial.begin(115200); // Inicialização da comunicação serial
Wire.begin(23, 22); // Inicialização do barramento I2C
lcd.init(); // Inicialização do display LCD
lcd.backlight(); // Liga a luz de fundo do LCD
lcd.setCursor(0, 0); // Define a posição do cursor no LCD
lcd.print("Distance:"); // Imprime o texto no LCD
lcd.setCursor(0, 1); // Define a posição do cursor no LCD
lcd.print("Temp:"); // Imprime o texto no LCD
// Configuração dos pinos
pinMode(TRIG_PIN, OUTPUT); // Define o pino TRIG_PIN como saída
pinMode(ECHO_PIN, INPUT); // Define o pino ECHO_PIN como entrada
pinMode(BUZZER_PIN, OUTPUT); // Define o pino BUZZER_PIN como saída
servo1.attach(SERVO_PIN_1); // Anexa o servo motor 1 ao pino correspondente
servo2.attach(SERVO_PIN_2); // Anexa o servo motor 2 ao pino correspondente
servo1.write(0); // Define a posição inicial do servo motor 1
servo2.write(0); // Define a posição inicial do servo motor 2
setup_wifi(); // Configura a conexão Wi-Fi
client.setServer(MQTT_SERVER, MQTT_PORT); // Configura o servidor MQTT
client.setCallback(callback); // Define a função de callback para mensagens MQTT
}
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Conectando-se a ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD); // Conecta-se à rede Wi-Fi
while (WiFi.status() != WL_CONNECTED) { // Aguarda até a conexão ser estabelecida
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi conectado");
Serial.println("Endereço IP: ");
Serial.println(WiFi.localIP());
}
void reconnect() {
while (!client.connected()) {
Serial.print("Tentando se reconectar ao MQTT Broker...");
if (client.connect("949494949449494949494HHHHH")) { // Tenta conectar-se ao servidor MQTT
Serial.println("Conectado ao MQTT Broker");
client.subscribe(SERVO_CTRL_TOPIC); // Inscreve-se no tópico de controle de servos
client.subscribe(DIST_TOPIC); // Inscreve-se no tópico de distância
} else {
Serial.print("Falha na conexão, rc=");
Serial.print(client.state());
Serial.println(" Tentando novamente em 5 segundos");
delay(5000);
}
}
}
void callback(char* topic, byte* payload, unsigned int length) {
String message;
for (unsigned int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.print("Mensagem recebida [");
Serial.print(topic);
Serial.print("]: ");
Serial.println(message);
if (String(topic) == SERVO_CTRL_TOPIC) {
DynamicJsonDocument doc(1024);
deserializeJson(doc, message);
float distance_cm = doc["distance"];
if (distance_cm < DIST_THRESHOLD) {
servo1.write(180); // Move o servo 1 para 180 graus
servo2.write(180); // Move o servo 2 para 180 graus
delay(10000); // Aguarda 10 segundos
servo1.write(0); // Retorna o servo 1 para 0 graus
servo2.write(0); // Retorna o servo 2 para 0 graus
}
}
if (String(topic) == DIST_TOPIC) {
DynamicJsonDocument doc(1024);
deserializeJson(doc, message);
float distance_cm = doc["distance"];
if (distance_cm < DIST_THRESHOLD) {
servo1.write(180); // Move o servo 1 para 180 graus
servo2.write(180); // Move o servo 2 para 180 graus
} else {
servo1.write(0); // Retorna o servo 1 para 0 graus
servo2.write(0); // Retorna o servo 2 para 0 graus
}
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
// Leitura da distância usando o sensor ultrassônico
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration_us = pulseIn(ECHO_PIN, HIGH);
float distance_cm = (duration_us * 0.0343) / 2;
// Leitura da temperatura usando o sensor DHT22
float temperature = dht.readTemperature();
// Exibição da distância e temperatura no LCD
lcd.setCursor(10, 0);
lcd.print(" "); // Limpa leitura anterior
lcd.setCursor(10, 0);
lcd.print(distance_cm); // Exibe distância no LCD
lcd.setCursor(13, 1);
lcd.print(" "); // Limpa leitura anterior
lcd.setCursor(10, 1);
lcd.print(temperature, 1); // Exibe temperatura no LCD com uma casa decimal
// Publica os valores de distância e temperatura nos tópicos MQTT
if (client.connected()) {
// Cria o documento JSON para a distância
DynamicJsonDocument distDoc(1024);
distDoc["sensor"] = "esp32/distance";
distDoc["valor"] = distance_cm;
String distMessage;
serializeJson(distDoc, distMessage);
client.publish(DIST_TOPIC, distMessage.c_str());
// Cria o documento JSON para a temperatura
DynamicJsonDocument tempDoc(1024);
tempDoc["sensor"] = "esp32/temperature";
tempDoc["valor"] = temperature;
String tempMessage;
serializeJson(tempDoc, tempMessage);
client.publish(TEMP_TOPIC, tempMessage.c_str());
Serial.println("Dados publicados nos tópicos MQTT");
}
// Controle do buzzer baseado na distância
if (distance_cm < DIST_THRESHOLD) {
digitalWrite(BUZZER_PIN, HIGH); // Liga o buzzer quando a distância for menor que o limite
} else {
digitalWrite(BUZZER_PIN, LOW); // Desliga o buzzer
}
delay(2000); // Aguarda um intervalo antes da próxima leitura
}