Problemas Conocidos
Fecha de análisis: 2026-06-29 Última actualización: 2026-06-29 Total: 14 issues — 4 críticos, 7 moderados, 3 leves
Correcciones Recientes ✅
| ID | Fecha | Descripción |
|---|---|---|
| — | — | — |
🔴 Críticos
HW-01 — digitalWrite(8, ...) en ISR corrompe SPI del display {#hw-01}
- Archivo:
rc5.cpp:134 - Descripción: La ISR
rc5_isr()escribe al pin 8 (digitalWrite(8, digitalRead(IR_PIN))), que esTFT_MOSI(SPI MOSI del display). Cualquier escritura a MOSI durante una transacción SPI activa corromperá los datos enviados al display, causando artefactos visuales o bloques de píxeles incorrectos. - Impacto: Alto — corrupción visual del display cada vez que se recibe una señal RC5.
- Mitigación actual: Ninguna.
- Solución propuesta: Eliminar
digitalWrite(8, ...). Es código de debug residual. Si se necesita monitorizar el pin IR, usar un pin GPIO libre o Serial.
HW-02 — delayMicroseconds(100) en ISR bloquea el sistema {#hw-02}
- Archivo:
rc5.cpp:123 - Descripción:
rc5_register()(llamada desde la ISR) ejecutadelayMicroseconds(100). Esto bloquea el core durante 100 µs en contexto de interrupción. Con la ISR disparándose a ~2-3 kHz (flanco CHANGE del receptor RC5), el overhead es ~20-30% del tiempo de CPU solo en el delay. - Impacto: Alto — pérdida de rendimiento, posibles pérdidas de interrupciones, latencia añadida al bucle principal.
- Mitigación actual: Ninguna.
- Solución propuesta: Eliminar el delay o usar
ets_delay_us()si es absolutamente necesario. Considerar refactorizar la decodificación RC5 para usar RMT (hardware) en lugar de GPIO interrupt.
CM-01 — Bucle infinito en client_start() si ESP-NOW falla {#cm-01}
- Archivo:
aux_module/client.cpp:68-71 - Descripción:
client_start()reintentaesp_now_send()en un buclewhilesin timeout. Si el módulo principal no está encendido, está fuera de rango, o el buffer ESP-NOW está lleno, el módulo auxiliar se cuelga permanentemente. - Impacto: Alto — el módulo auxiliar deja de responder, no se puede recuperar sin reset físico.
- Mitigación actual: Ninguna (el callback
data_sentintenta reenviar también). - Solución propuesta: Añadir un timeout (ej. 100 reintentos o 500 ms) y salir con log de error. También valorar añadir un contador de reintentos máximo en
data_sent.
SW-01 — pending_event sin volatile — race condition ISR↔main loop {#sw-01}
- Archivo:
control.cpp:10 - Descripción:
pending_eventes modificado porcontrol_set_pending_event()(llamada desde la cadena ISR de RC5) y leído encontrol_manage_pending_event()(bucle principal). Sinvolatile, el compilador puede cachear el valor en un registro y no ver actualizaciones de la ISR. - Impacto: Alto — eventos RC5 (STOP, RESET) pueden perderse o procesarse con latencia indeterminada.
- Mitigación actual: Ninguna.
- Solución propuesta: Declarar
static volatile enum RC5_EVENTS pending_event.
🟡 Moderados
HW-03 — MAC addresses hardcodeadas en el módulo auxiliar {#hw-03}
- Archivo:
aux_module/config.cpp:12-16,aux_module/client.cpp:40 - Descripción: Las MACs de los módulos (
64:E8:33:87:CB:ACpara START,34:B7:DA:F8:C9:9Cpara FINISH) y del módulo principal (40:4C:CA:F5:75:74) están hardcodeadas en el código fuente. Cambiar de hardware requiere recompilar y reflashear. - Impacto: Medio — requiere modificar código fuente para nuevo hardware.
- Mitigación actual: Ninguna.
- Solución propuesta: Usar un archivo de configuración en SPIFFS/LittleFS, o EEPROM, o pines de configuración por hardware.
SW-02 — long signed para valores de millis() — overflow a los ~24.8 días {#sw-02}
- Archivo:
stopwatch.cpp:8-16,screen.cpp:221 - Descripción: Variables de tiempo como
start_ms,last_time_ms,best_lap_ms, y parámetros descreen_update_timmings()usanlong(int32_t) en lugar deunsigned long(uint32_t). Cuandomillis()supera2^31(~24.8 días de uptime), estos valores se vuelven negativos al asignarse along. - Impacto: Medio — no crítico para competición (uptime < horas), pero es frágil.
- Mitigación actual: Ninguna.
- Solución propuesta: Cambiar todas las variables de tiempo a
unsigned long. La aritméticamillis() - startya es correcta con unsigned.
SW-03 — time_ms > 1000 congela el display el primer segundo de vuelta {#sw-03}
- Archivo:
screen.cpp:225 - Descripción: La condición
if (time_ms == 0 || time_ms > 1000 || last_lap_ms == 0)impide actualizar el display cuando0 < time_ms <= 1000ylast_lap_ms != 0. Durante el primer segundo de cada vuelta, la pantalla muestra el tiempo de la vuelta anterior en lugar del cronómetro en marcha. - Impacto: Medio — el display muestra información incorrecta durante 1 segundo tras cada inicio de vuelta.
- Mitigación actual: Ninguna.
- Solución propuesta: Cambiar la condición a
time_ms > 0para que el display se actualice siempre que el cronómetro esté corriendo.
CM-02 — web_stop() sin rate-limit — posible flood SSE {#cm-02}
- Archivo:
web.cpp:348-351 - Descripción:
web_start(),web_lap(), yweb_reset()tienen rate-limit de 1 evento/segundo, peroweb_stop()tiene el rate-limit comentado. Siweb_stop()se llama múltiples veces en rápida sucesión, puede inundar la conexión SSE. - Impacto: Medio — posible flood de eventos al navegador.
- Mitigación actual: Ninguna (rate-limit comentado).
- Solución propuesta: Descomentar el rate-limit en
web_stop()para que coincida con las otras funciones.
MN-01 — Bucles busy-wait en botones sin timeout {#mn-01}
- Archivo:
control.cpp:69,81,90,98,104 - Descripción: Los 5 bucles
while (digitalRead(BTN))para debounce de botones no tienen timeout. Si un botón se queda atascado mecánicamente, el sistema se congela. - Impacto: Medio — sistema no responsivo si un botón falla.
- Mitigación actual: Ninguna.
- Solución propuesta: Añadir timeout (ej. 500 ms) con
millis()y salir del bucle aunque el botón siga pulsado.
SS-01 — Bucle busy-wait en stopwatch_check() del módulo auxiliar {#ss-01}
- Archivo:
aux_module/stopwatch.cpp:22-27 - Descripción: El bucle
while (!digitalRead(SENSOR_PIN))espera indefinidamente a que el sensor se libere. Si un robot se para justo delante del sensor, el módulo se bloquea. - Impacto: Medio — módulo auxiliar no responde si el sensor está bloqueado.
- Mitigación actual: Si
can_start == falsey pasan 1000 ms,can_startse restaura, pero el bucle sigue ejecutándose. - Solución propuesta: Añadir un timeout máximo al bucle (ej. 5 segundos). Superado ese tiempo, salir y registrar el evento como anómalo.
🟢 Leves
CM-03 — RC5 pairing no persiste (EEPROM comentado)
- Archivo:
rc5.cpp:114-115 - Descripción:
rc5_init()tiene el cuerpo comentado. La lectura/escritura de EEPROM para almacenar los comandos RC5 emparejados no se ejecuta. Al reiniciar, los comandos emparejados se pierden. - Impacto: Bajo — el pairing funciona durante la sesión, pero se pierde al reiniciar.
- Mitigación actual: Las constantes
DATA_STOP = 0yDATA_START = 1conrc5_stored_data[]inicializado a cero en BSS permiten funcionamiento básico. - Solución propuesta: Implementar persistencia en NVS (Non-Volatile Storage) del ESP32, más adecuado que EEPROM para ESP32-C3.
BL-01 — Typo en nombre de variable battey_blink_ms
- Archivo:
control.cpp:8 - Descripción: La variable estática
battey_blink_mstiene un typo (falta una 'r'). - Impacto: Bajo — cosmético, no afecta al funcionamiento.
- Mitigación actual: Ninguna.
- Solución propuesta: Renombrar a
battery_blink_ms.
DB-01 — Typo en nombre de función screen_update_timmings
- Archivo:
screen.h:31,screen.cpp:221 - Descripción: La función se llama
screen_update_timmingsen lugar descreen_update_timings(doble 'm'). - Impacto: Bajo — cosmético, no afecta al funcionamiento.
- Mitigación actual: Ninguna.
- Solución propuesta: Renombrar a
screen_update_timingsy actualizar todas las referencias.
Documento generado el 2026-06-29. Los issues se añaden y actualizan mediante /doc-review al auditar el código fuente.