#include <ESP32Servo.h> // para el motor servo
#include <Keypad.h> // Para el teclado
#include <WiFi.h> // Para uso del wifi
#include <LiquidCrystal_I2C.h> // Para usar pantalla LCD
#include <Preferences.h> // para guardar en la memoria la contraseña
// Configuración de la LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Configuración de pines
#define SERVO_PIN 1
#define BUZZER_PIN 2
#define SENSOR_PIN 3 // cambiar por boton
// Configuración del servo
Servo myservo; // objeto myservo para controlar el motor servo
//configuración EEPROM con preferences
Preferences preferences; //objeto preferences
// Configuración del teclado matricial
const byte FILAS = 4;
const byte COLUMNAS = 4;
char teclas[FILAS][COLUMNAS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte pinesFilas[FILAS] = {19, 18, 17, 16};
byte pinesColumnas[COLUMNAS] = {15, 14, 13, 12};
Keypad teclado = Keypad(makeKeymap(teclas), pinesFilas, pinesColumnas, FILAS, COLUMNAS);
char tecla;
// Variables del sistema
String codigoIngresado = "";
String codigoGuardado = ""; // Contraseña inicial por defecto
bool cambiandoCodigo = false; // Estado para saber si estamos cambiando la contraseña
String nuevoCodigo = ""; // Nuevo código en proceso de configuración
String Clave = "";
long timer = 0; // timer para bloquear Cerradura
bool puerta_abierta = false; // variable que indica si la cerradura está abierta
bool mensaje_cerrado = false; // para que solo se envie una vez en la pantalla
void setup() {
Serial.begin(115200);
lcd.init();
lcd.backlight();
myservo.attach(SERVO_PIN); // Attach el servo al pin 1
pinMode(BUZZER_PIN, OUTPUT); // establecer como salida ese pin
// Abre el espacio de nombres "Contraseñas" en modo lectura/escritura
preferences.begin("Contraseñas", false);
Clave = preferences.getString("Clave1", "Vacia"); // Lee la cadena "Clave1" (valor predeterminado "Vacia" si no se encuentra)
if (Clave == "Vacia"){
codigoGuardado = "1234";
}
else{
codigoGuardado = Clave;
}
cerrar_puerta();
mostrarMensaje("Encendiendo",0);
lcd.setCursor(11, 0);
for (int i = 0; i < 3; i++) {
lcd.print(".");
delay(500);
}
lcd.setCursor(0, 0);
mostrarMensaje("Listo!",0);
}
void loop() {
char tecla = teclado.getKey();
if (tecla) {
if (cambiandoCodigo) {
manejarCambioCodigo(tecla);
} else {
manejarEntrada(tecla);
}
}
timer_puerta(); // Después de abrir la puerta, se cierra a los 5 segundos
if(!cambiandoCodigo && !puerta_abierta && mensaje_cerrado) {
mostrarMensaje("Bloqueado",0);
mensaje_cerrado = false;
}
}
void manejarEntrada(char tecla) {
if (tecla == '#') { // Comprobar código
verificarCodigo();
} else if (tecla == '*') { // Borrar entrada
codigoIngresado = "";
mostrarMensaje("Codigo borrado",0);
} else if (tecla == 'A' && puerta_abierta == true) { // Iniciar cambio de código
cambiarCodigo();
} else {
codigoIngresado += tecla;
mostrarMensaje("Ingresando: " + codigoIngresado,0);
}
}
void verificarCodigo() {
if (codigoIngresado == codigoGuardado) {
mostrarMensaje("Desbloqueado!",0);
abrir_puerta(); // Si la contraseña es correcta, abre la puerta
} else {
mostrarMensaje("Codigo incorrecto",0);
activarAlerta();
}
codigoIngresado = ""; // Reiniciar código ingresado
}
void cambiarCodigo() {
cambiandoCodigo = true;
nuevoCodigo = ""; // Reiniciar nuevo código
mostrarMensaje("Nuevo codigo:",0);
}
void manejarCambioCodigo(char tecla) {
if (tecla == '#') {
if (nuevoCodigo.length() >= 4) {
codigoGuardado = nuevoCodigo;
Clave = codigoGuardado;
preferences.putString("Clave1",Clave); // Almacena Clave con la clave "Clave1"
mostrarMensaje("Codigo guardado!",0);
cambiandoCodigo = false;
delay(1000);
} else {
mostrarMensaje("Codigo: ",1);
mostrarMensaje("Muy corto",2);
}
} else if (tecla == '*') {
nuevoCodigo = ""; // Reiniciar nuevo código
mostrarMensaje("Codigo borrado",0);
} else {
nuevoCodigo += tecla;
mostrarMensaje("Nuevo: " + nuevoCodigo,0);
}
}
void mostrarMensaje(String mensaje, int pos) {
if(pos==0){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(mensaje.substring(0, 16)); // Primera línea
if (mensaje.length() > 16) {
lcd.setCursor(0, 1);
lcd.print(mensaje.substring(16)); // Segunda línea
}
}
if(pos==1){
lcd.setCursor(0, 0);
lcd.print(mensaje); // Primera línea
}
if(pos==2){
lcd.setCursor(0, 1);
lcd.print(mensaje);
}
}
void cerrar_puerta() {
myservo.write(0); // Mover el servo a la posición de bloqueo
puerta_abierta = false;
}
void abrir_puerta() {
myservo.write(90); // Mover el servo a la posición de desbloqueo
puerta_abierta = true;
mensaje_cerrado = true;
timer = millis(); // Guardar el tiempo exacto en que se abre la puerta
// Marcar que la puerta se ha abierto
}
void timer_puerta() {
// Verificamos si ha pasado el tiempo de 5 segundos y la puerta está abierta
if (puerta_abierta && (millis() - timer >= 2000)) {
cerrar_puerta(); // Si han pasado 2 segundos, cerramos la puerta
}
}
void activarAlerta() {
tone(BUZZER_PIN, 1000, 250); // Plays 262Hz tone for 0.250 seconds
}