AbortController cancelaba fetch de movimiento (F/B/L/R) antes de que
llegase al ESP32 si la latencia del proxy Synology era >150ms.
Resultado: algunos comandos (especialmente B y R) no alcanzaban el
servidor y el motor no respondia.
Cambios:
- Movimiento (F/B/L/R): sin AbortController, el fetch llega siempre
- Stop (S): mantiene AbortController para que la parada sea instantanea
- Heartbeat: 150ms → 300ms (margen para latencia de proxy ~100-200ms)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
object-fit:cover + width/height:100% en lugar de max-width/max-height
+ contain. El stream ahora llena toda la pantalla disponible con un
recorte minimo. Sin impacto en latencia: cambio puramente CSS.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Forzado v13 para verificar que el OTA del ESP8266 funciona
- Pitidos handshake alargados a 180ms para distinguirlos mejor
del "pitido largo" que sonaban antes (100ms eran muy cortos)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
setBufferSizes(512,512) rechazaba records TLS > 512 bytes durante la
descarga del binario. La primera OTA exitosa no usaba setBufferSizes.
Eliminadas todas las llamadas — buffers por defecto de BearSSL.
Se mantiene el scope block que libera el cliente de version.txt
antes de crear el cliente de descarga.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
setBufferSizes(512,512) en el cliente de descarga causaba que BearSSL
rechazase records TLS de datos > 512 bytes durante la descarga del
binario de ~400KB. Cambiado a setBufferSizes(4096,512):
- 4096 bytes entrada: suficiente para records TLS de datos
- 512 bytes salida: suficiente para peticiones HTTP
- El scope block del cliente de version.txt libera ~10KB antes,
dejando heap suficiente para este cliente mas grande.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix OTA ESP8266 (pitidos cada arranque):
- BearSSL ocupa ~20KB de heap. El cliente de version.txt y el cliente
de firmware.bin coexistian → sin heap suficiente → descarga falla.
- Ahora el primer cliente se destruye en su scope {} antes de crear
el segundo. setBufferSizes(512,512) reduce uso BearSSL durante descarga.
Idioma de pitidos:
- 2 pitidos: handshake OK, ambas placas conectadas y listas
- 3 pitidos: ESP32-CAM actualizandose via OTA
- 4 pitidos: ESP8266 actualizandose via OTA
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ESP32-CAM:
- handshakeTask() corre ahora en tarea FreeRTOS separada.
setup() termina de inmediato, el servidor web arranca sin bloqueos.
El watchdog de hardware ya no puede dispararse (antes setup()
bloqueaba hasta 30s con readStringUntil que no cedia el CPU).
ESP8266:
- Antes del flash OTA, fuerza ENA=ENB=0 e IN1-IN4=LOW para reducir
el glitch de pines GPIO durante el proceso de escritura en flash.
(La solucion definitiva es resistencias pull-down en ENA/ENB.)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Problema raiz: el bootloader ROM del ESP32 emite logs a 115200 baud.
Al recibirlos a 9600 baud en el ESP8266 salen bytes aleatorios, alguno
de los cuales puede ser F/B/L/R (mover ruedas) o '!' (activar espReady).
Solucion: handshake con string de 2 chars "GO\n" / "OK\n":
- ESP32-CAM envia "GO\n" cada 300ms hasta recibir "OK\n"
- ESP8266 descarta todo el buffer al arrancar (basura del bootloader),
luego espera exactamente "GO\n" y responde "OK\n"
- En loop(), si ESP32 reinicia y manda "G", el ESP8266 repite el handshake
- Probabilidad de falso positivo: << 1 en millones vs ~40% del '!' solo
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
El LED ahora se enciende/apaga siempre con el boton, sin necesitar
que el stream este activo (antes requeria isStreaming==true).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ESP32-CAM:
- Envia '!' por Serial cuando el servidor esta listo
- Watchdog subido a 800ms (compatible con heartbeat 150ms)
ESP8266:
- waitForReady(): bloquea hasta recibir '!' (max 90s)
- loop(): ignora comandos hasta recibir '!' — sin movimiento al arrancar
- Si ESP32 se reinicia (OTA), detecta nuevo '!' y reanuda
Web (index.html):
- Heartbeat: reenvio del comando de movimiento cada 150ms mientras tecla/boton pulsado
- Mantiene vivo el watchdog y garantiza que el motor no pare solo
- carStop() limpia el intervalo y envia S al soltar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Watchdog FreeRTOS: si no llega comando F/B/L/R en 400ms envia S
automaticamente. Evita que el coche siga recto cuando se pierde
el comando de parada por latencia del proxy HTTPS.
- X-Accel-Buffering: no en stream_handler: desactiva buffering en
nginx/Synology. Elimina los microcortes del video MJPEG.
- Cache-Control: no-cache en el stream.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Añadido token de autenticacion a todas las peticiones Gitea
- version.txt y firmware.bin se solicitan con ?token=...
- Sin token el repo privado devuelve 404 y el OTA no arrancaba
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bugs corregidos:
- ESP32-CAM: binario anterior tenia FW_VERSION=2 aunque version.txt=3
(causaba bucle infinito de actualizaciones). Recompilado con v3 real.
- ESP8266: Serial.begin() movia a ANTES de checkOTA() para que el pitido
del ESP32-CAM llegue a tiempo. stopMotors() se llama primero para
evitar movimientos involuntarios.
- Timeout HTTP 5s → 10s para conexiones HTTPS externas lentas.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Interfaz completamente rediseñada: tema militar/racing oscuro
- Fondo con grid animado, tipografia Orbitron
- Barras de potencia estilo LED (6 segmentos verde→rojo)
- Botones angulares con glow rojo (traccion) y azul (camara)
- Flechas CSS puras, crosshair en centro de camara
- Esquinas HUD animadas sobre el stream
- camera_index.h regenerado desde data/index.html (4.6KB gzipped)
- gen_header.py para regenerar el header en el futuro
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 3 pitidos al actualizar ESP32-CAM (via Serial al buzzer)
- 4 pitidos al actualizar ESP8266 (directo al buzzer)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ESP32-CAM: servidor web, stream MJPEG, control motores via Serial
- ESP8266/Wemos D1: control motores DC, servos pan/tilt, buzzer
- OTA automatico en arranque via Gitea (HTTPS, WiFiClientSecure)
- Interfaz web rediseñada: full-screen, tema gaming, reconexion de stream
- partitions.csv con esquema dual OTA (2x1.75MB) para ESP32-CAM
- firmware/ con version.txt inicial para cada placa
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>