Power-cycle-friendly Nano boot and ESP relay handling

Nano / driver:
- No full on/off flip at boot; the first display() after boot is a forced
  full redraw instead, since the physical dot state is unknown
- Send READY when booted

ESP32:
- relayOn() only switches and waits when the relay was off, and waits for
  the Nano's READY (3 s timeout) instead of a fixed 3 s on every frame
- relayOff() ends Serial and releases the TX pin so the idle-high line no
  longer back-powers the Nano through its RX pin
- No display commands are sent while the relay is off
- Switching the relay on cancels a pending power-off countdown

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mangavalkandClaude Opus 5.5 committed 2026-10-13 00:12:28 +02:00
1 parent f7ffcf4ab3
commit 6e4d5e152b
8 files changed
+158 -68

No files matched your search

+9 -3
View File
@@ -8,8 +8,11 @@ logic.
## Behaviour
- **Boot:** the Nano loads the flip time from EEPROM and flips the whole display on and
then off.
- **Boot:** the Nano loads the flip time from EEPROM, sets up the pins and sends `READY`.
It doesn't flip any dots at boot. The relay powers the Nano, so it boots every time the
display is switched on.
- **First `display()` after boot** redraws every dot, because the Nano doesn't know which
state the dots were left in.
- **`display()`:** compares the new buffer with the last one that was shown and strobes
only the dots that changed.
- **Every 2 minutes** (`REFRESH_TIME`) it does a full redraw to fix dots that got stuck.
@@ -47,7 +50,10 @@ skipped and the next line starts clean. Coordinates are 2-digit **hex**. Color i
| `R` | `R` | Print the buffer as ASCII art on the serial port |
| `T` | `Tnnn` | Set the flip pulse length in µs (decimal, 50–2000), stored in EEPROM |
Invalid commands get a reply that starts with `ERR:` on the Nano's TX pin.
Replies on the Nano's TX pin:
- `READY` after booting. The ESP waits for it before sending the first frame.
- `ERR: ...` for invalid commands.
Example (what the ESP32 sends for one pixel and a refresh):