#include <ESP32Servo.h>
#include "AlarmTone.h"
#include <WiFi.h>
#include <PubSubClient.h> // Inclua a biblioteca MQT
#define ID_MQTT "esp32_mqtt" // id mqtt (para identificação de sessão)
//conexao com o broker
const char* BROKER_MQTT = "broker.hivemq.com";
int BROKER_PORT = 1883;
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
WiFiClient espClient;
PubSubClient MQTT(espClient);
void initWiFi(void);
void initMQTT(void);
void callbackMQTT(char *topic, byte *payload, unsigned int length);
void reconnectMQTT(void);
void reconnectWiFi(void);
void checkWiFIAndMQTT(void);
int ledPin = 2;
int inputPin = 13;
int pirState = LOW;
int val = 0;
int pos = 0;
bool servoOpen = false;
const char *SENSOR_TOPIC = "sensorConf/";
const char *LUZ_TOPIC = "luzAcessa/";
unsigned long previousMillis = 0;
const long interval = 5; // Intervalo para atualização do servo e do buzzer em milissegundos
const int servoPin = 12;
const int SPEAKER_PIN = 18;
Servo servo;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(inputPin, INPUT);
Serial.begin(9600);
servo.attach(servoPin, 500, 2400);
servo.write(0);
// Inicializa a conexao Wi-Fi
initWiFi();
// Inicializa a conexao ao broker MQTT
initMQTT();
MQTT.subscribe(SENSOR_TOPIC);
MQTT.subscribe(LUZ_TOPIC);
}
void playBuzzerPattern(int frequency, int duration, int repetitions) {
for (int i = 0; i < repetitions; i++) {
tone(SPEAKER_PIN, frequency, duration);
delay(duration);
noTone(SPEAKER_PIN);
delay(50); // Pequeno atraso entre os padrões de toque
}
}
void loop() {
val = digitalRead(inputPin);
if (val == HIGH) {
// Verifica o funcionamento das conexões WiFi e ao broker MQTT
checkWiFIAndMQTT();
digitalWrite(ledPin, HIGH);
if (pirState == LOW) {
pirState = HIGH;
Serial.println("Motion detected!");
delay(2000);
for (pos = 0; pos <= 180; pos += 1) {
servo.write(pos);
delay(15);
}
digitalWrite(ledPin, LOW);
MQTT.publish("sensorConf/", "open");
MQTT.publish("luzAcessa/", "true");
// Tocar padrão de toque 1 cinco vezes
//playBuzzerPattern(1000, 300, 5);
}
}
if (servoOpen) {
checkWiFIAndMQTT(); // Check WiFi and MQTT connections
// Check for incoming MQTT messages to close the servo
MQTT.loop();
// Check if a command to close the servo has been received
if (!servoOpen) {
for (pos = 180; pos >= 0; pos -= 1) {
servo.write(pos);
delay(5);
playBuzzerPattern(2000, 200, 1);
}
}
}
}
void initMQTT(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)
}
/* Inicializa e conecta-se na rede WI-FI desejada */
void initWiFi(void)
{
delay(10);
Serial.println("------Conexao WI-FI------");
Serial.print("Conectando-se na rede: ");
Serial.println(SSID);
Serial.println("Aguarde");
reconnectWiFi();
}
/* 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 reconnectMQTT(void)
{
while (!MQTT.connected()) {
Serial.print("* Tentando se conectar ao Broker MQTT: ");
Serial.println(BROKER_MQTT);
if (MQTT.connect(ID_MQTT)) {
Serial.println("Conectado com sucesso ao broker MQTT!");
} else {
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 checkWiFIAndMQTT(void)
{
if (!MQTT.connected())
reconnectMQTT(); // se não há conexão com o Broker, a conexão é refeita
reconnectWiFi(); // se não há conexão com o WiFI, a conexão é refeita
}
void reconnectWiFi(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)
return;
WiFi.begin(SSID, PASSWORD); // Conecta na rede WI-FI
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println();
Serial.print("Conectado com sucesso na rede ");
Serial.print(SSID);
Serial.println("IP obtido: ");
Serial.println(WiFi.localIP());
}
/* 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) {
Serial.println("MSG CLIENT!");
String topicStr = String(topic);
// Verifica se o tópico recebido é o tópico do sensor
if (topicStr.equals(SENSOR_TOPIC)) {
String msg = "";
for (int i = 0; i < length; i++) {
char c = (char)payload[i];
msg += c;
}
if (msg.equals("closed")) {
if (servoOpen) {
Serial.println("Fechando o servo...");
for (pos = 180; pos >= 0; pos -= 1) {
servo.write(pos);
delay(5);
playBuzzerPattern(2000, 200, 1);
}
Serial.println("Servo ativado.");
// Publica a informação de que o servo foi fechado
MQTT.publish("sensorConf/", "sensorClosed");
servoOpen = false; // Set the servo state to closed
}
}
}
}