// Definir pines para el teclado matricial 4x4
const int filas[4] = {13, 12, 14, 27}; // Pines conectados a las filas del teclado
const int columnas[4] = {25, 26, 33, 32}; // Pines conectados a las columnas del teclado
// Mapeo del teclado 4x4
char teclas[4][4] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'F', '0', 'E', 'D'} //'D' será enter
};
// Definir pines para el display de 7 segmentos (4 dígitos)
const int segmentos[7] = {15, 2, 4, 5, 18, 19, 23}; // Pines para los segmentos a-g
const int digitos[2] = {22, 21}; // Solo usaremos los pines 22 y 21 para los dígitos del display
// Variables para el display y contador
char display[4] = {' ', ' ', ' ', ' '};
byte segmentosCaracteres[16] = {0X3F, 0X06, 0X5B, 0X4F, 0X66,
0X6D, 0X7D, 0X07, 0X7F, 0X6F, 0X77, 0X7C, 0X58, 0X5E, 0X71, 0X79};
int contador = 11;
bool detener = false;
// Contraseña para detener el contador
String password = "0406";
String entrada = "";
// Intentos
int intentos = 3;
bool intentosAgotados = false;
// Temporización del contador
unsigned long tiempoPrevio = 0;
unsigned long periodo = 1000;
void setup() {
Serial.begin(115200); // Iniciar comunicación serial
// Configurar pines de segmentos como salidas
for (int i = 0; i < 7; i++) {
pinMode(segmentos[i], OUTPUT);
digitalWrite(segmentos[i], LOW);
}
// Configurar pines de dígitos como salidas (solo los pines 22 y 21)
for (int i = 0; i < 2; i++) {
pinMode(digitos[i], OUTPUT);
digitalWrite(digitos[i], HIGH); // Apagar dígitos
}
// Configurar pines de filas como entradas
for (int i = 0; i < 4; i++) {
pinMode(filas[i], INPUT);
}
// Configurar pines de columnas como entradas con resistencia pull-up
for (int i = 0; i < 4; i++) {
pinMode(columnas[i], INPUT_PULLUP);
}
// Mostrar intentos iniciales en el Serial Monitor
Serial.print("Intentos restantes: ");
Serial.println(intentos);
}
void loop() {
if (intentosAgotados) {
Serial.println("Intentos agotados");
return; // Si los intentos se agotaron, detener el programa
}
// Leer el teclado
char tecla = leerTeclado();
// Si se ha presionado una tecla
if (tecla) {
if (tecla == 'D') { // Si se presiona 'D', verificar la contraseña
if (entrada == password) {
detener = true; // Si la contraseña es correcta, detener el contador
Serial.println("Contraseña correcta. Contador detenido.");
} else {
intentos--; // Restar un intento
Serial.print("Contraseña incorrecta. Intentos restantes: ");
Serial.println(intentos);
if (intentos == 0) {
intentosAgotados = true; // Si no quedan intentos, marcar como agotados
Serial.println("Intentos agotados");
}
}
entrada = ""; // Reiniciar la entrada después de verificar
} else {
entrada += tecla; // Concatenar la tecla presionada
}
}
// Actualizar el contador si no está detenido
if (!detener && millis() - tiempoPrevio >= periodo) {
tiempoPrevio = millis();
contador--;
if (contador < 0) {
detener = true; // Detener el contador si llega a 0
// Apagar los dígitos del display
for (int i = 0; i < 2; i++) {
digitalWrite(digitos[i], HIGH); // Apagar dígitos
}
Serial.println("Contador terminado.");
return; // Terminar la ejecución
}
mostrarNumero(contador);
}
// Mostrar el contenido en el display (multiplexado)
for (int i = 0; i < 2; i++) {
mostrarCaracter(i, display[i + 2]); // Mostrar solo los dígitos correspondientes
}
}
// Función para leer la tecla presionada
char leerTeclado() {
for (int i = 0; i < 4; i++) {
// Configurar la fila como salida y ponerla en LOW
pinMode(filas[i], OUTPUT);
digitalWrite(filas[i], LOW);
// Leer las columnas
for (int j = 0; j < 4; j++) {
pinMode(columnas[j], INPUT_PULLUP);
if (digitalRead(columnas[j]) == LOW) {
while (digitalRead(columnas[j]) == LOW); // Esperar a que se suelte la tecla
return teclas[i][j]; // Retornar la tecla presionada
}
}
// Restablecer la fila a entrada para evitar interferencias
pinMode(filas[i], INPUT);
}
return 0; // No se ha presionado ninguna tecla
}
// Función para mostrar un número en el display
void mostrarNumero(int num) {
if (num < 10) {
display[2] = ' '; // Mostrar un espacio en lugar de las decenas
display[3] = num + '0'; // Mostrar solo las unidades
} else {
display[2] = (num / 10) + '0'; // Obtener y mostrar las decenas
display[3] = (num % 10) + '0'; // Obtener y mostrar las unidades
}
}
// Función para encender los segmentos del display
void mostrarCaracter(int digito, char caracter) {
byte segmentosEncender = 0b00000000; // Apagar todos los segmentos por defecto
// Convertir el carácter en segmentos
if (caracter >= '0' && caracter <= '9') {
segmentosEncender = segmentosCaracteres[caracter - '0']; // Convertir el caracter en número
}
// Encender los segmentos adecuados
for (int i = 0; i < 7; i++) {
// Usar desplazamiento de bits y operación AND para leer el estado del bit
digitalWrite(segmentos[i], (segmentosEncender >> i) & 0b00000001);
}
// Encender el dígito correspondiente
digitalWrite(digitos[digito], LOW); // Activa el dígito
delay(5);
digitalWrite(digitos[digito], HIGH); // Desactiva el dígito
}