ESP32-CAM: eliminada handshakeTask (fragmentaba heap durante 30s
con String objects, causando inestabilidad al manejar el coche)
ESP8266: sustituido waitForReady() por delay fijo de 20s + flush
de Serial + 2 pitidos. Sin WiFi, sin String, sin tareas extra.
Arquitectura identica a v1 que funcionaba, mas watchdog 1.5s.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ESP8266:
- Eliminado completamente WiFi, BearSSL, HTTPClient, ESPhttpUpdate
- Firmware pasa de 375KB a 240KB (sin stack WiFi)
- Sin interferencia de WiFi con analogWrite/PWM de motores
- Se mantiene: waitForReady(), 2 pitidos conexion, watchdog 1.5s
- Solo se actualiza por USB (el hardware cambia poco)
ESP32-CAM:
- OTA sin cambios, version -> 20
- Indicador OTA: 3 x Serial H1/H0 -> 3 flashes LED GPIO4
(el ESP8266 estaba en waitForReady() y no procesaba Serial)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
El handler 'G' en loop() empeoraba el problema:
el bootloader del ESP32 manda basura que incluye bytes 0x47 ('G'),
lo que disparaba un handshake falso y dejaba espReady=true
antes de tiempo, permitiendo que mas basura del bootloader
ejecutase backward().
Ahora: solo waitForReady() hace el handshake al arrancar.
Si el ESP32 se cuelga y reinicia, el watchdog de 1.5s (millis())
para los motores. Cuando el ESP32 termina de arrancar, el usuario
puede volver a manejar normalmente.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bug: en v16 se elimino if(!espReady)return del loop() y no se restauro
en v17. Resultado: bytes basura del bootloader ESP32 (ej 0x42='B') se
ejecutaban como backward() antes y despues del handshake.
Fixes:
- Restaurado bool espReady con guard if(!espReady)return en loop()
- Restaurado handler 'G' en loop() para reinicio del ESP32:
espReady=false + stopMotors() inmediato + nuevo handshake
- Watchdog ligero en ESP8266 (solo millis(), sin FreeRTOS):
si no llega comando de movimiento en 1.5s -> para motores
Evita que el coche siga moviendose si el ESP32 crashea
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Eliminados para diagnostico del problema de ruido electrico:
- Watchdog de motores (tarea FreeRTOS en ESP32)
- Handshake GO/OK bidireccional
- ESP8266 vuelve a delay fijo de 15s para esperar al ESP32
Si el problema de desconexion persiste con v16 -> es hardware (ruido L298N)
Si mejora -> alguna de estas tareas contribuia al problema
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
- 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>