Flash the Nano over WiFi through the ESP32

- ESP32: NanoFlashBridge on TCP port 2323. A connection power cycles the
  Nano into its bootloader and bridges TCP <-> Serial2 at 57600 baud; the
  clock pauses during the session, 10 s idle timeout
- tools/nano_net_upload.py: STK500v1 uploader over TCP (standard library
  only), with sync retries, write and read-back verification. avrdude 6.3
  net: ports are broken on Windows, so avrdude is not used
- New nano_ota environment: pio run -e nano_ota -t upload
- README: usage, requirements, troubleshooting; TODO for hardware test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mangavalkandClaude Opus 5.5 committed 2026-10-13 00:35:28 +02:00
1 parent 8415dee347
commit bea5b9daa1
10 files changed
+438 -7

No files matched your search

+31 -1
View File
@@ -39,7 +39,7 @@ void relayOn()
if (relay_on)
return;
nanoSerial.begin(115200, SERIAL_8N1, nano_rx, nano_tx);
nanoSerial.begin(NANO_BAUD, SERIAL_8N1, nano_rx, nano_tx);
// drop old data (e.g. ERR replies) so only a new READY counts
while (nanoSerial.available())
nanoSerial.read();
@@ -59,6 +59,30 @@ void relayOff()
nanoSerial.end();
pinMode(nano_tx, INPUT);
}
// Flash session started: power cycle the Nano so its bootloader runs, and talk to the
// bootloader at its baud rate. The PC uploader keeps sending sync bytes until it answers.
void startNanoFlash()
{
if (relay_on)
relayOff();
delay(NANO_POWER_OFF_TIME);
nanoSerial.begin(NANO_BOOTLOADER_BAUD, SERIAL_8N1, nano_rx, nano_tx);
while (nanoSerial.available())
nanoSerial.read();
digitalWrite(relay, LOW);
}
// Flash session ended: switch off, the clock powers the Nano on again with the new firmware
void endNanoFlash()
{
relayOff();
// skip the frames that were missed while flashing
next_display = millis();
}
NanoFlashBridge nanoFlashBridge(NANO_FLASH_PORT, nanoSerial, startNanoFlash, endNanoFlash);
void turnPowerOff(uint32_t delay = 30000, bool _turn_hassio_power_off = false)
{
if(triggered_power_off == false)
@@ -269,6 +293,7 @@ void setup()
});
ArduinoOTA.begin();
nanoFlashBridge.begin();
do
{
@@ -441,6 +466,11 @@ void loop()
{
ArduinoOTA.handle();
mqtt.loop();
// While the Nano is being flashed, nothing else may talk to it
if (nanoFlashBridge.handle())
return;
updatePower();
wifiStatus = WiFi.waitForConnectResult() == WL_CONNECTED;