Engineering Fonix One: a tiny touchscreen music player

Designing and building an ESP32-powered Bluetooth player with a touchscreen UI and more than sixteen hours of playback.

I wanted a pocketable music player that wasn't my phone. It needed a real battery and none of the distractions.

The hardware

The device runs on the classic dual-core ESP32-WROOM-32 module, not one of the newer ESP32 variants. I chose it because it has Bluetooth Classic, which A2DP audio streaming needs. The module drives a 2.8" capacitive touchscreen, Bluetooth 4.2 audio out and a microSD slot. There is one physical button, for power and for switching the screen on and off.

The slot takes cards up to 2 TB. I customised the firmware's exFAT support for very large file systems to get there, and it works.

Constraints are the best design tool I know. The ESP32 has 520 KB of SRAM in total. After IRAM, FreeRTOS and the Wi-Fi and Bluetooth stacks, the firmware gets about 160 KB of it, and that forces decisions a Raspberry Pi never would.

Driving the display

A microcontroller UI stays fluid only if it never redraws what didn't change. The renderer keeps two dirty-rect lists and sends only the changed regions over SPI at 80 MHz.

One core for audio

The audio pipeline has core 0 to itself. The UI, Bluetooth, SPI, the file system, touch input and everything else run on core 1. A lot happens in that pipeline, and giving it a core of its own is what keeps playback smooth whatever the rest of the device is doing.

Fonix One plays MP3, FLAC, AAC, M4A, MP4, WAV and Opus. The 5-band EQ is built from biquad IIR filters in Q15 fixed-point.

Battery life

The 1,200 mAh cell gives more than sixteen hours of playback. Most of that comes from the screen, which switches itself off when it isn't needed. A tap wakes it.

What's next

The 3D print files for the case and the firmware will be made public after the Kickstarter launch.

Written by Alopex ↗Developer, maker, explorer. I build tools, games and systems for creators and players.