DrowsGuard
Documentación técnica

Arquitectura de DrowsGuard

DrowsGuard es un sistema IoT de detección de microsueños al volante. Combina visión por computadora, señales fisiológicas e inercia en un único puntaje de riesgo, procesado en el borde sobre una Raspberry Pi y visualizado en la nube en tiempo real. Este documento detalla cada capa: percepción, procesamiento, comunicación, datos y presentación.

Visión general

El flujo de datos sigue cuatro etapas encadenadas:

Percepción
Cámara, pulso, inercia
Procesamiento
EAR, PERCLOS, BPM, riesgo
Comunicación
Supabase, MQTT
Presentación
Panel web en vivo

El procesamiento ocurre en el vehículo (edge computing) para minimizar la latencia de la alerta. La nube solo recibe el resultado y permite visualizar, historizar y enviar órdenes remotas al actuador.

1. Capa de percepción

Tres sensores capturan el estado del conductor:

Cámara Raspberry Pi V2.1 (Sony IMX219)

Captura video a 320×240 a través del bus CSI-2 usando libcamera/picamera2, que aprovecha el ISP por hardware para reducir el uso de CPU. Sobre cada cuadro se ejecuta detección facial y ocular. En 32 bits (armhf) MediaPipe no está disponible, por lo que se usa OpenCV con cascadas Haar, incluyendo una cascada específica para ojos con gafas.

MAX30102 (sensor de pulso PPG)

Mide fotopletismografía con LEDs rojo e infrarrojo a 25 Hz (promediado por hardware). A partir de la señal IR se estima la frecuencia cardíaca (BPM) y la variabilidad (HRV/SDNN). El sistema detecta automáticamente si hay dedo apoyado: sin contacto, reporta el estado "sin dedo" en lugar de inventar valores.

MPU6050 (acelerómetro y giroscopio)

Entrega aceleración en los tres ejes a ±2g. Se filtra con un Kalman 1D por eje para eliminar ruido sin introducir retraso. La suma de cambios entre lecturas (jerk) detecta correcciones bruscas del volante o cabeceos; una sacudida muy fuerte eleva el riesgo a alto de inmediato.

2. Raspberry y conexiones (protoboard)

El núcleo es una Raspberry Pi 3 (ARM Cortex-A53, 1 GB RAM). Los dos sensores I2C comparten el mismo bus (SDA/SCL) y se diferencian por dirección; el buzzer y los LEDs se controlan por GPIO.

Componente Alimentación Tierra Señal / datos Dirección
MAX30102 (pulso) 3V3 (pin 1) GND (pin 6) SDA GPIO2 (pin 3) / SCL GPIO3 (pin 5) I2C 0x57
MPU6050 (acelerómetro) 3V3 (pin 17) GND (pin 9) SDA GPIO2 (pin 3) / SCL GPIO3 (pin 5) I2C 0x68
Buzzer activo - GND (pin 14) GPIO17 (pin 11) Salida digital
LED verde (activo) - GND vía resistencia 220 ohm GPIO22 (pin 15) Salida digital
LED rojo (alerta) - GND vía resistencia 220 ohm GPIO27 (pin 13) Salida digital
Cámara V2.1 (IMX219) - - Conector CSI-2 libcamera

Configuración del sistema operativo

  • Raspberry Pi OS (32 bits). I2C habilitado con raspi-config (dtparam=i2c_arm=on).
  • Cámara habilitada: camera_auto_detect=1 en config.txt; verificación con rpicam-hello.
  • Dependencias: OpenCV, numpy, smbus2, heartpy, paho-mqtt, supabase, python-dotenv.
  • El proceso corre como servicio systemd (drowsguard.service) con reinicio automático.

3. Capa de procesamiento (Python)

El software está organizado con principios SOLID y patrones de diseño. Cada sensor es una clase que hereda de una base abstracta (patrón Observer: notifica al motor en cada lectura).

Visión: EAR y PERCLOS

El Eye Aspect Ratio mide la apertura del ojo. PERCLOS es el porcentaje de cuadros con ojo cerrado en una ventana temporal; es el indicador de somnolencia más validado en la literatura. Un cierre sostenido se clasifica como microsueño.

Pulso: BPM y HRV

La librería heartpy filtra la señal PPG y calcula BPM y SDNN. Como respaldo se usa un detector de picos por umbral. El cómputo pesado corre en un hilo aparte para no bloquear el lazo de lectura.

Inercia: Kalman y jerk

Un filtro de Kalman escalar por eje estabiliza la aceleración. El jerk (cambio brusco) alimenta el riesgo y, si supera un umbral alto, dispara alerta inmediata.

Concurrencia

Cinco hilos independientes: cámara, pulso, acelerómetro, publicación MQTT y publicación Supabase. Un watchdog reinicia el proceso ante cuelgues. Un lock protege el bus I2C compartido.

4. Motor de riesgo y alertas

El motor de riesgo usa el patrón Strategy: una estrategia ponderada multivariable combina las tres señales en un puntaje 0-100.

Fórmula de puntaje

score = PERCLOS × 0.70 + BPM_anómalo × 0.20 + jerk × 0.10

  • Niveles: BAJO (0-29), MEDIO (30-49), ALTO (50-100).
  • PERCLOS alto basta para alcanzar nivel ALTO.
  • Una sacudida muy brusca fuerza nivel ALTO de inmediato.
  • En ALTO suena el buzzer (GPIO17) y parpadea el LED rojo (GPIO27).

El gestor de alertas (patrón Observer del motor) controla el actuador. Respeta el toggle del buzzer configurado desde el panel y atiende el comando de silencio para cortar la alarma al instante. Cada disparo se registra en la base de datos con su origen (automático o remoto).

5. Capa de comunicación

Supabase (tiempo real)

La Raspberry escribe cada lectura (aprox. cada segundo) en PostgreSQL vía la API de Supabase usando la clave service_role. El panel se suscribe con Supabase Realtime y recibe cada inserción al instante, sin polling. Un canal de comandos remotos permite activar o silenciar el buzzer desde la web.

ThingSpeak (MQTT)

En paralelo se publican las métricas a un canal de ThingSpeak por MQTT cada 15 segundos (mínimo del plan gratuito), útil para gráficas históricas y como segundo respaldo de telemetría.

6. Base de datos (PostgreSQL)

Cuatro tablas principales, todas protegidas con Row Level Security:

TablaPropósito
devicesDispositivos del usuario, estado en línea y toggle del buzzer.
sensor_readingsLecturas: BPM, PERCLOS, aceleración, riesgo, detección de rostro y dedo.
alertsHistórico de alertas con nivel y origen.
remote_commandsCola de órdenes desde la web (BUZZ / SILENCE).

La seguridad real la garantiza RLS: cada usuario autenticado solo accede a sus propios dispositivos y datos. La Raspberry usa la clave service_role para escribir sin sesión de usuario.

7. Frontend y panel

El panel está construido con Astro (renderizado estático) y componentes interactivos en React, estilizados con Tailwind CSS. Las gráficas usan Recharts. La autenticación (registro, login, recuperación de contraseña) la maneja Supabase Auth.

  • Medidor de riesgo en vivo con estados "sin rostro" y "sin dedo".
  • Gráficas en tiempo real de BPM, PERCLOS y aceleración.
  • Control remoto: activar alerta, silenciar y habilitar/deshabilitar el buzzer.
  • Gestión de múltiples dispositivos e histórico de alertas.

8. Despliegue

El backend corre en la Raspberry como servicio systemd con reinicio automático. El panel web se compila a archivos estáticos y se publica en Vercel. La base de datos y la autenticación viven en Supabase; ThingSpeak provee el canal MQTT.

¿Listo para verlo en acción?

Crea una cuenta y conecta tu dispositivo.

Crear cuenta