An iPod-inspired audiobook controller for children using ESPHome and LVGL on a tiny round display.
- Think:* Toniebox without expensive characters, Tigerbox without subscription
Built from the silence room in a spa, between Christmas and New Year's 2024.
While my wife was reading, I was playing with Claude on my phone (forgot my book). The problem: our kid wakes up very early, and you don't want to give her a real screen. But a speaker and "something fenced" to control it? That could work.
There are tons of commercial options for kids' audio players, but they all come with subscriptions and limited content libraries. Since we're already on Spotify with all her audiobooks, I had the idea to create this little device. No soldering required - just flash and go.
The entire project was built in conversation with Claude. I started with the regular Claude app to research the hardware and generate a detailed briefing document (included in this repo as briefing.md). Then I fed that briefing into Claude Code which implemented everything - from hardware config to the final UI. Pure ESPHome YAML, no C++ needed.
For the UI design, I used SquareLine Studio to visually design the circular interface with nested rings and shadows (project files in squareline/). Then I simply asked Claude to convert the exported C code to ESPHome LVGL YAML - it translated all the widget properties, colors, and layout perfectly.
NanoPod is a simple, child-friendly audiobook controller that connects to Music Assistant. Turn the wheel to browse, click to play - just like an iPod. No phone needed, no complicated apps.
- iPod-style navigation - Rotary encoder for browsing, click to select
- Touch gestures - Swipe left/right to browse, tap to select, swipe up to go back
- Cover art display - Shows album artwork from Music Assistant
- Progress indicator - Outer arc shows playback position
- Volume control - Turn wheel during playback to adjust volume
- Sleep mode - Display dims after inactivity
- OTA updates - Update firmware over WiFi
| Component | Specification |
|---|---|
| Display | GC9A01A 240x240 round LCD |
| MCU | ESP32-S3 (16MB Flash, 8MB PSRAM) |
| Input | Rotary encoder with push button |
| Touch | CST816S capacitive touchscreen |
| LEDs | 5x WS2812 RGB (optional) |
Where to buy: Elecrow | AliExpress | BerryBase
- ESPHome 2024.x or later
- Music Assistant server
- WiFi network
-
Clone the repository
git clone https://github.com/tobsch/nanopod.git cd nanopod -
Configure secrets
Create
secrets.yaml:wifi_ssid: "YourWiFiName" wifi_password: "YourWiFiPassword" ap_password: "fallback-ap-password" api_key: "your-esphome-api-key" ota_password: "your-ota-password" # Music Assistant ma_url: "http://your-music-assistant:8095" ma_player: "your_player_id"
-
Flash the firmware
esphome run nanopod.yaml
HOME (Artist/Series carousel)
│
├── Turn wheel / Swipe L/R → Browse artists
└── Click / Tap / Swipe down → Enter albums
ALBUMS (Album list)
│
├── Turn wheel / Swipe L/R → Browse albums
├── Click / Tap / Swipe down → Play album
└── Long press / Swipe up → Back to HOME
PLAYER (Now playing)
│
├── Turn wheel / Swipe L/R → Adjust volume
├── Click / Tap → Play/Pause
└── Long press / Swipe up → Stop & back to ALBUMS
- Center: Cover art and track info
- Outer ring: Playback progress (cyan arc)
- Volume bar: Appears when adjusting volume
NanoPod fetches content from Music Assistant using the library filter configured in nanopod.yaml:
substitutions:
ma_library_filter: "audiobook" # Filter for audiobook contentAdjust the filter to match how your audiobooks are tagged in Music Assistant.
Key settings in nanopod.yaml:
| Setting | Description |
|---|---|
sleep_timeout_ms |
Display sleep timeout (default: 60000ms) |
volume_display_ms |
Volume indicator display time (default: 2000ms) |
ma_library_filter |
Music Assistant content filter |
nanopod/
├── nanopod.yaml # Main ESPHome configuration
├── hardware-test.yaml # Hardware verification config
├── secrets.yaml # WiFi, API keys (create this)
└── images/ # Documentation images
The CrowPanel requires explicit power rail activation. This is handled in on_boot - ensure the power switches are configured correctly.
- Verify
ma_urlin secrets.yaml points to your MA server - Check that the
ma_playerID matches your speaker in Music Assistant - Ensure the ESP32 is on the same network as Music Assistant
The CST816S touch controller shares I2C with other peripherals. Ensure GPIO5 (INT) and GPIO13 (RST) are correctly configured.
MIT License - See LICENSE for details.
- Claude - AI pair programmer that built this entire project with me
- ESPHome - The foundation
- LVGL - Graphics library
- Music Assistant - Media backend
- Elecrow - Hardware
