#include <Keypad.h>
#include <LiquidCrystal.h>
// =====================================================
// LCD 16x2
// Pines: RS, E, D4, D5, D6, D7
// =====================================================
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
// =====================================================
// PINES DEL SISTEMA
// =====================================================
const int PIR_PIN = 27;
const int SENSOR_MAGNETICO = 5; // Boton: presionado = cerrado
const int BUZZER_PIN = 6;
const int LED_VERDE_ARMADO = 4;
// LED RGB
const int RGB_ROJO = 3;
const int RGB_VERDE = 2;
const int RGB_AZUL = 1;
// =====================================================
// TECLADO MATRICIAL 4x4
// =====================================================
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
// Pines que tú indicaste
byte rowPins[ROWS] = {26, 22, 21, 20};
byte colPins[COLS] = {19, 18, 17, 16};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// =====================================================
// ESTADOS DEL SISTEMA
// =====================================================
enum Estado {
STANDBY,
ARMADO,
ALARMA
};
Estado estado = STANDBY;
// =====================================================
// VARIABLES
// =====================================================
String pinSistema = "";
String pinIngresado = "";
bool fotoEnviada = false;
bool mensajeStandby = false;
bool mensajeArmado = false;
bool mensajeAlarma = false;
unsigned long tiempoBuzzer = 0;
bool buzzerEstado = false;
// =====================================================
// LCD
// =====================================================
void mostrarMensaje(String linea1, String linea2) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(linea1.substring(0, 16));
lcd.setCursor(0, 1);
lcd.print(linea2.substring(0, 16));
}
// =====================================================
// LED RGB
// =====================================================
void rgbNaranja() {
digitalWrite(RGB_ROJO, HIGH);
digitalWrite(RGB_VERDE, HIGH);
digitalWrite(RGB_AZUL, LOW);
}
void rgbVerde() {
digitalWrite(RGB_ROJO, LOW);
digitalWrite(RGB_VERDE, HIGH);
digitalWrite(RGB_AZUL, LOW);
}
void rgbRojo() {
digitalWrite(RGB_ROJO, HIGH);
digitalWrite(RGB_VERDE, LOW);
digitalWrite(RGB_AZUL, LOW);
}
// =====================================================
// SENSORES
// =====================================================
bool puertaCerrada() {
/*
Sensor magnetico simulado con boton.
INPUT_PULLUP:
Boton presionado = LOW = puerta cerrada
Boton suelto = HIGH = puerta abierta
*/
return digitalRead(SENSOR_MAGNETICO) == LOW;
}
bool hayMovimiento() {
return digitalRead(PIR_PIN) == HIGH;
}
bool sensoresSeguros() {
return puertaCerrada() && !hayMovimiento();
}
// =====================================================
// MOSTRAR ESTADO DE SENSORES
// =====================================================
void mostrarEstadoSensores() {
if (puertaCerrada()) {
mostrarMensaje("Sensor magnet.", "CERRADO");
} else {
mostrarMensaje("Sensor magnet.", "ABIERTO");
}
delay(1200);
if (hayMovimiento()) {
mostrarMensaje("Sensor PIR", "MOVIMIENTO");
} else {
mostrarMensaje("Sensor PIR", "SIN PRESENCIA");
}
delay(1200);
}
// =====================================================
// CREAR PIN AL INICIAR
// =====================================================
String crearPIN() {
String clave = "";
mostrarMensaje("Cree su PIN", "Presione # OK");
while (true) {
char tecla = keypad.getKey();
if (tecla) {
if (tecla >= '0' && tecla <= '9') {
clave += tecla;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Cree su PIN:");
lcd.setCursor(0, 1);
for (int i = 0; i < clave.length(); i++) {
lcd.print("*");
}
}
if (tecla == '*') {
clave = "";
mostrarMensaje("PIN borrado", "Ingrese otra vez");
delay(1000);
mostrarMensaje("Cree su PIN", "Presione # OK");
}
if (tecla == '#') {
if (clave.length() >= 4) {
return clave;
} else {
mostrarMensaje("PIN muy corto", "Min 4 digitos");
delay(1200);
mostrarMensaje("Cree su PIN", "Presione # OK");
}
}
}
}
}
// =====================================================
// FOTO Y EMAIL SIMULADOS
// =====================================================
void tomarYEnviarFoto() {
mostrarMensaje("Tomando foto", "DroidCam...");
delay(1500);
mostrarMensaje("Foto capturada", "Correctamente");
delay(1500);
mostrarMensaje("Enviando foto", "por email...");
delay(1500);
mostrarMensaje("Email enviado", "Usuario alertado");
delay(1500);
}
// =====================================================
// ACTIVAR ALARMA
// =====================================================
void activarAlarma(String causa) {
estado = ALARMA;
fotoEnviada = false;
mensajeAlarma = false;
pinIngresado = "";
rgbRojo();
digitalWrite(LED_VERDE_ARMADO, LOW);
mostrarMensaje("ALARMA ACTIVA", causa);
delay(1200);
}
// =====================================================
// BUZZER INTERMITENTE
// =====================================================
void manejarBuzzer() {
if (millis() - tiempoBuzzer >= 250) {
tiempoBuzzer = millis();
buzzerEstado = !buzzerEstado;
digitalWrite(BUZZER_PIN, buzzerEstado);
}
}
// =====================================================
// APAGAR ALARMA CON PIN
// =====================================================
void leerPINParaApagar() {
char tecla = keypad.getKey();
if (tecla) {
if (tecla >= '0' && tecla <= '9') {
pinIngresado += tecla;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("PIN apagar:");
lcd.setCursor(0, 1);
for (int i = 0; i < pinIngresado.length(); i++) {
lcd.print("*");
}
}
if (tecla == '*') {
pinIngresado = "";
mostrarMensaje("PIN borrado", "Intente otra vez");
delay(900);
mostrarMensaje("PIN apagar:", "Ingrese clave");
}
if (tecla == '#') {
if (pinIngresado == pinSistema) {
digitalWrite(BUZZER_PIN, LOW);
buzzerEstado = false;
rgbNaranja();
digitalWrite(LED_VERDE_ARMADO, LOW);
estado = STANDBY;
fotoEnviada = false;
mensajeStandby = false;
mensajeArmado = false;
mensajeAlarma = false;
pinIngresado = "";
mostrarMensaje("PIN correcto", "Alarma apagada");
delay(1500);
} else {
pinIngresado = "";
mostrarMensaje("PIN incorrecto", "Alarma sigue");
delay(1200);
mostrarMensaje("PIN apagar:", "Ingrese clave");
}
}
}
}
// =====================================================
// ARMAR SISTEMA CON TECLA A
// =====================================================
void revisarTeclaA() {
char tecla = keypad.getKey();
if (tecla == 'A') {
mostrarMensaje("Tecla A detect.", "Espere 3 seg...");
delay(3000);
mostrarMensaje("Verificando", "sensores...");
delay(1000);
mostrarEstadoSensores();
if (sensoresSeguros()) {
estado = ARMADO;
rgbVerde();
digitalWrite(LED_VERDE_ARMADO, HIGH);
digitalWrite(BUZZER_PIN, LOW);
mensajeArmado = false;
mensajeStandby = false;
mostrarMensaje("Sistema armado", "Seguridad ON");
delay(1500);
} else {
rgbNaranja();
digitalWrite(LED_VERDE_ARMADO, LOW);
mostrarMensaje("No se puede", "armar sistema");
delay(1500);
if (!puertaCerrada()) {
mostrarMensaje("Boton suelto", "Sensor abierto");
delay(1500);
mostrarMensaje("Presione boton", "para cerrar");
delay(1500);
}
if (hayMovimiento()) {
mostrarMensaje("PIR activo", "Hay presencia");
delay(1500);
mostrarMensaje("Espere zona", "sin movimiento");
delay(1500);
}
mensajeStandby = false;
}
}
}
// =====================================================
// SETUP
// =====================================================
void setup() {
lcd.begin(16, 2);
pinMode(PIR_PIN, INPUT);
pinMode(SENSOR_MAGNETICO, INPUT_PULLUP);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(LED_VERDE_ARMADO, OUTPUT);
pinMode(RGB_ROJO, OUTPUT);
pinMode(RGB_VERDE, OUTPUT);
pinMode(RGB_AZUL, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
digitalWrite(LED_VERDE_ARMADO, LOW);
rgbNaranja();
mostrarMensaje("Alarma casera", "Iniciando...");
delay(1500);
pinSistema = crearPIN();
mostrarMensaje("PIN guardado", "Sistema listo");
delay(1500);
mostrarEstadoSensores();
mostrarMensaje("Modo standby", "LED naranja");
delay(1500);
}
// =====================================================
// LOOP PRINCIPAL
// =====================================================
void loop() {
// =====================================================
// STANDBY
// =====================================================
if (estado == STANDBY) {
rgbNaranja();
digitalWrite(BUZZER_PIN, LOW);
digitalWrite(LED_VERDE_ARMADO, LOW);
if (!mensajeStandby) {
mensajeStandby = true;
if (puertaCerrada()) {
mostrarMensaje("Standby", "Sensor cerrado");
} else {
mostrarMensaje("Standby", "Sensor abierto");
}
delay(1000);
mostrarMensaje("Para armar", "Presione A");
}
revisarTeclaA();
}
// =====================================================
// ARMADO
// =====================================================
if (estado == ARMADO) {
if (!mensajeArmado) {
mensajeArmado = true;
mostrarMensaje("Sistema armado", "Sin intrusos");
}
if (hayMovimiento()) {
activarAlarma("Movimiento PIR");
}
if (!puertaCerrada()) {
activarAlarma("Puerta abierta");
}
}
// =====================================================
// ALARMA
// =====================================================
if (estado == ALARMA) {
manejarBuzzer();
if (!fotoEnviada) {
fotoEnviada = true;
tomarYEnviarFoto();
mostrarMensaje("PIN apagar:", "Ingrese clave");
}
leerPINParaApagar();
}
}