#include <Servo.h>
// ==========================================
// MAPEAMENTO DE PINOS (Conforme Circuito)
// ==========================================
const int LED_VERDE = 13;
const int LED_VERMELHO = 12;
const int PIN_TRIG = A2;
const int PIN_ECHO = A1;
const int JOY_X = A0;
const int JOY_Y = A3;
const int PIN_SERVO = 11;
Servo portaoServo;
const int SEG_A = 10;
const int SEG_B = 9;
const int SEG_C = 8;
const int SEG_D = 7;
const int SEG_E = 6;
const int SEG_F = 5;
const int SEG_G = 4;
// ==========================================
// CONFIGURAÇÕES E VARIÁVEIS
// ==========================================
enum Direcao { NEUTRO, DIREITA, ESQUERDA, CIMA, BAIXO };
const Direcao SENHA_CORRETA[5] = { DIREITA, DIREITA, BAIXO, CIMA, DIREITA };
Direcao senhaInserida[5];
int passoSenha = 0;
enum EstadoSistema { ESPERA, AUTENTICACAO, ACESSO_PERMITIDO, ACESSO_NEGADO };
EstadoSistema estadoAtual = ESPERA;
const int DISTANCIA_DETECCAO = 50;
const byte NUMEROS[7] = {
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101 // 6
};
// Protótipos das funções
void desligarDisplay();
void processarEspera();
void processarAutenticacao();
void processarAcessoPermitido();
void processarAcessoNegado();
long lerDistancia();
Direcao lerJoystick();
void mostrarNumero(int num);
const char* direcaoParaTexto(Direcao d);
// ==========================================
// SETUP & LOOP
// ==========================================
void setup() {
Serial.begin(9600);
Serial.println("--- Sistema Iniciado ---");
pinMode(LED_VERDE, OUTPUT);
pinMode(LED_VERMELHO, OUTPUT);
pinMode(PIN_TRIG, OUTPUT);
pinMode(PIN_ECHO, INPUT);
portaoServo.attach(PIN_SERVO);
portaoServo.write(0);
for (int i = 4; i <= 10; i++) {
pinMode(i, OUTPUT);
}
desligarDisplay();
}
void loop() {
switch (estadoAtual) {
case ESPERA:
processarEspera();
break;
case AUTENTICACAO:
processarAutenticacao();
break;
case ACESSO_PERMITIDO:
processarAcessoPermitido();
break;
case ACESSO_NEGADO:
processarAcessoNegado();
break;
}
delay(50);
}
// ==========================================
// FUNÇÕES DE ESTADO
// ==========================================
void processarEspera() {
digitalWrite(LED_VERDE, LOW);
digitalWrite(LED_VERMELHO, LOW);
desligarDisplay();
portaoServo.write(0);
passoSenha = 0;
long distancia = lerDistancia();
if (distancia > 0 && distancia < DISTANCIA_DETECCAO) {
estadoAtual = AUTENTICACAO;
Serial.println("Presenca detectada! Insira a senha pelo Joystick...");
digitalWrite(LED_VERMELHO, HIGH);
delay(200);
digitalWrite(LED_VERMELHO, LOW);
}
}
void processarAutenticacao() {
Direcao movimento = lerJoystick();
if (movimento != NEUTRO) {
senhaInserida[passoSenha] = movimento;
passoSenha++;
Serial.print("Movimento ");
Serial.print(passoSenha);
Serial.print("/5 detectado: ");
Serial.println(direcaoParaTexto(movimento));
mostrarNumero(passoSenha);
// Espera você soltar o joystick antes de continuar
unsigned long tempoSeguranca = millis();
while (lerJoystick() != NEUTRO) {
delay(10);
if (millis() - tempoSeguranca > 1200) {
break;
}
}
delay(300); // Evita cliques duplos fantasiados
// CORREÇÃO AQUI: Se chegou a 5 movimentos, valida NA HORA!
if (passoSenha >= 5) {
bool senhaValida = true;
for (int i = 0; i < 5; i++) {
if (senhaInserida[i] != SENHA_CORRETA[i]) {
senhaValida = false;
break;
}
}
if (senhaValida) {
estadoAtual = ACESSO_PERMITIDO;
processarAcessoPermitido(); // Executa o LED Verde e abre o motor direto
} else {
estadoAtual = ACESSO_NEGADO;
processarAcessoNegado(); // Executa o LED Vermelho piscando direto
}
return;
}
}
}
void processarAcessoPermitido() {
Serial.println("ACESSO PERMITIDO! Abrindo portao...");
digitalWrite(LED_VERDE, HIGH);
digitalWrite(LED_VERMELHO, LOW);
portaoServo.write(90); // Gira o servo para abrir o portão
delay(500);
// Contagem Regressiva de 6 segundos no display
for (int i = 6; i >= 0; i--) {
mostrarNumero(i);
delay(1000);
}
Serial.println("Fechando portao e resetando.");
estadoAtual = ESPERA;
}
void processarAcessoNegado() {
Serial.println("ACESSO NEGADO! Senha incorreta.");
digitalWrite(LED_VERDE, LOW);
// Pisca o LED Vermelho 3 vezes indicando o erro
for (int i = 0; i < 3; i++) {
digitalWrite(LED_VERMELHO, HIGH);
delay(400);
digitalWrite(LED_VERMELHO, LOW);
delay(400);
}
estadoAtual = ESPERA;
}
// ==========================================
// FUNÇÕES AUXILIARES
// ==========================================
long lerDistancia() {
digitalWrite(PIN_TRIG, LOW);
delayMicroseconds(2);
digitalWrite(PIN_TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(PIN_TRIG, LOW);
long duracao = pulseIn(PIN_ECHO, HIGH, 30000);
long distanciaCm = duracao * 0.034 / 2;
return distanciaCm;
}
Direcao lerJoystick() {
int x = analogRead(JOY_X);
int y = analogRead(JOY_Y);
// Faixa de leitura ajustada para evitar falsos comandos no Wokwi
if (x > 920) return ESQUERDA;
if (x < 100) return DIREITA;
if (y > 920) return CIMA;
if (y < 100) return BAIXO;
return NEUTRO;
}
const char* direcaoParaTexto(Direcao d) {
switch(d) {
case DIREITA: return "DIREITA";
case ESQUERDA: return "ESQUERDA";
case CIMA: return "CIMA";
case BAIXO: return "BAIXO";
default: return "NEUTRO";
}
}
void mostrarNumero(int num) {
if (num < 0 || num > 6) return;
byte padrao = NUMEROS[num];
digitalWrite(SEG_A, (padrao & 0b00000001) ? HIGH : LOW);
digitalWrite(SEG_B, (padrao & 0b00000010) ? HIGH : LOW);
digitalWrite(SEG_C, (padrao & 0b00000100) ? HIGH : LOW);
digitalWrite(SEG_D, (padrao & 0b00001000) ? HIGH : LOW);
digitalWrite(SEG_E, (padrao & 0b00010000) ? HIGH : LOW);
digitalWrite(SEG_F, (padrao & 0b00100000) ? HIGH : LOW);
digitalWrite(SEG_G, (padrao & 0b01000000) ? HIGH : LOW);
}
void desligarDisplay() {
for (int i = 4; i <= 10; i++) {
digitalWrite(i, LOW);
}
}