Proyecto Final 2

Garaje y Punto de Acceso Inteligente

 

¡Afrontemos un nuevo módulo de tu aprendizaje en domótica! En este proyecto, te sumergirás en la automatización y seguridad de uno de los espacios más funcionales de tu hogar: el garaje. Diseñarás y construirás un "Guardián del Garaje y una Puerta de Acceso Inteligente", aprendiendo a controlar el acceso vehicular, monitorizar la ocupación y gestionar una puerta auxiliar, todo ello con tecnología de vanguardia.

Tu misión principal será implementar un sistema que detecte la aproximación de un vehículo mediante un sensor infrarrojo (IR), activando de inmediato un motor paso a paso 5V 28BYJ-48 para abrir la puerta principal del garaje con precisión milimétrica. Para evitar situaciones incómodas, un módulo medidor de distancia láser se encargará de verificar si ya hay un coche aparcado dentro, garantizando que solo se permita el acceso si la plaza está libre. Además, tu proyecto incluirá la automatización de un acceso secundario: un micro servo SG90 de 180 grados controlará la apertura y cierre de una puerta trasera o una trampilla, al presionar uno de los pulsadores, ofreciendo una opción versátil para personas o incluso mascotas.

La información y el estado del garaje serán presentados de forma clara y concisa a través de una pantalla OLED, mostrando mensajes útiles como "Puerta Abierta", "Garaje Ocupado" o "Plaza Libre". Complementando esto, el LED RGB del MentorBit proporcionará una retroalimentación visual instantánea sobre el estado general del garaje y sus componentes. Para la conectividad de todos estos elementos, utilizarás tu MentorBit junto con el módulo expansor de entradas y salidas, apoyándote en los cables JST, tornillos y tuercas para un montaje robusto y funcional de tu prototipo. Prepárate para dominar la detección de movimiento, el control de motores con alta precisión y la visualización de datos cruciales, llevando la automatización del garaje a un nuevo nivel.

#include <MentorBit.h>
#include <MentorBitMotores.h>  // Para el Servo y el PaP
#include <MentorBitPantallas.h> // Para la pantalla OLED
#include <MentorBitVL53.h>      // Para el sensor de distancia láser
#include <MentorBitIR.h>       // Para el sensor de infrarrojos
#include <MentorBitPuertos.h>  // Para la gestión de pines
#include <MentorBitRGB.h>      // Para el RGB

// --- INSTANCIACIÓN DE OBJETOS ---
MentorBit miMentorBit;
MentorBitPuertos miModuloPuertos;
MentorBitMotores DriverMotores;    // Este objeto controlará todos los motores
MentorBitPantallas DriverPantallas; // Este objeto manejará la OLED
MentorBitVL53 laser;              // Objeto para el sensor de distancia láser (I2C)

// --- DEFINICIÓN DE PINES (AJUSTA SEGÚN TUS CONEXIONES REALES) ---
// Utiliza los nombres de pines que te proporcione la documentación de MentorBit y del módulo expansor.

// Pin para el Sensor IR de entrada
#define PIN_IR miModuloPuertos.PUERTO_GENERICO_1_DIGITAL_2

// Pin para el Micro Servo SG90 (puerta auxiliar)
#define SERVO MentorBitMotores::SERVOMOTOR_1

MentorBitIR miIR_Entrada(PIN_IR); // Objeto para el sensor IR de entrada


// --- CONSTANTES Y VARIABLES GLOBALES ---
const int UMBRAL_DISTANCIA_COCHE = 40; // Distancia en mm para detectar coche aparcado (85cm si no hay objeto). ¡AJUSTA ESTE VALOR!
const unsigned long TIEMPO_MOVIMIENTO_PUERTA = 4000; // Tiempo en ms que tarda la puerta en abrir/cerrar
const unsigned long TIEMPO_PUERTA_ABIERTA = 5000; // Tiempo en ms que la puerta permanece abierta

// Número de pasos para el motor para abrir/cerrar completamente
const int PASOS_MOTOR_GARAGE = 300;

// Estados de la puerta del garaje
enum EstadoPuerta { CERRADA, ABRIENDO, ABIERTA, CERRANDO };
EstadoPuerta estadoActualPuerta = CERRADA;
unsigned long tiempoUltimoCambioEstadoPuerta = 0; // Para gestionar temporizadores

// --- VARIABLES PARA EL PULSADOR DE LA PUERTA AUXILIAR ---
bool puertaAuxiliarAbierta = false; // Estado de la puerta auxiliar (false = cerrada, true = abierta)
bool lastButtonStateDigital = HIGH; // Estado anterior del pulsador digital (HIGH por INPUT_PULLUP)
unsigned long lastDebounceTimeDigital = 0; // Última vez que se detectó un cambio válido en el pulsador digital
const unsigned long DEBOUNCE_DELAY = 50; // Retardo en ms para el anti-rebotes

// --- FUNCIONES AUXILIARES ---

void establecerColorRGB(int r, int g, int b) {
    miMentorBit.encenderRGB(r, g, b);
}

// Función para actualizar la pantalla OLED
void actualizarOLED(String linea1, String linea2 = "", String linea3 = "", String linea4 = "") {
    DriverPantallas.oled.clearDisplay(); // Limpia la pantalla
    DriverPantallas.oled.setCursor(0, 0); DriverPantallas.oled.print(linea1);
    DriverPantallas.oled.setCursor(0, 10); DriverPantallas.oled.print(linea2);
    DriverPantallas.oled.setCursor(0, 20); DriverPantallas.oled.print(linea3);
    DriverPantallas.oled.setCursor(0, 30); DriverPantallas.oled.print(linea4);
    DriverPantallas.oled.display(); // Muestra el contenido en la pantalla
}

void setup() {
    Serial.begin(9600);
    Serial.println("Iniciando Guardián del Garaje...");

    // Inicializar sensor IR de entrada
    pinMode(PIN_IR, INPUT);

    // Inicializar servo
    DriverMotores.inicializarServo(SERVO);
    DriverMotores.moverServo(SERVO, 0); // Puerta auxiliar cerrada al inicio (0 grados)

    // Inicializar LED RGB
    miMentorBit.apagarRGB();

    // Inicializar pantalla OLED
    DriverPantallas.inicializarOLED();
    // Configuramos el tamaño del texto
    DriverPantallas.oled.setTextSize(1);
    // Configuramos el color del texto
    DriverPantallas.oled.setTextColor(SSD1306_WHITE);
    actualizarOLED("Garaje Inteligente", "Iniciando...");
    delay(2000);

    // Inicializar sensor de distancia láser
    laser.begin();
    actualizarOLED("Garaje Inteligente", "Listo para operar");

    establecerColorRGB(0, 255, 0); // Verde - Listo
    delay(1000);
}

void loop() {
    // --- 1. Detección de Vehículos y Control de Puerta Principal ---
    bool vehiculoEnEntrada = miIR_Entrada.objetoPresente(); // true si hay objeto/vehículo
    float distancia_coche_garaje = laser.leerDistancia(); // Distancia en mm al coche aparcado

                    Serial.println(vehiculoEnEntrada);
                Serial.println(miIR_Entrada.objetoPresente());


    // Manejo de estados de la puerta principal del garaje
    switch (estadoActualPuerta) {
        case CERRADA:
            if (vehiculoEnEntrada) {
                Serial.println("Vehiculo detectado");
                // Verificar si hay espacio en el garaje
                if (distancia_coche_garaje > UMBRAL_DISTANCIA_COCHE) { // Plaza libre
                    Serial.println("Abriendo puerta...");
                    actualizarOLED("Abriendo Puerta...", "Vehiculo Detectado");
                    establecerColorRGB(255, 255, 0); // Amarillo - Abriendo
                   
                    // --- Lógica para mover motor paso a paso para abrir ---
                    // Arrancamos el motor paso a paso 300 pasos en una dirección
                    DriverMotores.moverMotorPP(300, 0);
                    delay(2); // Controla la velocidad de los pasos


                    estadoActualPuerta = ABRIENDO;
                    tiempoUltimoCambioEstadoPuerta = millis();
                } else {
                    Serial.println("Garaje Ocupado. No se puede abrir.");
                    actualizarOLED("Garaje Ocupado!", "Dist: " + String(distancia_coche_garaje) + "mm");
                    establecerColorRGB(255, 0, 0); // Rojo - Ocupado
                }
            } else {
                // Si no hay vehículo en entrada y puerta cerrada, mostrar estado normal
                actualizarOLED("Garaje Cerrado", "Plaza Libre: Si");
                establecerColorRGB(0, 255, 0); // Verde - Listo/Cerrado
            }
            break;

        case ABRIENDO:
            if (millis() - tiempoUltimoCambioEstadoPuerta >= TIEMPO_MOVIMIENTO_PUERTA) {
                Serial.println("Puerta Abierta.");
                actualizarOLED("Puerta Abierta", "Esperando cierre...");
                establecerColorRGB(0, 0, 255); // Azul - Abierta
                estadoActualPuerta = ABIERTA;
                tiempoUltimoCambioEstadoPuerta = millis(); // Reinicia temporizador para el cierre automático
            }
            break;

        case ABIERTA:
            if (millis() - tiempoUltimoCambioEstadoPuerta >= TIEMPO_PUERTA_ABIERTA) {
                Serial.println("Cerrando puerta...");
                actualizarOLED("Cerrando Puerta...", "");
                establecerColorRGB(255, 255, 0); // Amarillo - Cerrando
               
                // --- Lógica para mover motor paso a paso para cerrar ---
                DriverMotores.moverMotorPP(300, 1);
                delay(2);

                estadoActualPuerta = CERRANDO;
                tiempoUltimoCambioEstadoPuerta = millis();
            }
            break;

        case CERRANDO:
            if (millis() - tiempoUltimoCambioEstadoPuerta >= TIEMPO_MOVIMIENTO_PUERTA) {
                Serial.println("Puerta Cerrada.");
                actualizarOLED("Garaje Cerrado", "Plaza Libre: Si");
                establecerColorRGB(0, 255, 0); // Verde - Cerrado
                estadoActualPuerta = CERRADA;
            }
            break;
    }

    // --- 2. Control de Acceso Auxiliar (Servo SG90 con Pulsador Integrado) ---
    int reading = digitalRead(miMentorBit.PULSADOR_PULLUP_DIGITAL);

    // Si el estado del pulsador ha cambiado Y ha pasado suficiente tiempo para el debounce
    if (reading != lastButtonStateDigital && (millis() - lastDebounceTimeDigital > DEBOUNCE_DELAY)) {
        lastDebounceTimeDigital = millis(); // Actualiza el tiempo del último cambio

        // Si el pulsador está presionado (LOW, por INPUT_PULLUP)
        if (reading == LOW) {
            // Alternar estado de la puerta auxiliar
            if (puertaAuxiliarAbierta) { // Si la puerta está abierta, la cerramos
                DriverMotores.moverServo(SERVO, 0); // Cerrar a 0 grados
                Serial.println("Puerta auxiliar cerrada por pulsador.");
                puertaAuxiliarAbierta = false;
                actualizarOLED("Puerta Auxiliar", "Cerrada!", "", "");
            } else { // Si la puerta está cerrada, la abrimos
                DriverMotores.moverServo(SERVO, 90); // Abrir a 90 grados
                Serial.println("Puerta auxiliar abierta por pulsador.");
                puertaAuxiliarAbierta = true;
                actualizarOLED("Puerta Auxiliar", "Abierta!", "", "");
            }
        }
    }
    lastButtonStateDigital = reading; // Guarda el estado actual como el último estado

    // --- 3. Monitoreo de Ocupación del Garaje (Sensor Láser) - Actualización Continua ---
    // Esta sección actualiza la distancia y estado de ocupación de la plaza en la OLED
    // de forma continua, incluso si la lógica de la puerta no está en acción.

    actualizarOLED(
        (estadoActualPuerta == CERRADA) ? "Garaje Cerrado" : (estadoActualPuerta == ABRIENDO ? "Abriendo Puerta..." : (estadoActualPuerta == ABIERTA ? "Puerta Abierta" : "Cerrando Puerta...")),
        (estadoActualPuerta == CERRADA) ? "Plaza Libre: Si" : (estadoActualPuerta == ABRIENDO ? "Vehiculo Detectado" : (estadoActualPuerta == ABIERTA ? "Esperando cierre..." : "")),
        "Dist: " + String(distancia_coche_garaje) + "mm",
        (distancia_coche_garaje > 0 && distancia_coche_garaje <= UMBRAL_DISTANCIA_COCHE) ? "Coche Aparcado!" :
        (distancia_coche_garaje == 0) ? "Sensor Fuera Rango" : "Plaza Libre"
    );
   
    delay(300);
}
Vistas
1 Número de vistas
1 Vistas de miembros
0 Vistas públicas
Acciones
0 Gustos
0 No me gusta
0 Comentarios
Compartir en redes sociales
Compartir enlace
Compartir por correo

Por favor iniciar sesión para compartir esto webpage por correo.