Repository navigation
Home
Now playing, transport, volume and album art on an ESP32 touch panel, talking to a Volumio player over the network. Firmware written in Rust for the family of ESP32 display boards: the pages, the player state and the Volumio client are written once and know nothing of the board; a board contributes its pins, its bring-up and a record of what it has; a controller chip has one driver however many vendors solder it down.
It grows out of rpi-waveshare28, the Raspberry Pi runtime for the Waveshare 2.8" SPI LCD. Peter of PIXIS, who tested that runtime on the PIXIS CB-1, asked for the same on the Waveshare ESP32-C5-Touch-LCD-2.8 and sent the first board. Thank you, Peter.
Where the project stands. Pre-alpha, and running on its first board. Every layer exists and is tested on a desktop: the pages, the application loop, the Volumio client, the album-art decoder, the drivers, the ESP-IDF platform crate. On the Waveshare ESP32-C5-Touch-LCD-2.8 the firmware boots, takes its network, its name and its player from a microSD card (Card setup), joins on 2.4 or 5 GHz, shows the player's face with its album art, and answers to a tap and a swipe. Not yet: sound, the settings page, a second board. Install takes you from the release to the face in ten minutes; Building is for building it yourself.
| Page | What it is for |
|---|---|
| Install | From nothing to the player's face: download, flash from Windows, macOS or Linux, write the card. Start here. |
| Connections | How the panel meets the player: the network, the optional serial cable, the board's headers. |
| Boards | The boards the project targets, what each carries, the pin map, and where each stands. |
| Building | The toolchain, the build, the image and the flash command. |
| Card setup | How to give the device its network and its player: one text file on a microSD card. |
flowchart LR
subgraph LAN
V[Volumio player<br/>REST on :3000, mDNS _Volumio._tcp] <-- Wi-Fi --> B
subgraph B[ESP32 display board]
direction TB
FW[firmware/<vendor>-<model><br/>pins, bring-up, capabilities] --> RT[runtime<br/>loop, gestures, Volumio client, art gate]
RT --> C[core<br/>pages, surface, state]
FW --> D[drivers<br/>touch, expander]
FW --> P[platform/esp-idf<br/>Wi-Fi, NVS, HTTP]
FW --> A[art<br/>fetch + decode thread]
C -- DrawTarget --> LCD[(panel)]
D -- hal::TouchSource --> RT
end
end
| Layer | Where | Holds |
|---|---|---|
| core | core/ |
The pages, the drawing surface, the player state model and the Volumio protocol types. No operating system, no chip, no vendor. |
| hal | hal/ |
The contract between the shared code and a device: the traits the core and the runtime talk to, and the capabilities record a firmware fills in. |
| drivers | drivers/<chip>/ |
One crate per controller chip, over embedded-hal, used by every board that carries the chip. Today the CH32V003 IO expander, the CST3530 touch controller and the ES8311 codec. |
| runtime | runtime/ |
The application: the loop as a state machine the device steps, the gesture derivation, the Volumio client, the album-art gate, the settings. no_std, generic over hal; the device owns threads, clock and I/O and calls in. |
| art | art/ |
Album art fetched and decoded (JPEG, PNG) on a thread, for any device with std and the memory. The simulator and an ESP32 on ESP-IDF share it. |
| platform | platform/esp-idf/ |
What every ESP board shares: the HTTP client, the configuration store over NVS, Wi-Fi and the network status the status page shows. |
| firmware | firmware/<vendor>-<model>/ |
The device. One crate per board, with its own target, toolchain and chip configuration; its build is the image you flash. |
| sim | sim/ |
The runtime on a desktop, in a window or straight to a PNG, talking to a real player. |
All of it exists today, with its tests; core, hal, runtime and the drivers also build for bare-metal RISC-V, which is how the check proves they are no_std. Finding the player by mDNS is not written yet: the player's address is a setting.
flowchart TB
core[core · no_std + alloc · pages, surface, state, protocol types]
hal[hal · no_std + alloc · traits + capabilities]
drivers[drivers/<chip> · no_std · embedded-hal]
runtime[runtime · no_std + alloc · the application]
art[art · std · the decode thread]
platform[platform/esp-idf · std + esp-idf-svc]
firmware[firmware/<vendor>-<model> · the device, the image]
sim[sim · the runtime on a desktop]
core --> hal
runtime --> core
runtime --> hal
art --> hal
drivers --> hal
platform --> hal
firmware --> runtime
firmware --> art
firmware --> drivers
firmware --> platform
sim --> runtime
sim --> art
Arrows read "depends on". Nothing above platform knows ESP-IDF; nothing in core, hal, runtime or the drivers knows std.

The companion is a client of the player over the LAN, as the Volumio apps are: it polls the player's state over its REST interface on port 3000 and sends transport and volume the same way, at the address you give it (finding it by mDNS, _Volumio._tcp, is on the list). Nothing is installed on the player. Connections has the detail and the one cable you might run.
Volumio ESP Companion is free and open source, designed, built and maintained by one developer in his own time. If it has earned a place beside your player:
Provided as-is under the MIT licence; sponsorship is a thank-you, not a purchase: it buys no priority, no features and no support agreement.