A Nerves-powered conference badge, first displayed at ElixirConf EU 2025. Featuring an e-ink display and a tiny onboard camera, this project is designed to showcase a fun use-case of Nerves.
Note
Do you want to learn how to write an e-ink driver and get some e-ink hardware to take home? I'm running a workshop at several upcoming conferences, based on this project. Check it out - ElixirConf US and CodeBEAM Europe
Feel free to contact me if you're interested or have any questions!
| Button | Press Type | Action |
|---|---|---|
| Red | Any | Capture an image and show it on the display |
| Black | Short | Cycle through the loaded slides |
| Black | Long (5s) | Power off (low power mode) |
Nerves Glam Cam is made of several components:
- Raspberry Pi Zero 2W
- Soleil board for power management, battery charging and sleep mode
- 4.2", 400x300 e-ink display (I used this one from Good Display)
- 24-pin e-ink SPI display adapter (I used this one from Good Display)
- Tiny MIPI-CSI2 camera (I used this OV5647-based one from AliExpress)
- Some 3D printed parts and some superglue. STEP files are available in the
mechanicaldirectory
It's a surprisingly small amount of code required to build this app and make it run. There's two areas which are not super trivial though:
The e-ink display contains a SSD1683 driver chip, and is controlled using an SPI
interface. The NervesGlamCam.EInk module handles initialization, configuring
parameters like dimensions and operating mode, writing pixel data to the display
buffer, and enabling power-saving sleep mode.
The device datasheet contains example code which served as the starting point for the software driver in this repo.
Images go through a standard processing pipeline to prepare them for display. The source of the images can be static images (such as the pre-rendered slides, which are just JPEG files) or dynamic images captured by the camera. First, an image is converted to black and white, then resized to fit the screen dimensions, and finally dithered using the Floyd-Steinberg algorithm. To handle dithering, I cross compiled the Rust-based dither tool by Efron Licht. Finally, the processed image is formatted to match the display driver requirements and written to the buffer for rendering.
If you've gone through the trouble of acquiring all the hardware, and want to run this on your own device:
export MIX_TARGET=soleil_rpi0_2or prefix every command withMIX_TARGET=soleil_rpi0_2. If you don't have the Soleil board for power management, you can also just use a target ofrpi0_2.- Set your WiFi credentials as environment variables,
NERVES_WIFI_SSIDandNERVES_WIFI_PASSPHRASE - Install dependencies with
mix deps.get - Create firmware with
mix firmware - Burn to an SD card with
mix burn
The first version as shown at ElixirConf EU 2025 was bare-bones (I threw it together in a weekend!). For the next conference, I'd like to make a few updates:
- Support 4-bit grayscale for nicer images (especially text and fonts)
- Better button debounce
- More static slides
- Make it more social and interactive!
Stay tuned... v2 coming at Goatmire in September 2025 👀






