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

+32 -11
View File
@@ -92,10 +92,11 @@ pio run -e nano_ota -t upload
What happens:
1. The uploader ([tools/nano_net_upload.py](tools/nano_net_upload.py)) connects to the
ESP32 on TCP port **2323**.
2. The ESP32 pauses the clock and switches the relay off for 1 second, then on again. This
restarts the Nano, and its bootloader starts.
3. The ESP32 switches its link to the bootloader's 57600 baud and passes bytes between
ESP32 on TCP port **2323** and tells it the bootloader's baud rate.
2. The ESP32 pauses the clock and switches the relay off for 1 second, then on again. If
the reset wire is fitted, it also pulses the Nano's RESET pin. This restarts the Nano,
and its bootloader starts.
3. The ESP32 switches its link to the bootloader's baud rate and passes bytes between
WiFi and the Nano.
4. The uploader writes the new firmware and reads it back to verify it.
5. When the uploader disconnects, the ESP32 switches the relay off. The clock powers the
@@ -108,24 +109,43 @@ The display goes dark for the duration of the upload, which takes a few seconds.
- The reply wire must be connected: Nano D1 (TX) → voltage divider → ESP32 GPIO 16. The
uploader needs the bootloader's answers.
- The ESP32 must be running firmware with the flash bridge (this version or newer).
- The Nano must have the **old bootloader** (the `nanoatmega328` board, 57600 baud), which
also runs at power-on. The newer Optiboot bootloader only runs after a reset-pin reset,
so the relay power cycle would not start it.
**Bootloaders**
Flashing the Nano's firmware never changes its bootloader. Both common Nano bootloaders
are supported:
| Bootloader | Baud | Starts after a power cycle | Reset wire |
|------------|------|----------------------------|------------|
| Old bootloader (ATmegaBOOT), the one this Nano has now | 57600 | Yes | Not needed |
| Optiboot ("new bootloader") | 115200 | No, only after a reset-pin reset | **Required** |
By default (`--baud=auto` in `upload_flags`) the uploader tries 57600 first and then
115200. Set `--baud=57600` or `--baud=115200` to skip the other attempt.
If you ever replace the bootloader with Optiboot:
- Fit the reset wire: ESP32 GPIO → 1 kΩ → base of an NPN transistor (e.g. 2N2222 or
BC547). Connect the collector to Nano RESET and the emitter to GND. Set `nano_reset` in
`src/esp32/libs.h` to that GPIO, for example `4`. The transistor keeps the Nano's 5 V
reset line away from the 3.3 V ESP32 pin.
- For uploads over USB, change `board` in the `nano` environment to `nanoatmega328new`.
**Settings**
- ESP32 IP address: `upload_port` in the `nano_ota` environment in `platformio.ini`. You
can add a port number: `10.1.1.198:2323`. For a one-time different address, use
`pio run -e nano_ota -t upload --upload-port 10.1.1.50`.
- Port, baud rate and power-off time: `NANO_FLASH_PORT`, `NANO_BOOTLOADER_BAUD` and
`NANO_POWER_OFF_TIME` in `src/esp32/libs.h`.
- Port, reset pin and timings: `NANO_FLASH_PORT`, `nano_reset`, `NANO_POWER_OFF_TIME` and
`NANO_RESET_DELAY` in `src/esp32/libs.h`.
**If it fails**
| Message | Cause |
|---------|-------|
| `can't connect to ...` | Wrong IP address, or the ESP32 is offline or running older firmware |
| `no answer from the Nano bootloader` | Reply wire missing, or the Nano has Optiboot |
| `can't connect to ...` | Wrong IP address, or the ESP32 is offline |
| `the ESP32 flash bridge didn't accept the request` | The ESP32 runs older firmware without the flash bridge. Flash it first (`esp32` or `esp32_usb`). |
| `no answer from the Nano bootloader` | Reply wire missing, or the Nano has Optiboot and the reset wire is missing |
| `bad reply to command ...` / `verify failed` | Connection problem. Try again. A failed upload can leave the Nano without working firmware, but the bootloader itself is never overwritten, so flashing again (over WiFi or USB) always fixes it. |
The ESP32 ends the session after 10 seconds without data, so the clock always resumes,
@@ -143,6 +163,7 @@ The ESP32 talks to the Nano on **UART2** (`Serial2`, 115200 baud). The ESP32's o
|-------|------|-------|
| GPIO 17 (TX2) | D0 (RX) | Display commands |
| GPIO 16 (RX2) | D1 (TX) | `READY` and `ERR` replies, and bootloader answers when flashing over WiFi. Use a 5 V → 3.3 V voltage divider (e.g. 1 kΩ / 2 kΩ), because the ESP32 is not 5 V tolerant. Without it, the ESP waits a fixed 3 s after power-on, and `nano_ota` doesn't work. |
| GPIO set in `nano_reset` | RESET (through an NPN transistor) | Optional, only needed to flash a Nano with Optiboot over WiFi. See [Bootloaders](#bootloaders). |
| GND | GND | Common ground |
| GPIO 13 | Relay input | Relay powers the panels and the Nano (`LOW` = on) |