Update remaining docs for the second panel/board (missed in the previous commit)
Build and push server image / test (push) Successful in 42s
Build and push server image / build-and-push (push) Successful in 3m32s
Build and push server image / deploy (push) Failing after 1m28s

docs/hardware.md and firmware/README.md were updated already; this
catches the root README, docs/architecture.md, docs/widgets.md, and
server/README.md -- all still described the project as single-panel/
single-chip (800x480, ESP32-C6 only) even after image_pipeline.py
stopped hardcoding that.
This commit is contained in:
2026-08-04 20:50:29 +00:00
parent 474b92a282
commit fe5a2df074
4 changed files with 60 additions and 32 deletions
+11 -7
View File
@@ -3,14 +3,15 @@
Two independent pieces talk over HTTP or HTTPS (the server itself always
speaks plain HTTP; HTTPS means a reverse proxy in front of it, see
[`firmware/README.md`](../firmware/README.md#http-vs-https)) on the local
network: the ESP32-C6 firmware, and a small FastAPI server that sits
between it and Immich.
network: the ESP32 firmware (ESP32-C6 for the devkit/xiao boards,
ESP32-S3 for ee02 -- see [`docs/hardware.md`](hardware.md)), and a small
FastAPI server that sits between it and Immich.
```mermaid
sequenceDiagram
participant Immich
participant Server as ESPresso Frame Server
participant Frame as ESP32-C6 Frame
participant Frame as ESP32 Frame
Note over Frame: First boot / never provisioned
Frame->>Frame: Generate AP SSID/password, draw QR + config QR on panel
@@ -33,7 +34,7 @@ sequenceDiagram
Server->>Immich: List album assets / download preview / faces<br/>(once per photo widget on the panel)
Immich-->>Server: JPEG + face bounding boxes
Server->>Server: Composite every widget's region onto one canvas,<br/>then enhance/overlay/quantize (dither)/pack 4bpp once
Server-->>Frame: 192,000 raw bytes, streamed
Server-->>Frame: packed 4bpp bytes, streamed<br/>(192,000 for the 7.3" panel; sized to whichever<br/>panel this frame's device reports, see Frame.panel_type)
Frame->>Frame: Write to panel SPI buffer, compute CRC32
alt CRC unchanged since last physical refresh
Frame->>Frame: Skip refresh (nothing visually changed)
@@ -83,8 +84,9 @@ placement grid, and button-action dispatch.
once).
- Fetch the frame and write it into the panel's SPI buffer
(`epd_write_frame()`), computing a CRC32 as it streams -- never
buffering the full ~192KB frame in RAM. The panel driver refuses to
write a short/wrong-size response into the buffer at all, so a
buffering the full packed frame in RAM (~192KB for the 7.3" panel;
proportionally more for the 13.3" panel). The panel driver refuses
to write a short/wrong-size response into the buffer at all, so a
truncated fetch can't corrupt what's already there.
- Compare the new CRC32 against the last one that was actually
refreshed onto the panel (persisted in NVS). If it matches -- the
@@ -117,7 +119,9 @@ git history). Decoding a JPEG, then resizing/dithering/quantizing it to
the panel's 6-color palette, would be expensive on-device in both memory
and battery. Instead, the server does all of that with Pillow and hands
the frame a pre-packed, ready-to-stream buffer -- the device never
decodes an image at all.
decodes an image at all. The ee02 board's ESP32-S3 does have PSRAM, but
the same server-side design applies there too, for consistency and
battery reasons rather than because the C6's memory limit forces it.
## Why face detection isn't run on-device (or even on the server)