#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
#include <Wire.h>
#include <RTClib.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); // Inicializar pantalla de 20x4
Servo servo;
RTC_DS3231 rtc; // Asegúrate de que tienes este RTC conectado
// Pines a utilizar
#define pirPin 2
#define buzzerPin 4
#define btnPin 14
#define ledAllowed 17
#define ledDenied 16
#define servoPin 15
boolean pirState = false;
boolean isAllowed = false;
unsigned long lastTimeBtnStateChanged = millis();
unsigned long debounce = 50;
byte lastBtnState = 0;
// Definir la estructura RFIDCard
struct RFIDCard {
String id;
String name;
};
// Arreglo de tarjetas predefinidas
RFIDCard cards[] = {
{"123456", "John Doe"},
{"654321", "Jane Smith"},
{"112233", "Alice Johnson"},
{"445566", "Bob Brown"},
{"778899", "Charlie Davis"},
{"998877", "Eva Wilson"},
{"334455", "George Clark"},
{"223344", "Hannah Lee"},
{"556677", "Isabella King"}
};
// Número de tarjetas en el sistema
const int numCards = sizeof(cards) / sizeof(cards[0]);
// Función para sonido del buzzer al permitir acceso
void buzzerBeep() {
tone(buzzerPin, 4000, 100); // Sonido de 4000 Hz por 100 ms
delay(100); // Pausa de 100 ms
noTone(buzzerPin); // Apagar el tono
delay(100); // Pausa de 100 ms
}
// Función para sonido del buzzer al denegar acceso
void buzzerBeepNO() {
tone(buzzerPin, 300, 100); // Sonido de 300 Hz por 100 ms
delay(100); // Pausa de 100 ms
noTone(buzzerPin); // Apagar el tono
delay(100); // Pausa de 100 ms
tone(buzzerPin, 300, 100); // Repetir el sonido
delay(100); // Pausa de 100 ms
}
// Función para simular el nivel de batería
float getBatteryLevel() {
int sensorValue = analogRead(34); // Leer voltaje de la batería en GPIO 34
float voltage = sensorValue * (3.3 / 4095.0) * 2; // Conversión a voltaje, considerando divisor de voltaje
return voltage;
}
// Función para determinar si la batería es alta o baja
String obtenerEstadoBateria(float voltage) {
if (voltage > 3.7) {
return "Bateria Alta";
} else {
return "Bateria Baja";
}
}
void setup() {
// Inicializar el serial
Serial.begin(115200);
// Modo de los pines
pinMode(btnPin, INPUT);
pinMode(ledAllowed, OUTPUT);
pinMode(ledDenied, OUTPUT);
pinMode(buzzerPin, OUTPUT);
// Inicializar el servomotor
servo.attach(servoPin, 500, 2400);
// Inicializar la LCD
lcd.init();
lcd.backlight();
// Inicializar el RTC
if (!rtc.begin()) {
Serial.println("No se encontró el RTC");
while (1);
}
// Si el RTC pierde potencia, establecer la fecha y hora inicial
if (rtc.lostPower()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
Serial.println("Sistema de control de acceso listo");
}
void loop() {
// Leer el estado del botón
byte btnState = digitalRead(btnPin);
// Verificar si el botón fue presionado (debounce)
if (btnState == HIGH && (millis() - lastTimeBtnStateChanged > debounce)) {
lastTimeBtnStateChanged = millis();
// Simulamos una tarjeta leída (código de tarjeta)
String cardId = "123456"; // Cambia esto para probar con diferentes tarjetas
isAllowed = false;
// Comprobar si la tarjeta es válida
for (int i = 0; i < numCards; i++) {
if (cards[i].id == cardId) {
isAllowed = true;
break;
}
}
// Mostrar en la pantalla LCD
lcd.clear();
lcd.setCursor(0, 0);
if (isAllowed) {
lcd.print("Acceso Permitido");
digitalWrite(ledAllowed, HIGH); // Encender LED de permitido
buzzerBeep(); // Sonido de permitido
servo.write(90); // Mover el servo a 90 grados (abrir)
delay(2000); // Mantener abierto por 2 segundos
servo.write(0); // Cerrar el servo
} else {
lcd.print("Acceso Denegado");
digitalWrite(ledDenied, HIGH); // Encender LED de denegado
buzzerBeepNO(); // Sonido de denegado
}
// Esperar un tiempo para limpiar los LEDs
delay(2000);
digitalWrite(ledAllowed, LOW); // Apagar LED de permitido
digitalWrite(ledDenied, LOW); // Apagar LED de denegado
}
// Obtener la fecha y hora del RTC
DateTime now = rtc.now();
String currentDateTime = String(now.year()) + "/" + String(now.month()) + "/" + String(now.day()) + " " +
String(now.hour()) + ":" + String(now.minute());
// Simular la lectura de batería
float batteryVoltage = getBatteryLevel();
String batteryStatus = obtenerEstadoBateria(batteryVoltage);
// Mostrar en la pantalla LCD (20x4) la fecha y estado de batería
lcd.setCursor(0, 1); // Línea 2
lcd.print("Bateria: ");
lcd.print(batteryStatus);
lcd.setCursor(0, 2); // Línea 3
lcd.print("Fecha: ");
lcd.print(currentDateTime);
delay(1000); // Actualizar cada segundo
}