Spotify Desk Thing
A knob so I'd stop picking up my phone.
A knob so I'd stop picking up my phone.

Designed for Self (Concept)
Completed in 2026
Designed for Self (Concept)
Completed in 2026
Experiments
ESP32, Sensors
Experiments
ESP32, Sensors
Why?
Why?
Why?
With Spotify open, I reach for my phone to skip a song - and end up doom-scrolling instead. Even charging my phone became an excuse to get distracted, since the charger's in another room from where I actually listen.
I missed the iPod Shuffle for exactly this reason: no screen, nothing to scroll, just buttons. I wanted that back.
With Spotify open, I reach for my phone to skip a song - and end up doom-scrolling instead. Even charging my phone became an excuse to get distracted, since the charger's in another room from where I actually listen.
I missed the iPod Shuffle for exactly this reason: no screen, nothing to scroll, just buttons. I wanted that back.


The making.
The making.
The making.
Four interactions, deliberately chosen:
Rotary dial - play/pause + volume, the two I'd reach for most. Continuous motion felt more analog than a flat button.
Tactile buttons - skip + like. Leftover stock from a past project, so cost drove this one as much as feel did.
LED ring, not a screen - staying screen-less on purpose. Light and color carry song progress and feedback instead.
Four interactions, deliberately chosen:
Rotary dial - play/pause + volume, the two I'd reach for most. Continuous motion felt more analog than a flat button.
Tactile buttons - skip + like. Leftover stock from a past project, so cost drove this one as much as feel did.
LED ring, not a screen - staying screen-less on purpose. Light and color carry song progress and feedback instead.
Four interactions, deliberately chosen:
Rotary dial - play/pause + volume, the two I'd reach for most. Continuous motion felt more analog than a flat button.
Tactile buttons - skip + like. Leftover stock from a past project, so cost drove this one as much as feel did.
LED ring, not a screen - staying screen-less on purpose. Light and color carry song progress and feedback instead.




Built with Claude as a sounding board and debugging partner throughout - the calls on what to build were mine.
Over Bluetooth, it shows up as a wireless keyboard sending media shortcuts. Song progress needed a separate script polling Spotify directly, since Bluetooth alone has no idea what's playing.
Built with Claude as a sounding board and debugging partner throughout - the calls on what to build were mine.
Over Bluetooth, it shows up as a wireless keyboard sending media shortcuts. Song progress needed a separate script polling Spotify directly, since Bluetooth alone has no idea what's playing.
Tech Stack
Tech Stack
Tech Stack
MCU
ESP32 WROOM-32D
Input Dial
EC11 rotary encoder, play/pause + volume
Input Buttons
Tactile switches, skip + like
Feedback
16x WS2812B addressable LED ring
Connectivity
BLE HID keyboard emulation
Playback data
Spotify Web API via Spotipy (Python)
Firmware
Arduino / C++
Mechanical Design
Mechanical Design
An early 3D print to test fit - wiring routes, clearance, and where to put a charging door that stays hidden day-to-day.
It also caught a flaw: individually capped buttons rarely lined up straight. Fix - one printed part, three caps joined by a living hinge, so they sit in line by construction, not careful assembly.
An early 3D print to test fit - wiring routes, clearance, and where to put a charging door that stays hidden day-to-day.
It also caught a flaw: individually capped buttons rarely lined up straight. Fix - one printed part, three caps joined by a living hinge, so they sit in line by construction, not careful assembly.


Industrial Design
Industrial Design
Teenage Engineering's catalogue was the starting reference - considered, a little playful, not a project box. Sketches, then CAD.
Teenage Engineering's catalogue was the starting reference - considered, a little playful, not a project box. Sketches, then CAD.




Interactions
Interactions
Since there's no screen, every interaction needed its own honest answer in light. I coded two distinct animation behaviors into the LED ring, deliberately different from each other: a steady, breathing fill that tracks song progress in the background, and a sharper, momentary flash when skip or like is pressed. The difference is intentional - I wanted to feel the difference between "time is passing" and "I just did something," without ever looking down at the controller.
Since there's no screen, every interaction needed its own honest answer in light. I coded two distinct animation behaviors into the LED ring, deliberately different from each other: a steady, breathing fill that tracks song progress in the background, and a sharper, momentary flash when skip or like is pressed. The difference is intentional - I wanted to feel the difference between "time is passing" and "I just did something," without ever looking down at the controller.


Printed and assembled
Printed and assembled
Lots of iterations to get the fit just right. My Bambu A1 was working overtime.




Living with it.
Living with it.
It works: skip, like, play/pause, volume, no phone required. One gap left - the progress ring needs a laptop-run script to poll Spotify, so it's either wireless with the ring, or standalone without it. Closing that gap is next.
This project's real takeaway was fluency with a rotary input as a physical primitive - encoder reading, debouncing, real-time feedback.


