#include <ESP32Servo.h>
#include <WiFi.h>
#include <PubSubClient.h>
// Configurações Wifi e MQTT
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqttServer = "broker.mqttdashboard.com";
const int mqttPort = 1883;
WiFiClient espClient;
PubSubClient client(espClient);
// Tópicos MQTT
const char* topicTorreta = "sihs/torivus/1/torreta";
const char* topicStatus = "torreta/status";
const char* topicMovement = "sihs/torivus/1/pir";
const char* topicSound = "sihs/torivus/1/sound";
// Pinos
const int pinServo = 4; // Servo da torreta
const int pinTrigger = 17;
const int pinPir = 16; // Sensor PIR (movimento)
const int pinBuzzer = 25; // Buzzer
const int pinSound = 32; // Sensor de som
// Configurações do Servo
Servo torreta;
int posAtual = 0; // Posição atual do servo
int posAlvo = 0; // Posição alvo do servo
int vel = 5;
bool torretaAtiva = true;
// Configurações dos sensores
int soundLevel = 0; // Dados lidos pelo sensor de som
int pirState = LOW; // Estado do PIR
int soundState = LOW; // Estado do som
const int soundThreshold = 300; // Limiar para som anormal
bool alarmeAtivo = false;
bool buzzerAtivo = false;
bool sensorSomAtivo = false;
// Controle de tempo
unsigned long lastReconnect = 0;
const unsigned long reconnectInterval = 5000;
unsigned long lastPirCheck = 0;
unsigned long lastSoundCheck = 0;
unsigned long lastBuzzerToggle = 0;
unsigned long lastServoMove = 0;
unsigned long lastPrint = 0;
unsigned long lastShootTime = 0;
const unsigned long checkInterval = 1000; // Intervalo de checagem (2s)
const unsigned long buzzerInterval = 1000; // Intervalo do alarme sonoro (500ms)
const unsigned long servoInterval = 100; // Intervalo entre movimentos do servo (50ms)
const unsigned long serialPrintInterval = 1000; // Intervalo entre prints no Serial (1s)
const unsigned long shootInterval = 2000;
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived: ");
Serial.println(topic);
String msg = "";
for (int i = 0; i < length; i++) {
msg += ((char)payload[i]);
}
//Verifica conteudo
Serial.print("Comando: ");
Serial.println(msg);
if (String(topic) == topicTorreta) {
if (msg == "LIGAR_TORRETA") {
torretaAtiva = true;
} else if (msg == "DESLIGAR_TORRETA") {
torretaAtiva = false;
torreta.write(0);
} else if (msg == "LIGAR_ALARME") {
buzzerAtivo = true;
alarmeAtivo = true; // Certifica que o alarme fica ativo
} else if (msg == "DESLIGAR_ALARME") {
buzzerAtivo = false;
alarmeAtivo = false; // Desativa também o alarme
ledcWrite(pinBuzzer, 0); // Certifica que o buzzer para
} else if (msg == "LIGAR_SENSOR_SOM") {
sensorSomAtivo = true;
} else if (msg == "DESLIGAR_SENSOR_SOM") {
sensorSomAtivo = false;
}
}
}
void setup() {
Serial.begin(115200);
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
if (torreta.attach(pinServo)) { // Tenta anexar o servo ao pino configurado
Serial.println("Servo conectado com sucesso!");
// torreta.write(0); // Posição inicial do servo
} else {
Serial.println("Erro ao conectar o servo. Verifique o pino e a alimentação.");
}
// Inicializa WiFi
// reconnect();
// pinMode(pinPir, INPUT);
pinMode(pinSound, INPUT);
// pinMode(pinTrigger, OUTPUT);
// torreta.write(posAtual); // Inicia a torreta na posição inicial
Serial.println("Sistema Iniciado");
}
void reconnect() {
//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;
Serial.print("Tentando conexão Wifi...");
WiFi.begin(ssid, password); // Conecta na rede WI-FI
if (millis() - lastReconnect > reconnectInterval) {
lastReconnect = millis();
while (WiFi.status() != WL_CONNECTED)
{
delay(1000);
Serial.print(".");
}
Serial.print("Wifi conectado!");
delay(2000);
// Loop ate conectar mqtt
while (!client.connected()) {
Serial.print("Tentando conexao mqtt...");
if (client.connect("espVhtdm1")) {
Serial.println("Conectado ao MQTT.");
//Subscrevendo em um topico
client.subscribe(topicTorreta);
} else {
Serial.print("Falha, rc=");
Serial.print(client.state());
Serial.println(" Tentado novamente em 5s.");
delay(5000);
}
}
}
}
void loop() {
//Conecta MQTT
//Deixa MQTT no loop
unsigned long currentMillis = millis();
// Checa o sensor PIR
if (currentMillis - lastPirCheck >= checkInterval) {
lastPirCheck = currentMillis;
pirState = digitalRead(pinPir);
client.publish(topicMovement, pirState == HIGH ? "Movimento detectado" : "Sem movimento");
}
// Checa o sensor de som
if (currentMillis - lastSoundCheck >= checkInterval) {
lastSoundCheck = currentMillis;
soundLevel = analogRead(pinSound);
Serial.print("Nivel de som: ");
Serial.println(soundLevel);
soundState = (soundLevel > soundThreshold);
}
// Atualiza o estado do alarme
if (pirState == HIGH || soundState == HIGH) {
alarmeAtivo = true;
posAlvo = 90; // Torreta vai para posição de disparo
} else {
alarmeAtivo = false;
Serial.println("Retornando ao inicio");
posAlvo = 0; // Torreta retorna à posição inicial
}
// Gerencia o alarme sonoro, movimentação da torreta e disparo
gerenciarBuzzer(currentMillis);
if (torretaAtiva) {
moverTorreta(currentMillis);
if (alarmeAtivo && posAtual == posAlvo) {
dispararTorreta(currentMillis);
}
}
}
void verificarSensores() {
int pirState = digitalRead(pinPir);
int soundLevel = analogRead(pinSound);
if (pirState == HIGH || soundLevel > soundThreshold) {
alarmeAtivo = true;
} else {
alarmeAtivo = false;
}
}
void conectarWiFi() {
if (WiFi.status() != WL_CONNECTED) {
WiFi.begin(ssid, password);
}
// Aguarda a conexão sem bloquear o código
unsigned long startMillis = millis();
while (WiFi.status() != WL_CONNECTED) {
if (millis() - startMillis >= 10000) { // Timeout de 10 segundos
Serial.println("Falha ao conectar no Wi-Fi!");
return;
}
delay(1000); // Tenta a conexão a cada segundo
Serial.print(".");
}
Serial.println("\nConectado ao Wifi!");
}
// Função para gerenciar o som intermitente do buzzer
void gerenciarBuzzer(unsigned long currentMillis) {
static bool buzzerLigado = false;
if (alarmeAtivo && buzzerAtivo) {
if (currentMillis - lastBuzzerToggle >= buzzerInterval) {
lastBuzzerToggle = currentMillis;
buzzerLigado = !buzzerLigado;
ledcWrite(pinBuzzer, buzzerLigado ? 128 : 0); // Liga ou desliga o buzzer
}
} else {
ledcWrite(pinBuzzer, 0); // Silêncio absoluto se alarme não está ativo
}
}
// Função para mover a torreta suavemente
void moverTorreta(unsigned long currentMillis) {
if (currentMillis - lastServoMove >= servoInterval) {
lastServoMove = currentMillis;
// Movimento mais suave e preciso
if (posAtual < posAlvo) {
posAtual += vel;
} else if (posAtual > posAlvo) {
posAtual -= vel;
}
torreta.write(posAtual); // Atualiza a posição do servo
}
}
// Função para gerenciar o disparo da torreta
void dispararTorreta(unsigned long currentMillis) {
if (currentMillis - lastShootTime >= shootInterval) {
lastShootTime = currentMillis;
Serial.println("Disparo realizado!");
digitalWrite(pinTrigger, HIGH);
delay(1000); // Simula disparo curto
digitalWrite(pinTrigger, LOW);
}
}