#include <Keypad.h>
#include <Servo.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Definición de constantes para la pantalla OLED
#define ANCHO_PANTALLA 128
#define ALTO_PANTALLA 64
#define OLED_RESET -1
// Inicialización del objeto para la pantalla OLED
Adafruit_SSD1306 display(ANCHO_PANTALLA, ALTO_PANTALLA, &Wire, OLED_RESET);
// Definición de la matriz de teclas del teclado numérico
const byte FILAS = 4; // Cuatro filas
const byte COLUMNAS = 4; // Cuatro columnas
char teclas[FILAS][COLUMNAS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte pinesFilas[FILAS] = {2, 3, 4, 5}; // Pines conectados a las filas del teclado
byte pinesColumnas[COLUMNAS] = {6, 7, 8, 9}; // Pines conectados a las columnas del teclado
// Configuración del teclado numérico
Keypad keypad = Keypad(makeKeymap(teclas), pinesFilas, pinesColumnas, FILAS, COLUMNAS);
Servo myservo; // Objeto para controlar el servo
int posicion = 0; // Variable para almacenar la posición del servo
String codigo = ""; // Variable para almacenar el código ingresado por el usuario
String codigoCorrecto = "A1B2C3D4"; // Código correcto para acceder
bool troyanoActivo = false; // Indicador de activación del "troyano"
unsigned long ultimoTiempoAcceso = 0; // Tiempo del último acceso autorizado
unsigned long retardoAcceso = 5000; // Retardo de 5 segundos para cerrar la puerta automáticamente
void setup() {
myservo.attach(10); // Asignar el pin 10 al servo
Serial.begin(9600); // Iniciar comunicación serial a 9600 baudios
myservo.write(0); // Configurar el servo en posición cerrada
delay(500); // Pequeña pausa para asegurar que el servo se establezca correctamente
// Inicialización de la pantalla OLED
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Iniciar la comunicación con la pantalla OLED
Serial.println(F("Error al asignar SSD1306")); // Imprimir mensaje de error si la inicialización falla
for(;;); // Bucle infinito para detener el programa en caso de error
}
display.display(); // Mostrar pantalla OLED
delay(2000); // Esperar 2 segundos
display.clearDisplay(); // Limpiar la pantalla OLED
// Configurar el texto inicial en la pantalla OLED
display.setTextSize(1); // Tamaño de texto 1 (pequeño)
display.setTextColor(WHITE); // Color del texto blanco
display.setCursor(0, 0); // Establecer el cursor en la posición (0, 0)
display.println(F("Ingrese Codigo:")); // Imprimir mensaje inicial en la pantalla OLED
display.display(); // Mostrar lo que se ha dibujado en la pantalla OLED
}
void loop() {
char tecla = keypad.getKey(); // Leer la tecla presionada por el usuario
if (tecla) { // Verificar si se ha presionado una tecla
if (tecla != '#') { // Si la tecla presionada no es '#'
codigo += tecla; // Agregar la tecla presionada al código ingresado
} else { // Si se presiona '#', se finaliza el ingreso del código
// Validar el código ingresado
if (!troyanoActivo && codigo == codigoCorrecto) { // Si no está activo el "troyano" y el código es correcto
display.clearDisplay(); // Limpiar la pantalla OLED
display.setCursor(0, 0); // Establecer el cursor en la posición (0, 0)
display.println(F("Acceso Permitido")); // Mostrar mensaje de acceso permitido en la pantalla OLED
display.display(); // Mostrar mensaje en la pantalla OLED
myservo.write(90); // Abrir la puerta (posición del servo 90 grados)
delay(2000); // Esperar 2 segundos
myservo.write(0); // Cerrar la puerta (posición del servo 0 grados)
ultimoTiempoAcceso = millis(); // Actualizar el tiempo del último acceso
display.clearDisplay(); // Limpiar la pantalla OLED
display.setCursor(0, 0); // Establecer el cursor en la posición (0, 0)
display.println(F("Ingrese Codigo:")); // Mostrar mensaje de ingreso de código en la pantalla OLED
display.display(); // Mostrar mensaje en la pantalla OLED
} else if (troyanoActivo || codigo.startsWith("9999")) { // Si está activo el "troyano" o se ingresa el código especial
// Activar el "troyano" o código especial para desactivar la validación
troyanoActivo = true; // Activar el "troyano"
display.clearDisplay(); // Limpiar la pantalla OLED
display.setCursor(0, 0); // Establecer el cursor en la posición (0, 0)
display.println(F("Acceso Permitido")); // Mostrar mensaje de acceso permitido en la pantalla OLED
display.display(); // Mostrar mensaje en la pantalla OLED
myservo.write(90); // Abrir la puerta (posición del servo 90 grados)
delay(2000); // Esperar 2 segundos
myservo.write(0); // Cerrar la puerta (posición del servo 0 grados)
ultimoTiempoAcceso = millis(); // Actualizar el tiempo del último acceso
display.clearDisplay(); // Limpiar la pantalla OLED
display.setCursor(0, 0); // Establecer el cursor en la posición (0, 0)
display.println(F("Ingrese Codigo:")); // Mostrar mensaje de ingreso de código en la pantalla OLED
display.display(); // Mostrar mensaje en la pantalla OLED
} else { // Si el código ingresado no es correcto y no se activa el "troyano"
display.clearDisplay(); // Limpiar la pantalla OLED
display.setCursor(0, 0); // Establecer el cursor en la posición (0, 0)
display.println(F("Acceso Denegado")); // Mostrar mensaje de acceso denegado en la pantalla OLED
display.display(); // Mostrar mensaje en la pantalla OLED
display.setCursor(0, 10); // Establecer el cursor en la posición (0, 10)
display.println(F("Intente de nuevo")); // Mostrar mensaje para intentar de nuevo en la pantalla OLED
display.display(); // Mostrar mensaje en la pantalla OLED
// Devolver el servo a su estado inicial después de 5 segundos
unsigned long tiempoActual = millis(); // Obtener el tiempo actual en milisegundos
if (tiempoActual - ultimoTiempoAcceso >= retardoAcceso) { // Si ha pasado el tiempo de retardo
myservo.write(0); // Cerrar la puerta (posición del servo 0 grados)
}
delay(2000); // Esperar 2 segundos
display.clearDisplay(); // Limpiar la pantalla OLED
display.setCursor(0, 0); // Establecer el cursor en la posición (0, 0)
display.println(F("Ingrese Codigo:")); // Mostrar mensaje de ingreso de código en la pantalla OLED
display.display(); // Mostrar mensaje en la pantalla OLED
}
codigo = ""; // Reiniciar el código ingresado
}
// Actualizar la pantalla OLED para mostrar el código ingresado
display.clearDisplay(); // Limpiar la pantalla OLED
display.setCursor(0, 0); // Establecer el cursor en la posición (0, 0)
display.println(F("Ingrese Codigo:")); // Mostrar mensaje de ingreso de código en la pantalla OLED
display.print(codigo); // Mostrar el código ingresado por el usuario en la pantalla OLED
display.display(); // Mostrar mensaje en la pantalla OLED
}
}