Support both Nano bootloaders for flashing over WiFi

- Uploader sends 'FLASH <baud>' first; the ESP32 restarts the Nano and
  bridges at that baud rate, then answers OK
- --baud=auto (default) tries 57600 (old ATmegaBOOT) then 115200 (Optiboot)
- Optional nano_reset GPIO (NPN to Nano RESET) pulses reset after power
  on, needed for Optiboot which skips the bootloader after a power cycle
- Clear errors for outdated ESP32 firmware and missing wires
- README: bootloader table, reset wire, troubleshooting

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mangavalkandClaude Opus 5.5 committed 2026-10-13 00:44:35 +02:00
1 parent bea5b9daa1
commit cefb76c1ad
8 files changed
+220 -77

No files matched your search

+20 -4
View File
@@ -60,18 +60,29 @@ void relayOff()
pinMode(nano_tx, INPUT);
}
// Flash session started: power cycle the Nano so its bootloader runs, and talk to the
// Flash session started: restart 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()
// The old bootloader also starts after a power cycle; Optiboot only after a reset pulse.
void startNanoFlash(uint32_t baud)
{
if (relay_on)
relayOff();
delay(NANO_POWER_OFF_TIME);
nanoSerial.begin(NANO_BOOTLOADER_BAUD, SERIAL_8N1, nano_rx, nano_tx);
nanoSerial.begin(baud, SERIAL_8N1, nano_rx, nano_tx);
digitalWrite(relay, LOW);
if (nano_reset >= 0)
{
delay(NANO_RESET_DELAY);
digitalWrite(nano_reset, HIGH);
delay(NANO_RESET_PULSE);
digitalWrite(nano_reset, LOW);
}
// drop anything the Nano sent before its bootloader started
while (nanoSerial.available())
nanoSerial.read();
digitalWrite(relay, LOW);
}
// Flash session ended: switch off, the clock powers the Nano on again with the new firmware
@@ -312,6 +323,11 @@ void setup()
otaPanicMode = false;
pinMode(relay, OUTPUT);
if (nano_reset >= 0)
{
digitalWrite(nano_reset, LOW);
pinMode(nano_reset, OUTPUT);
}
relayOn();
display.begin(&nanoSerial);