doc: Add a new section detailing recent mainline.py changes and their implications for hardware porting, including headline caching, firehose mode, and frame timing. #4

Merged
genewildish merged 1 commits from feat/arduino into main 2026-03-15 00:10:10 +00:00

View File

@@ -189,3 +189,60 @@ mainline.py does a lot of things that don't map directly to an ESP32 + TFT. Whic
### 5. SD card availability ### 5. SD card availability
All three boards have TF card slots but the doorbell firmware doesn't use them. A microSD card would be useful for caching fonts, pre-rendered glyph atlases, or translated headline buffers. **Is there an SD card in the board you'd want to target?** All three boards have TF card slots but the doorbell firmware doesn't use them. A microSD card would be useful for caching fonts, pre-rendered glyph atlases, or translated headline buffers. **Is there an SD card in the board you'd want to target?**
---
## Recent mainline.py changes and port implications
*Updated after merge of latest `main` — three new features affect the port calculus.*
### Local headline cache (`--refresh`)
mainline.py now caches fetched headlines to a JSON file (`.mainline_cache_{MODE}.json`) and skips network fetches on subsequent runs unless `--refresh` is passed. This is good news for an ESP32 port:
- **Faster boot.** The device could load cached headlines from flash/SD on power-up and start scrolling immediately, then refresh feeds in the background.
- **Offline operation.** If WiFi drops, the device can still display cached content.
- **Storage question.** A typical cache is ~200500 headlines × ~100 bytes ≈ 2050 KB of JSON. That fits comfortably in Board 3's 9 MB FAT partition or on SD. On Boards 1 & 2 (4 MB flash), it would need SPIFFS/LittleFS and would compete with app code for flash space.
**Recommendation:** If targeting Boards 1 or 2, confirm how much flash is left after the app partition. Board 3's `app3M_fat9M_16MB` partition scheme already has 9 MB of FAT storage — more than enough.
### Firehose mode (`--firehose`)
mainline.py now has a `--firehose` flag that adds a 12-row dense data zone at the bottom of the viewport, cycling rapidly (every frame) through raw headline text, glitch noise, status lines, and headline fragments. This is the most demanding new feature for an ESP32 port:
- **Frame rate.** The firehose zone redraws completely every frame at 20 FPS. On SPI displays (Boards 1 & 2), rewriting 12 rows × 320 or 480 pixels at 40 MHz SPI would consume a significant fraction of each 50 ms frame budget. On Board 3's RGB framebuffer, this is trivial.
- **Randomness.** Each firehose line calls `random.choice()` over the full item pool. On ESP32, `esp_random()` is hardware-backed and fast, but iterating the full pool each frame needs the pool in RAM.
- **Visual density.** At 320px wide (Boards 1 & 2), 12 rows of dense data may be illegible. At 800px (Board 3), it works.
**Recommendation:** Firehose mode is only practical on Board 3. On Boards 1 & 2, consider either dropping it or replacing it with a single-line ticker.
### Fixed 20 FPS frame timing
The scroll loop now uses `time.monotonic()` with a 50 ms frame budget (`_FRAME_DT = 0.05`) and a scroll accumulator instead of sleeping per scroll step. This is actually a better fit for ESP32 than the old approach — it maps cleanly to a `millis()`-based main loop:
```
// ESP32 equivalent pattern
void loop() {
uint32_t t0 = millis();
// ... render frame ...
uint32_t elapsed = millis() - t0;
if (elapsed < FRAME_DT_MS) delay(FRAME_DT_MS - elapsed);
}
```
**Estimated per-frame budgets:**
| | Board 1 (320×240) | Board 2 (320×480) | Board 3 (800×480) |
|---|---|---|---|
| Full-screen SPI flush | ~30 ms | ~60 ms | n/a (framebuffer) |
| Partial update (12 rows) | ~4 ms | ~4 ms | n/a |
| Remaining CPU budget (of 50 ms) | ~20 ms | ~0 ms (tight) | ~45 ms |
Board 2 at 20 FPS with a full-screen redraw each frame would have essentially zero headroom. Partial updates (dirty-rect tracking) would be mandatory.
### Updated feature priority question
Given the new features, the feature priority question (§3 above) gains two more items:
- **Firehose mode** — the dense data ticker at the bottom. Want it? It's only viable on Board 3.
- **Headline caching** — persist headlines to flash/SD for instant boot and offline fallback. Recommended regardless of board, but storage medium depends on board choice.