05. Arquitectura del sistema - diegogopa/Challenge-IOT GitHub Wiki
La arquitectura se organiza en las capas típicas de un ecosistema IoT: percepción, cómputo, actuación/notificación, conectividad, aplicación (tablero) y alimentación.
flowchart LR
subgraph PER[Percepción]
US[HC-SR04<br/>Nivel]
DHT[DHT22<br/>Temp / HR]
UV[GUVA-S12SD<br/>UV]
BMP[BMP180<br/>Presión]
end
subgraph CPU[Cómputo - ESP32 DevKit V1]
T1[Tarea de sensado<br/>FreeRTOS]
L[loop principal]
WS[Servidor web<br/>asíncrono]
end
subgraph ACT[Notificación in situ]
OLED[OLED SH1106]
BZ[Buzzer]
end
subgraph NET[Conectividad y aplicación]
AP[WLAN de la zona]
NAV[Navegador PC / celular<br/>Tablero de control]
end
PWR[Alimentación 5 V] --> CPU
US -- "TRIG GPIO5 / ECHO GPIO18" --> T1
DHT -- "1-Wire GPIO4" --> T1
UV -- "ADC GPIO34" --> T1
BMP -- "I2C 0x77" --> T1
L -- "I2C 0x3C" --> OLED
L -- GPIO33 --> BZ
WS -- "WiFi 2.4 GHz / HTTP" --> AP --> NAV
Si el navegador del wiki no renderiza el diagrama, se conserva la versión en texto:
HC-SR04 ──TRIG/ECHO directo──┐
DHT22 ─────────GPIO4──────────┤
GUVA-S12SD ────ADC GPIO34─────┤──► ESP32 ──► OLED (I2C 0x3C)
BMP180 ────────I2C 0x77───────┘ │ └──► Buzzer (GPIO33)
│
└──► WiFi ──► WLAN ──► Navegador (tablero)
Alimentación 5 V ──► ESP32 (3.3 V a sensores; 5 V al HC-SR04)
La WLAN no es una dependencia para la detección ni para las alertas físicas: si se pierde, el sensado, la OLED y el buzzer siguen funcionando.
El firmware separa tres flujos de ejecución que comparten datos a través de dos mutex:
flowchart TB
subgraph TS[Tarea de sensado - FreeRTOS, núcleo 1, cada 2 s]
A1[DHT22] --> A5
A2[BMP180 *] --> A5
A3[GUVA-S12SD] --> A5
A4[HC-SR04 mediana + EMA] --> A5
A5[Validación y contadores de falla] --> A6[Tendencia, tasa, evaporación, ΔP]
A6 --> A7[calcularEstado - fusión]
A7 --> A8[Eventos e histórico]
end
A8 -->|mutexDatos| D[("struct Datos<br/>eventos: 10<br/>historico: 60")]
D -->|snapshot| LP
D -->|copia| WS
subgraph LP[loop principal - cada 100 ms]
B1[Buzzer] --- B2[OLED *] --- B3[gestionarWiFi] --- B4[vigilarOLED *]
end
subgraph WS[Servidor web asíncrono - AsyncTCP]
C1["GET /"] --- C2["GET /data"] --- C3["GET /historico"] --- C4["POST /silenciar"]
end
* Los accesos al bus I2C (lectura del BMP180, refresco y verificación de la OLED) se serializan con un segundo mutex, mutexI2C, porque ambos dispositivos comparten SDA/SCL y se acceden desde tareas distintas.
-
Tarea de sensado (
tareaSensado, núcleo 1, prioridad 1, pila de 8 KB): adquiere, filtra, fusiona y clasifica. Es el "hilo diferente al principal" que exige el reto. -
Ciclo principal (
loop()): toma un snapshot de los datos y maneja buzzer, OLED, WiFi y verificación de la OLED. -
Servidor web (tarea interna de AsyncTCP): responde a los endpoints copiando los datos bajo
mutexDatos.
Sensores (HC-SR04, DHT22, GUVA-S12SD, BMP180)
↓
Adquisición en la tarea de sensado
↓
Validación de rangos y contadores de falla por sensor
↓
Nivel: mediana → % → EMA → tendencia y tasa de cambio
Ambiente: índice UV, índice de evaporación, variación de presión en 3 h
↓
Lógica de fusión con histéresis (calcularEstado)
↓
Escritura protegida (mutexDatos) + eventos + histórico
↓
┌──────────────┬──────────────┬─────────────────────────┐
▼ ▼ ▼ ▼
OLED Buzzer Monitor serie Servidor web → Navegador
- Cada ≈ 2.4 s la tarea de sensado lee los cuatro sensores.
- El HC-SR04 toma 5 muestras; con al menos 3 válidas calcula la mediana, la convierte a % y la suaviza con EMA.
- El DHT22, el BMP180 y el GUVA-S12SD se validan por rango; 3 ciclos malos seguidos activan la falla del sensor.
- Se calculan tendencia (cada 10 s), tasa de cambio (ventana de 5 min), índice de evaporación y variación de presión (ventana de 3 h).
- La lógica de fusión determina el estado; cada cambio de estado o de falla se guarda como evento.
- Cada minuto se guarda una muestra en el histórico (60 muestras).
- El ciclo principal actualiza la OLED y el buzzer, gestiona la reconexión WiFi y verifica la presencia de la OLED.
- El tablero consulta
/datay/historicocada 4 s.
| Estándar / referencia | Aplicación concreta en el proyecto |
|---|---|
| UML 2.5 (OMG) | Diagramas de clases, estados, secuencia y actividad (sección 7.12) |
| IEEE 802.11 b/g/n | Conexión del ESP32 a la WLAN en 2.4 GHz |
| NXP UM10204 — especificación I2C | Bus compartido OLED/BMP180 a 100 kHz, direcciones 0x3C y 0x77 |
| IETF RFC 9110 — HTTP | Endpoints del servidor, códigos 200/401/403/404/503 |
| IETF RFC 7617 — HTTP Basic Authentication | Autenticación del tablero |
| IETF RFC 8259 — JSON | Formato de /data y /historico
|
| JCGM 100:2008 (GUM) | Reporte de sesgo, error y desviación estándar en la calibración (sección 11) |
| OMS — Índice UV solar mundial | Categorías BAJA / MEDIA / ALTA / MUY ALTA / EXTREMA |
| FAO-56 / Hargreaves-Samani | Inspiración del índice de evaporación potencial (sección 8.9) |
| IEC 60529 | Referencia para discutir el grado de protección de la carcasa (sin certificación) |
| IEEE 315 / IEC 60617 | Simbología del esquemático (sección 6) |
No se declara una certificación formal del prototipo; los estándares se aplican en la medida en que existe evidencia en el diseño, la implementación o la validación.