← All work

Creative hardware

In Residence

Five fictional artists. One small museum on my wall.

My role
Concept, software, and hardware integration
When
2025
Built with
Raspberry Pi, Python, Flask / Jinja, llama.cpp, SDXL Turbo / OnnxStream, ESP32
The Great Unknown, presented in Inkwell’s gallery.

The idea

I built In Residence to give generative art a place in my home. Five fictional artists inhabit a wall-mounted display. Each has a set of subjects, a visual style, and a writing voice; each new piece adds an image and a gallery note to the collection.

A Raspberry Pi coordinates local language and image models, the gallery, and a small circular artist display. I designed the personas and connected the software and hardware so the museum could keep making work between visits.

An object in the room

The screen holds the latest exhibition. Beside it, an ESP32 powers a 240 × 240 circular display: the artist orb. The Pi sends it the current persona and the stage of generation, giving the slow work of local inference a visible presence.

The build brought together 3D-printed parts, wiring, display testing, and installation on the board.

Download GIF
From printer to workbench to wall. The sequence ends on a photograph of the finished installation.

Meet the residents

I wrote five creative briefs in YAML. Each defines scene instructions, a fixed image style, a commentary voice, and a gallery palette. Weighted selection chooses an artist for each new piece.

The orb gives each artist its own display colors and label. Choose an artist and a stage of creation to try the eye, drawn here from the same routines I use on the ESP32.

  • Pierre

    Green terminal light, machine rituals, and imagined sacred spaces.

    Voice Reflects on memory and patterns as an introspective machine.

  • Inkwell

    Ink on off-white paper; mirrored forms and ambiguous figures.

    Voice Offers possible readings while leaving the interpretation open.

  • Deco-9

    Stepped towers, architectural symmetry, gold, and teal.

    Voice Thinks through balance, sightlines, and imagined buildings.

  • Bathys

    Deep-sea arrangements, sonar-like marks, and distant silhouettes.

    Voice Writes about echoes, distance, noise, and uncertainty.

  • Mycelia

    Branching networks, glowing hubs, and tendrils.

    Voice Follows growth, forks, and connections through the composition.

On the hardware

Pierre’s eye on the ESP32, stabilized from the bench recording.

Pierre, between pieces

The green eye belongs to Pierre. A close-up of the running display shows the small movements that give the hardware a character of its own.

Language generation sends a THINKING state; image synthesis sends DRAWING; saving a completed piece sends DONE. The main gallery can keep showing earlier work while the next piece is being made.

The display and artist orb in use.
The complete installation, including the Raspberry Pi and wiring.

From a brief to a piece

I separated scene composition, visual style, and commentary. That lets the subject change from piece to piece while retaining a recurring artist’s creative brief.

A Python background worker coordinates two requests to the local llama.cpp server, an SDXL Turbo subprocess, the saved collection, and the orb’s state.

  1. Compose and interpret

    The first language-model call proposes a title and scene. A second call writes a gallery note in the artist’s voice, using that title and scene.

  2. Render the image

    The artist’s fixed visual style is prepended to the scene. OnnxStream runs SDXL Turbo locally to produce the artwork.

  3. Keep the work

    After checking the render succeeded and the image exists, the worker saves the piece’s metadata and signals completion to the orb.

The writing follows the proposed scene, before the image is rendered. There is no visual critique pass: the image and its gallery note can diverge, as they do in The Great Unknown.

Small models, local hardware

Language generation uses a compact GGUF model served by llama.cpp. My documented Pi setup uses TinyLlama 1.1B Chat with Q4_K_M quantization, a 2,048-token context, and four CPU threads; the app can use whichever model the local server has loaded.

Image synthesis runs through OnnxStream with SDXL Turbo, configured for three steps at 512 × 512. Keeping inference on the Pi makes compute time part of the design: the museum creates work at its own pace.

Language
Two local model calls separate scene planning from the artist’s written voice.
Image
A fixed style prefix and a changing scene feed the diffusion process.
Interface
Flask serves saved work independently of the background generation thread.

Designing for a slow process

The worker makes one piece at a time, then waits 30 minutes before the next cycle. There is no promise of an exact refresh interval: generation takes its own time, and the browser shows new work on its next page load.

I use a temporary file and rename when saving collection metadata, so gallery requests do not read a half-written JSON file. Orb updates have short HTTP timeouts; a disconnected display does not abort the generation.

If generation raises an error, the worker logs it, resets the orb state, and waits until the next cycle. Recovery is intentionally basic in this installation: a stalled rendering process still needs intervention.

More workGybeMaps

Project image