#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define SDA_PIN 8
#define SCL_PIN 9
#define ledPin 16
#define buzzerPin 15
#define pirPin 2
//Pines matrix:
// Definir pines
const int filas[4] = {19, 20, 21, 47};
const int columnas[4] = {48, 45, 40, 41};
// Mapa de teclas(IA)
char mapaTeclas[4][4] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
char claveCorrecta[6] = {'2','0','2','3', '4','8'};
char claveRecibida[6] = {'0','0','0','0', '0','0'};
char tecla_leida;
LiquidCrystal_I2C lcd(0x27, 16, 2);
enum Estados{
desabilitado,
habilitado,
habilitado_recibir_clave,
alarma
}
Estados estado_actual = desabilitado;
Estados estado_siguiente = desabilitado;
//VAriables de control para maquina de estados}:
volatile bool hay_movimiento = false;
bool clave_es_correcta = false;
bool clave_en_tiempo_correcto = false;
bool se_termino_leer_clave = false;
uint8_t clave_pos = 0;
void ARDUINO_ISR_ATTR ISR_detectar_movimiento_positivo() {
hay_movimiento = true;
}
void ARDUINO_ISR_ATTR ISR_detectar_movimiento_negativo() {
hay_movimiento = false;
}
void setup() {
Serial.begin(115200);
Wire.begin(SDA_PIN, SCL_PIN);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
pinMode(ledPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(pirPin, INPUT);
attachInterrupt(digitalPinToInterrupt(pirPin), ISR_detectar_movimiento_positivo, RISING);
attachInterrupt(digitalPinToInterrupt(pirPin), ISR_detectar_movimiento_negativo, FALLING);
// Configurar filas como entradas con pull-up
for (int i = 0; i < 4; i++) {
pinMode(filas[i], INPUT_PULLUP);
}
// Configurar columnas como salidas
for (int i = 0; i < 4; i++) {
pinMode(columnas[i], OUTPUT);
digitalWrite(columnas[i], HIGH); // desactivadas
}
}
void loop() {
tecla_leida = leerTecla();
}
//Funcion para saber que tecla de la matrix se toco (IA)
char leerTecla() {
for (int c = 0; c < 4; c++) {
// Activar una columna (LOW)
digitalWrite(columnas[c], LOW);
// Revisar todas las filas
for (int f = 0; f < 4; f++) {
if (digitalRead(filas[f]) == LOW) { // tecla presionada
digitalWrite(columnas[c], HIGH); // restaurar
return mapaTeclas[f][c];
}
}
// Desactivar columna
digitalWrite(columnas[c], HIGH);
}
return 0; // ninguna tecla
}
void maquina_estados(){
switch(estado_actual){
case (desabilitado):
if(clave_es_correcta == true) estado_siguiente = habilitado;
else estado_siguiente = desabilitado;
break;
case(habilitado):
if(hay_movimiento = true) estado_siguiente = habilitado_recibir_clave;
case(habilitado_recibir_clave):
if(clave_es_correcta == true && clave_en_tiempo_correcto == true) estado_siguiente = desabilitado;
else if(clave_en_tiempo_correcto == false) estado_siguiente = alarma;
case (alarma):
if(clave_es_correcta == true) estado_siguiente = desabilitado;
}
estado_actual = estado_siguiente;
}
void leer_clave(){
if(tecla_leida != 0){
if(tecla_leida != 'D'){
if(clave_pos < 6){
se_termino_leer_clave = false;
claveRecibida[clave_pos] = tecla_leida;
clave_pos++;
claveRecibida = {'0','0','0','0', '0','0'};
clave_pos = 0;
}else{
se_termino_leer_clave = true;
claveRecibida = {'0','0','0','0', '0','0'};
clave_pos = 0;
}
}else{
se_termino_leer_clave = true;
clave_pos = 0;
}
}
}
void validar_clave(){
if(se_termino_leer_clave){
clave_es_correcta = claveRecibida == claveCorrecta;
}
}