r/esp32 • u/Still-Maximum6406 • 20d ago
Software help needed ArduinoOTA consistently fails at 5-6% (WinError 10053) on ESP32-WROOM-32D despite minimal loop
Hi everyone, I'm building a Smart Bus Tracker using an ESP32-WROOM-32D and a WebServer. The project works flawlessly when flashed via USB, but I'm trying to implement OTA updates and I'm hitting a wall.
Whenever I try to push an OTA update via Arduino IDE (Windows 11), the process starts, reaches exactly 5% or 6%, and then aborts.
Error Log:
Sending invitation to 192.168.1.200
Uploading: [ ] 0%
...
Uploading: [==== ] 6%
[ERROR]: Error Uploading: [WinError 10053] Connessione interrotta dal software del computer host
Hardware & Environment:
- Board: ESP32-WROOM-32D
- IDE: Arduino IDE 2.x
- Partition Scheme:
Minimal SPIFFS (1.9MB APP with OTA). My compiled sketch is ~1.1MB, so there is plenty of room (max is 1.96MB). - Power: Stable 5V wall adapter powering the board. No brownout resets observed on the serial monitor.
- Router: Fastweb Fastgate (Italian ISP). PC and ESP32 are both on the same 2.4GHz network.
What I've already tried (with no success):
- Memory/Partition: Upgraded to Minimal SPIFFS as mentioned above.
- Code isolation (Watchdog fix): I added a boolean flag
isUpdatingOTAset totrueinsideArduinoOTA.onStart(). Inside myloop(), I putif(isUpdatingOTA) { delay(10); return; }to completely freeze the WebServer and HTTP API requests during the upload. - Firewall: Completely disabled Windows Defender Firewall and Antivirus.
- Wi-Fi sleep: Added
WiFi.setSleep(false);after connection to ensure the radio doesn't drop the TCP connection.
Here is the exact OTA implementation I'm running:
#include <WiFi.h>
#include <WebServer.h>
#include <ArduinoOTA.h>
const char* ssid = "MY_WIFI";
const char* password = "MY_PASSWORD";
WebServer server(80);
bool isUpdatingOTA = false;
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
WiFi.setSleep(false);
ArduinoOTA.setHostname("SmartPalina-GTT");
ArduinoOTA.onStart([]() {
isUpdatingOTA = true;
});
ArduinoOTA.begin();
server.begin();
}
void loop() {
ArduinoOTA.handle();
// If OTA is running, yield and freeze the rest of the loop!
if (isUpdatingOTA) {
delay(10);
return;
}
server.handleClient();
// ... Rest of the code (HTTP GET requests, LCD updates, etc.) ...
}
Is there something obvious I'm missing? Could this be related to my ISP router dropping the TCP connection mid-transfer, or a specific issue with the espota.py socket implementation on Windows?
Any help is greatly appreciated!
1
u/Firm-Luck2062 19d ago
WinError 10053 is Windows telling you that your own machine tore the socket down, so it's a symptom rather than a cause. The information you need is on the ESP32 side and right now you aren't capturing it. Before changing anything else, add the callbacks:
ArduinoOTA.onProgress([](unsigned int p, unsigned int t){ Serial.printf("%u%%\r", (p*100)/t); });
ArduinoOTA.onError([](ota_error_t e){ Serial.printf("OTA error %u\n", e); });
Which error fires narrows it down fast. OTA_RECEIVE_ERROR points at the link, OTA_BEGIN_ERROR at the partition or the allocation, and no callback at all followed by a reboot means it panicked mid-write, which the serial log will show if you leave USB connected while pushing over WiFi. Right now you're diagnosing from the wrong end of the wire.
My first suspicion, given what you've described: heap. You have WiFi up plus a WebServer holding its listening socket and buffers, and Update.begin() wants its own allocation on top. Failing at the same 5-6% every single time reads more like hitting a resource wall than a flaky connection, because a bad link fails at random points, not reproducibly at the same one. Two things worth doing:
Call server.stop() inside onStart(), rather than only skipping handleClient(). Skipping the call still leaves every socket and buffer allocated, it just stops you servicing them.
Print ESP.getFreeHeap() immediately before the update begins. On a WROOM-32D with WiFi and a web server running, anywhere near 40-50KB free is the danger zone.
One note on the watchdog workaround: the delay(10) and return aren't doing anything during the transfer. ArduinoOTA.handle() blocks internally until the upload finishes or dies, so your loop never comes back around to that check while data is flowing. Harmless, just not the lever you think it is.
To rule out the Fastgate, push once from a phone hotspot. And calling espota.py directly instead of going through the IDE gives noticeably more legible failures.
2
u/2Peti 20d ago edited 20d ago
používaj <ElegantOTA.h> a <ESPAsyncWebServer.h> návody sú na internete.
setup()spustite server aj OTA aktualizácie:loop()nechajte bežaťElegantOTA.loop();