Public Access
Fix shifted pictures: non-blocking Nano drawing, frame check, refresh settings
The Nano's periodic full redraw blocked for ~0.8 s. A frame that arrived meanwhile overflowed its 64-byte serial buffer; lost bytes in a bitmap shift the rest of the image (picture moved up), and diff frames never repaired it. - Nano: all drawing (frames, effects, the dot refresh) runs from update() in ~1 ms slices; the refresh pauses while a frame is received or shown - New commands: C (reply with the image checksum) and I (refresh minutes, EEPROM) - ESP32: NanoMonitor asks for the checksum after frames and sends the whole image again on a mismatch, missing answer or Nano restart; counts ERR replies. Periodic whole-image resync. - Settings: "Dot refresh" and "Image resync" intervals (settings v5, v4 records are migrated) - System tab: loop timing, free memory, frame check counts - test_driver: the real driver against a simulated panel Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
58a7cb03c2
commit
090c2bf8ae
45 files changed
+1265
-157
No files matched your search
@@ -6,7 +6,8 @@ See README.md for the overview.
|
||||
## Layout and build
|
||||
|
||||
- `platformio.ini` has the environments `nano`, `nano_ota`, `esp32` (OTA to 10.1.1.198),
|
||||
`esp32_usb` (COM11), and the PC test environments `test_nano` and `test_esp32`. The
|
||||
`esp32_usb` (COM11), and the PC test environments `test_nano`, `test_esp32` and
|
||||
`test_driver`. The
|
||||
sources are split with `build_src_filter` (`src/nano/`, `src/esp32/`).
|
||||
- `lib/BROSE9323/` is the shared driver. Its behaviour depends on build flags set in
|
||||
`platformio.ini`, not in the header:
|
||||
@@ -27,7 +28,7 @@ See README.md for the overview.
|
||||
The uploader only uses the Python standard library. Test it against a simulated
|
||||
bootloader before changing it.
|
||||
- After any change, build both targets (`pio run`) and run the tests
|
||||
(`pio test -e test_nano -e test_esp32`).
|
||||
(`pio test -e test_nano -e test_esp32 -e test_driver`).
|
||||
|
||||
## Constraints
|
||||
|
||||
@@ -36,7 +37,7 @@ See README.md for the overview.
|
||||
data in `PROGMEM`.
|
||||
- The ESP32 talks to the Nano on `Serial2` (owned by `NanoLink`, GPIO 17 TX / GPIO 16 RX).
|
||||
`Serial` (UART0/USB) is free for debug output. Never write debug text to `Serial2`: the
|
||||
Nano runs lines that start with s/S/F/D/P/B/R/T/G/N/E as commands.
|
||||
Nano runs lines that start with s/S/F/D/P/B/R/T/G/N/E/I/C as commands.
|
||||
- Open hardware TODOs are listed in the README `TODO` section. Update it when one is done.
|
||||
- The README is the overview; the documentation is in `docs/` (web UI, pages, Home
|
||||
Assistant, how it works, wiring, Nano over WiFi, recovery app). Screenshots:
|
||||
@@ -62,22 +63,28 @@ See README.md for the overview.
|
||||
- Line based and non-blocking: bytes are collected into a 64-character buffer and a
|
||||
command runs when `\n` arrives. Bitmap (`B`) pixel data is the exception. It is drawn
|
||||
while it arrives, so it can be longer than the buffer. Keep `loop()` free of busy-waits.
|
||||
- A full redraw (`display(true)`) blocks for about 0.5 s, which overflows the 64-byte
|
||||
serial receive buffer. Only run it when no data is expected: right after a `D`, or after
|
||||
2 s with no serial data. The ESP only sends a frame (ending with `D`) when the screen
|
||||
changes, mostly once a minute.
|
||||
- The driver never blocks while flipping: `display()` only starts a run, `update()` flips
|
||||
dots in slices of about 1 ms (frames, effects, and the periodic dot refresh from
|
||||
`startRefresh()`, which waits while a frame is received or shown). Anything that blocks
|
||||
longer than about 5 ms overflows the 64-byte serial receive buffer; lost bytes shift the
|
||||
rest of a bitmap. That was the "picture moved up" bug. `test_driver` checks the time per
|
||||
`update()` call with a simulated panel.
|
||||
- Flip time is stored in EEPROM as a magic word at address 0 and a `uint16_t` at
|
||||
address 2. Values outside 50–2000 µs are rejected.
|
||||
- The Nano only replies `READY` (at boot) and `ERR: ...`. There is no per-frame
|
||||
acknowledgement. The Nano's TX is wired to the ESP's RX (flashing over WiFi works), but
|
||||
every wait for a reply still needs a timeout.
|
||||
- The Nano replies `READY` (at boot), `ERR: ...` and `C xxxx` (checksum of its image, for
|
||||
`C`). There is no per-frame acknowledgement: the ESP paces frames by time.
|
||||
`nano_link/nano_monitor` reads the replies and sends `C` after frames;
|
||||
`logic/frame_check` decides (wrong/missing answer or `READY` while on: send the whole
|
||||
image again via `controller.pageChanged()`). Every wait for a reply needs a timeout.
|
||||
- Driver tests: `pio test -e test_driver` runs the real `BROSE9323.cpp` (Nano build)
|
||||
against `test/driver_mocks/` (Arduino, Adafruit GFX, a panel that decodes the pins).
|
||||
- Unit tests: `pio test -e test_nano` runs `test/test_nano/` on the PC with the fakes in
|
||||
`test/mocks/` (Arduino, EEPROM, and a `BROSE9323` that records calls). It needs gcc on
|
||||
PATH (Strawberry Perl provides it at `C:\Strawberry\c\bin`). Add a test for every
|
||||
protocol change. The mocks only implement what the Nano code uses, so extend them when
|
||||
new Arduino or driver functions are called.
|
||||
- The board environments have `test_ignore = *`, so test firmware is never uploaded. Plain
|
||||
`pio test` runs nothing; always pass `-e test_nano -e test_esp32`.
|
||||
`pio test` runs nothing; always pass `-e test_nano -e test_esp32 -e test_driver`.
|
||||
|
||||
## ESP32 structure (`src/esp32/`)
|
||||
|
||||
|
||||
Reference in new issue
Block a user