#include <LiquidCrystal_I2C.h>
// --- Configuración de Hardware ---
#define DIRECCION_LCD 0x27
#define ANCHO_LCD 16
#define ALTO_LCD 2
// Instancia de la pantalla
LiquidCrystal_I2C pantalla(DIRECCION_LCD, ANCHO_LCD, ALTO_LCD);
// Asignación de terminales
const int SERVO_PIN = 9; // Salida PWM para el motor
const int LED_STATUS = 8; // Indicador visual
const int BTN_INPUT = 7; // Pulsador con Pull-up interno
// Parámetros de temporización para el Servo
const int PULSO_MIN = 500;
const int PULSO_MAX = 2400;
// Estado global del sistema
bool estaAbierta = false;
void setup() {
Serial.begin(115200);
// Configuración de E/S
pinMode(SERVO_PIN, OUTPUT);
pinMode(LED_STATUS, OUTPUT);
pinMode(BTN_INPUT, INPUT_PULLUP);
// Inicialización de periféricos
pantalla.init();
pantalla.backlight();
pantalla.clear();
pantalla.setCursor(0, 0);
pantalla.print("Puerta: ABIERTA");
// Estado inicial: Sistema bloqueado
accionarMecanismo(0);
digitalWrite(LED_STATUS, LOW);
}
void loop() {
// Detección de pulsación (Lógica negativa por Pull-up)
if (digitalRead(BTN_INPUT) == LOW) {
delay(50); // Filtro para evitar ruido (debouncing)
if (digitalRead(BTN_INPUT) == LOW) {
estaAbierta = !estaAbierta; // Invertir el estado actual
pantalla.clear();
pantalla.setCursor(0, 0);
if (estaAbierta) {
accionarMecanismo(90); // Posición de apertura
digitalWrite(LED_STATUS, HIGH);
pantalla.print("Puerta: CERRADA");
}
else {
accionarMecanismo(0); // Posición de cierre
digitalWrite(LED_STATUS, LOW);
pantalla.print("Puerta: ABIERTA");
}
// Bloqueo hasta que se libere el pulsador
while (digitalRead(BTN_INPUT) == LOW) {
delay(10);
}
}
}
}
/**
* Gestiona el movimiento del servo mediante pulsos manuales
* @param grados Ángulo de destino (0-180)
*/
void accionarMecanismo(int grados) {
int anchoPulso = map(grados, 0, 180, PULSO_MIN, PULSO_MAX);
// Ciclo de refresco para asegurar la posición física
for (int ciclo = 0; ciclo < 50; ciclo++) {
digitalWrite(SERVO_PIN, HIGH);
delayMicroseconds(anchoPulso);
digitalWrite(SERVO_PIN, LOW);
// Mantiene la frecuencia de 50Hz (periodo de 20ms)
delay(20 - (anchoPulso / 1000));
}
}