Sistema de Control de Acceso - Bus Facultativo

1. Diagrama de Bloques Estructurado

flowchart LR %% Definición de Estilos classDef hardware fill:#e1f5fe,stroke:#0288d1,stroke-width:2px; classDef cloud fill:#fff3e0,stroke:#f57c00,stroke-width:2px; classDef ui fill:#e8f5e9,stroke:#388e3c,stroke-width:2px; classDef bypass fill:#ffebee,stroke:#d32f2f,stroke-width:2px; subgraph Autobus ["Unidad de Autobús (Hardware Local)"] direction TB RFID["Módulo Lector RFID / NFC"]:::hardware GPS["Sensores de Velocidad / GPS"]:::hardware ESP32["Microcontrolador ESP32"]:::hardware OLED["Pantalla OLED 0.96' (Mensajes/Saldo)"]:::hardware LEDS["Indicadores LED (Rojo / Verde)"]:::hardware SERVO["Molinete (Servomotor MG90S)"]:::hardware BYPASS["Circuito Bypass Analógico"]:::bypass RFID -- "Lee ID" --> ESP32 GPS -- "Telemetría" --> ESP32 ESP32 -- "Aprobado/Denegado" --> OLED ESP32 -- "Señal" --> LEDS ESP32 -- "PWM Normal" --> SERVO BYPASS -.->|"Override"| SERVO end subgraph Nube ["Infraestructura en la Nube"] direction TB FIREBASE[("Base de Datos / Autenticación\n(Firebase)")]:::cloud MQTT{"Broker MQTT"}:::cloud end subgraph Clientes ["Interfaces de Usuario y Control"] direction TB APP["App Móvil PWA (Cloudflare)\n(Consulta/Recarga)"]:::ui CENTRAL["Comando Central SICAB\n(Monitoreo/Dashboard)"]:::ui end %% Conexiones principales ESP32 <-->|"1. ID\n2. Perfil/Saldo"| FIREBASE ESP32 -->|"Velocidad/Estado"| MQTT MQTT -->|"Datos en vivo"| CENTRAL APP <-->|"Registros/Recargas"| FIREBASE

* El Circuito Bypass actúa de forma independiente al ESP32. En caso de pérdida de conexión o fallo del microcontrolador, se activa para mantener el servo abierto y permitir el flujo, hasta que se restablezca la señal principal.

2. Diagrama de Flujo del Sistema (ESP32)

flowchart TD classDef startEnd fill:#333,stroke:#333,stroke-width:2px,color:#fff; classDef process fill:#e1f5fe,stroke:#0288d1; classDef decision fill:#fff9c4,stroke:#fbc02d; classDef cloudAction fill:#e8eaf6,stroke:#3f51b5; classDef fail fill:#ffebee,stroke:#e53935; classDef success fill:#e8f5e9,stroke:#43a047; START([Inicio del Sistema]):::startEnd --> INIT[Inicializar ESP32, Sensores, RFID, OLED]:::process INIT --> CONN{¿Conexión a Internet / Firebase / MQTT?}:::decision CONN -- No --> BYPASS_CHK1{¿Activar Bypass?}:::decision BYPASS_CHK1 -- Sí --> OPEN_BY[Abrir Molinete mediante Hardware de Emergencia]:::fail OPEN_BY --> RECONN[Intentar Reconexión]:::process RECONN --> CONN CONN -- Sí --> LOOP[Bucle Principal]:::process LOOP --> PUB[Publicar Telemetría vía MQTT\nVelocidad, Estado]:::cloudAction PUB --> CHECK_BY{¿Circuito Bypass Activo por Operador?}:::decision CHECK_BY -- Sí --> HOLD[Mantener Servo Abierto]:::fail HOLD --> LOOP CHECK_BY -- No --> WAIT_RFID{¿Tarjeta RFID o Celular detectado?}:::decision WAIT_RFID -- No --> LOOP WAIT_RFID -- Sí --> READ_ID[Leer ID y Enviar a Firebase]:::cloudAction READ_ID --> FIREBASE_DEC{Firebase evalúa:\n¿Existe el Usuario y \nTiene Saldo > 0?}:::decision FIREBASE_DEC -- No --> DENIED[Mostrar 'Acceso Denegado' en OLED\nEncender LED Rojo]:::fail DENIED --> LOOP FIREBASE_DEC -- Sí --> CLASSIFY[Firebase devuelve Perfil:\nDocente/Estudiante/Discapacidad/Extra]:::process CLASSIFY --> DEDUCT[Descontar tarifa específica\nsegún el perfil]:::cloudAction DEDUCT --> ALLOWED[Mostrar 'Acceso Permitido' y Saldo\nEncender LED Verde]:::success ALLOWED --> OPEN_SERVO[ESP32 manda señal PWM\nAbrir Molinete MG90S]:::success OPEN_SERVO --> WAIT_PASS[Esperar paso del pasajero]:::process WAIT_PASS --> CLOSE_SERVO[Cerrar Molinete MG90S]:::process CLOSE_SERVO --> LOOP

* Firebase es quien toma la decisión de acceso en función del ID recibido, aplicando tarifas discriminativas y validando el saldo. El ESP32 es el ejecutor que acciona los LEDs, la pantalla y el Servo.

3. Interconexión de Pines GPIO y Bypass Analógico

flowchart TD classDef esp fill:#283593,stroke:#fff,stroke-width:2px,color:#fff; classDef rfid fill:#e8eaf6,stroke:#3f51b5; classDef oled fill:#e0f7fa,stroke:#00acc1; classDef gps fill:#fff3e0,stroke:#fb8c00; classDef leds fill:#fce4ec,stroke:#d81b60; classDef bypass fill:#ffebee,stroke:#e53935; classDef servo fill:#f1f8e9,stroke:#7cb342; ESP([Microcontrolador ESP32]):::esp subgraph Modulo_RFID ["RFID RC522 (SPI)"] MOSI[MOSI]:::rfid MISO[MISO]:::rfid SCK[SCK]:::rfid SDA[SDA / SS]:::rfid RST[RST]:::rfid end ESP -- "GPIO 23" --> MOSI ESP -- "GPIO 19" --> MISO ESP -- "GPIO 18" --> SCK ESP -- "GPIO 5" --> SDA ESP -- "GPIO 4" --> RST subgraph Modulo_OLED ["Pantalla OLED (I2C)"] OSDA[SDA]:::oled OSCL[SCL]:::oled end ESP -- "GPIO 21" --> OSDA ESP -- "GPIO 22" --> OSCL subgraph Modulo_GPS ["Sensores GPS (UART)"] TXG[TX]:::gps RXG[RX]:::gps end ESP -- "GPIO 16 (RX2)" --> TXG ESP -- "GPIO 17 (TX2)" --> RXG subgraph Modulo_LED ["Indicadores Visuales"] LEDV((LED Verde)):::leds LEDR((LED Rojo)):::leds end ESP -- "GPIO 25" --> LEDR ESP -- "GPIO 26" --> LEDV subgraph Sistema_Molinete_Bypass ["Control de Molinete y Bypass"] RELAY{Relé Selector\nMultiplexor}:::bypass GEN[Circuito Analógico\nGenerador PWM 555]:::bypass SW((Interruptor\nBypass)):::bypass SRV[Molinete\nServo MG90S]:::servo end ESP -- "GPIO 13 (PWM Normal)" --> RELAY SW -.->|"1. Enciende"| GEN SW -.->|"2. Conmuta"| RELAY GEN -->|"PWM Emergencia"| RELAY RELAY -->|"PWM Activo"| SRV