Screeny is open-source firmware and software that turns a Tidbyt Gen 1 into a 30 fps display for generative art. Instead of rendering frames in the cloud, Screeny renders them on a computer on the local network and streams them straight to the panel. No cloud, no account, no subscription.
patches ──> art pipeline ──> encoder (best of 5 codecs, ≤ 1464 B) ──UDP/WiFi──> firmware ──> HUB75 panel
Firmware
no_stdRust on embassy and esp-hal, with the display on one ESP32 core and the network on the other.- Refreshes the 64×32 panel at 154 Hz with six bit planes, and dithers temporally to about a thousand levels per channel.
- Caps brightness so a laptop USB port can power it.
- Advertises itself over DNS-SD, sets up WiFi from the browser or a phone QR code, and takes over-the-air updates that roll back on their own if they fail.
Protocol
- One frame, one UDP datagram: an 8-byte header and at most 1,464 bytes of pixels.
- Nothing is retransmitted, every frame decodes on its own, and the newest frame wins.
- The sender tries five codecs on every frame — mostly adaptive palettes that shrink until the frame fits — scores each against a model of the panel, and sends the best. A clock frame is about 280 bytes.
screeny pipetakes raw RGB frames on stdin, so any program in any language can drive a panel.
Studio
- A single Rust binary: an axum server with the web UI compiled in, and an MQTT bridge to Home Assistant.
- Runs as a Home Assistant app, in Docker (amd64 or arm64), or from source. On a Raspberry Pi 4 it uses about half a core and 85 MB of memory.
- Each patch renders on its own thread, and a patch that stalls is replaced without taking the process down.
- Patches include clocks inspired by ClockClock 24 and the Vestaboard, a slow-motion flock, metaballs, raymarched solids, and a GPU-rendered procedural world.
The design docs cover the protocol, the architecture, and the research behind each decision. Read the story behind it in the blog post.