From b9bd18a56801eb7c43457d2ab0ba7d5135897fb4 Mon Sep 17 00:00:00 2001 From: Natxo1000 Date: Tue, 2 Jun 2026 14:49:11 +0200 Subject: [PATCH] =?UTF-8?q?firmware:=20v10=20=E2=80=94=20fix=20OTA=20ESP82?= =?UTF-8?q?66=20memoria=20+=20idioma=20de=20pitidos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- ESP8266/ESP8266.ino | 85 +++++++++++++++++++-------------- Esp32Cam/Esp32Cam.ino | 2 +- firmware/esp32cam/firmware.bin | Bin 1309296 -> 1309296 bytes firmware/esp32cam/version.txt | 2 +- firmware/esp8266/firmware.bin | Bin 411856 -> 411904 bytes firmware/esp8266/version.txt | 2 +- 6 files changed, 51 insertions(+), 40 deletions(-) diff --git a/ESP8266/ESP8266.ino b/ESP8266/ESP8266.ino index 8c1c497..1cda0c8 100644 --- a/ESP8266/ESP8266.ino +++ b/ESP8266/ESP8266.ino @@ -7,7 +7,7 @@ // ================================================================ // OTA CONFIG // ================================================================ -#define FW_VERSION 9 +#define FW_VERSION 10 #define GITEA_HOST "https://git.nacho.myds.me" #define GITEA_OWNER "Natxo" #define GITEA_REPO "Arduino-Car" @@ -57,47 +57,53 @@ static void checkOTA() { return; // sin WiFi, arranque normal } - BearSSL::WiFiClientSecure client; - client.setInsecure(); // cert Let's Encrypt/autofirmado — OK para LAN privada - HTTPClient http; - String base = String(GITEA_HOST) + "/" + GITEA_OWNER + "/" + GITEA_REPO + "/raw/branch/" + GITEA_BRANCH + "/firmware/esp8266/"; String token = "?token=" + String(GITEA_TOKEN); - http.begin(client, base + "version.txt" + token); - http.setTimeout(10000); - int code = http.GET(); - String body; - if (code == HTTP_CODE_OK) body = http.getString(); - http.end(); - - if (code == HTTP_CODE_OK) { - body.trim(); - int remoteVer = body.toInt(); - if (remoteVer > FW_VERSION) { - // 4 pitidos = ESP8266 actualizando - pinMode(buzzerPin, OUTPUT); - for (int i = 0; i < 4; i++) { - digitalWrite(buzzerPin, HIGH); - delay(150); - digitalWrite(buzzerPin, LOW); - delay(150); - } - delay(300); - - // Fuerza pines de motor a LOW antes del flash para minimizar glitch de GPIO - analogWrite(ENA, 0); analogWrite(ENB, 0); - digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); - digitalWrite(IN3, LOW); digitalWrite(IN4, LOW); - - BearSSL::WiFiClientSecure updateClient; - updateClient.setInsecure(); - ESPhttpUpdate.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); - ESPhttpUpdate.rebootOnUpdate(true); - ESPhttpUpdate.update(updateClient, base + "firmware.bin" + token); - // Si llega aquí, el update falló — continúa arranque normal + // ── Bloque de scope: libera el cliente BearSSL antes de la descarga ── + // BearSSL ocupa ~20KB de heap. Si los dos clientes coexisten el heap + // se agota y ESPhttpUpdate falla silenciosamente. + int remoteVer = 0; + { + BearSSL::WiFiClientSecure client; + client.setInsecure(); + client.setBufferSizes(512, 512); // buffers mínimos — suficiente para la respuesta + HTTPClient http; + http.begin(client, base + "version.txt" + token); + http.setTimeout(10000); + int code = http.GET(); + if (code == HTTP_CODE_OK) { + String body = http.getString(); + body.trim(); + remoteVer = body.toInt(); } + http.end(); + } // ← client y http se destruyen aquí, ~20KB liberados + + if (remoteVer > FW_VERSION) { + // 4 pitidos = ESP8266 actualizando + pinMode(buzzerPin, OUTPUT); + for (int i = 0; i < 4; i++) { + digitalWrite(buzzerPin, HIGH); + delay(150); + digitalWrite(buzzerPin, LOW); + delay(150); + } + delay(300); + + // Fuerza pines de motor a LOW antes del flash para minimizar glitch de GPIO + analogWrite(ENA, 0); analogWrite(ENB, 0); + digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); + digitalWrite(IN3, LOW); digitalWrite(IN4, LOW); + + BearSSL::WiFiClientSecure updateClient; + updateClient.setInsecure(); + updateClient.setBufferSizes(512, 512); // reduce heap BearSSL durante descarga + ESPhttpUpdate.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); + ESPhttpUpdate.rebootOnUpdate(true); + ESPhttpUpdate.update(updateClient, base + "firmware.bin" + token); + // Si llega aquí, el update falló — continúa arranque normal } WiFi.disconnect(); @@ -127,6 +133,11 @@ void waitForReady() { delay(50); while (Serial.available()) Serial.read(); // flush post-handshake espReady = true; + // 2 pitidos: conexión entre placas establecida + for (int i = 0; i < 2; i++) { + digitalWrite(buzzerPin, HIGH); delay(100); + digitalWrite(buzzerPin, LOW); delay(100); + } return; } buf = ""; diff --git a/Esp32Cam/Esp32Cam.ino b/Esp32Cam/Esp32Cam.ino index 6b63424..7f1760b 100644 --- a/Esp32Cam/Esp32Cam.ino +++ b/Esp32Cam/Esp32Cam.ino @@ -10,7 +10,7 @@ // ================================================================ // OTA CONFIG // ================================================================ -#define FW_VERSION 9 +#define FW_VERSION 10 #define GITEA_HOST "https://git.nacho.myds.me" #define GITEA_OWNER "Natxo" #define GITEA_REPO "Arduino-Car" diff --git a/firmware/esp32cam/firmware.bin b/firmware/esp32cam/firmware.bin index 878e88ca24b2d904cd6a8cd942ff7bd45889af08..77e9e996b2cc60a0c04b098fa2c871d3840b5dc0 100644 GIT binary patch delta 159 zcmezH#s9+>{|OruzN+#&ovzkffBCM~){`6l3AAi0{yDR_{k*Qj{uTEGTAw#wXuZJL zdV#6+0`t}jEb_*TE80I8vj8zG5VHX>I}mdKF((jn0Wmia^8hg~5c2^sKM)H5u^FLP<;j delta 159 zcmezH#s9+>{|OruV*O@@F8VPky7i5C{q|7v*kwz@k28sSU( diff --git a/firmware/esp32cam/version.txt b/firmware/esp32cam/version.txt index f11c82a..9a03714 100644 --- a/firmware/esp32cam/version.txt +++ b/firmware/esp32cam/version.txt @@ -1 +1 @@ -9 \ No newline at end of file +10 \ No newline at end of file diff --git a/firmware/esp8266/firmware.bin b/firmware/esp8266/firmware.bin index 9757547156eabcacb9431ad3db3e2857ad1eeddb..8c0b436417c4fc7e596dc4f61be3d58393ef12fe 100644 GIT binary patch delta 11141 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 Yf^4A0B>@BUrFcLqv-yk?9c1|b02QCjZU6uP delta 10942 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 b$b)VIv5#!=uwB77wTU3lIx$+blg0lB;2?IX diff --git a/firmware/esp8266/version.txt b/firmware/esp8266/version.txt index f11c82a..9a03714 100644 --- a/firmware/esp8266/version.txt +++ b/firmware/esp8266/version.txt @@ -1 +1 @@ -9 \ No newline at end of file +10 \ No newline at end of file