#include <Wire.h>
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
// --- PINES ---
#define SERVO_PIN 13
#define LED_VERDE 26
#define LED_ROJO 25
#define BUZZER_PIN 33
#define IR_ENTRADA 34
#define IR_SALIDA 35
// --- OBJETOS ---
LiquidCrystal_I2C lcd(0x27, 16, 2);
Servo puerta;
// --- VARIABLES ---
int totalEntradas = 0;
int personasAdentro = 0;
int intentosFallidos = 0;
String correctPIN = "2208";
String enteredPIN = "";
// --- TECLADO ---
const byte ROW_NUM = 4;
const byte COL_NUM = 4;
char keys[ROW_NUM][COL_NUM] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte pin_rows[ROW_NUM] = {14, 27, 19, 23};
byte pin_column[COL_NUM] = {16, 17, 18, 32};
Keypad keypad = Keypad(makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COL_NUM);
// --- FUNCIONES ---
void mostrarPantallaPrincipal() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("AFORO UNI: ");
lcd.print(personasAdentro);
lcd.setCursor(0, 1);
lcd.print("PIN: ");
for (int i = 0; i < enteredPIN.length(); i++) {
lcd.print("*");
}
}
void abrirServo() {
digitalWrite(LED_ROJO, LOW);
digitalWrite(LED_VERDE, HIGH);
for (int pos = 0; pos <= 90; pos++) {
puerta.write(pos);
delay(10);
}
}
void cerrarServo() {
for (int pos = 90; pos >= 0; pos--) {
puerta.write(pos);
delay(10);
}
digitalWrite(LED_VERDE, LOW);
digitalWrite(LED_ROJO, HIGH);
delay(1000);
digitalWrite(LED_ROJO, LOW);
mostrarPantallaPrincipal();
}
void ejecutarAlarma(String msg1, String msg2, int ciclos) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(msg1);
lcd.setCursor(0, 1);
lcd.print(msg2);
for (int i = 0; i < ciclos; i++) {
digitalWrite(LED_ROJO, HIGH);
tone(BUZZER_PIN, 800);
delay(200);
digitalWrite(LED_ROJO, LOW);
noTone(BUZZER_PIN);
delay(200);
}
mostrarPantallaPrincipal();
}
bool esperarSensor(int pinSensor, unsigned long tiempoMax = 5000) {
unsigned long inicio = millis();
while (digitalRead(pinSensor) == HIGH) {
if (millis() - inicio > tiempoMax) return false;
delay(10);
}
while (digitalRead(pinSensor) == LOW) {
if (millis() - inicio > tiempoMax) return false;
delay(10);
}
delay(300);
return true;
}
void setup() {
puerta.setPeriodHertz(50);
puerta.attach(SERVO_PIN, 500, 2400);
puerta.write(0);
pinMode(LED_VERDE, OUTPUT);
pinMode(LED_ROJO, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(IR_ENTRADA, INPUT);
pinMode(IR_SALIDA, INPUT);
digitalWrite(LED_VERDE, LOW);
digitalWrite(LED_ROJO, LOW);
lcd.init();
lcd.backlight();
mostrarPantallaPrincipal();
}
void loop() {
char key = keypad.getKey();
if (key) {
if (key == 'A') { // INGRESO
if (enteredPIN == correctPIN) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" BIENVENIDO A ");
lcd.setCursor(0, 1);
lcd.print(" LA ESCOM ");
intentosFallidos = 0;
abrirServo();
bool paso = esperarSensor(IR_SALIDA);
delay(500);
cerrarServo();
if (paso) {
personasAdentro++;
totalEntradas++;
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("NO DETECTADO");
lcd.setCursor(0, 1);
lcd.print("INGRESO");
delay(1500);
mostrarPantallaPrincipal();
}
} else {
intentosFallidos++;
if (intentosFallidos >= 4) {
ejecutarAlarma("ALARMA ACTIVADA", "SISTEMA BLOQUEADO", 15);
intentosFallidos = 0;
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("PIN INCORRECTO");
delay(1000);
mostrarPantallaPrincipal();
}
}
enteredPIN = "";
}
else if (key == 'B') { // SALIDA
if (personasAdentro > 0) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SALIENDO...");
abrirServo();
bool paso = esperarSensor(IR_ENTRADA);
delay(500);
cerrarServo();
if (paso) {
personasAdentro--;
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("NO DETECTADO");
lcd.setCursor(0, 1);
lcd.print("SALIDA");
delay(1500);
mostrarPantallaPrincipal();
}
}
}
else if (key == 'C') { // BORRAR
enteredPIN = "";
mostrarPantallaPrincipal();
}
else if (key == 'D') { // PLAN REACCION
ejecutarAlarma(" ALERTA! ", "PLAN DE REACCION", 12);
}
else if (key == '*') { // REPORTE
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("TOTAL INGRESOS:");
lcd.setCursor(0, 1);
lcd.print(totalEntradas);
delay(2500);
mostrarPantallaPrincipal();
}
else if (key >= '0' && key <= '9' && enteredPIN.length() < 4) {
enteredPIN += key;
mostrarPantallaPrincipal();
}
}
}