Overview
Physical controls for a more enjoyable media playback experience.
Features
- Responsive volume knob & mute button.
- Transport controls (play/pause, stop, FF/REW, skip tracks).
- Pair up with your favourite Bluetooth® speakers.
- Quick, physical connection (don't have to go through menu system to pair with keypad & speakers).
- Customizable controls/scheme.
- Customizable setup: Optionally connect USB hub/dock for added features, for example:
- mirror phone to TV w/HDMI out: Watch videos on a bigger screen
- add keyboard: Better typing experience for texts/emails.
- Solderless project.
Main hardware
Program your device
To get your RP2040 macropad to act as a media controller, it needs to:
- detect keypresses and changes in the knob position
- send out corresponding keyboard messages to the attached USB host device (ex: a phone).
My own implementation for this "media hub" is written for Adafruit's CircuitPython, and can be found here:
- 💾 MediaController project README (see MediaHub_AFMacropad). 🚀 Installation instructions.
Once your macropad is programmed (see above), the simplest solution is to connect it directly your phone (or PC, Mac, etc).
Pressing the keypad buttons will emulate pressing keyboard keys, and send them out to the USB host (attached phone). Similarly, turning the volume knob causes the microcontroller to send out a series of volume up/down keypresses as well.
By pairing your phone to Bluetooth® speakers, you will get more responsive (hopefully) control over the volume.
The next step up is to include a Bluetooth® audio transmitter like this one from Creative labs. The advantage of this setup is that you can keep the audio transmitter "permanently" paired with your favourite (nearby) speakers so that connecting a single USB cable immediately turns your phone+macropad into a media controller for your listening room.
Note that audio transmitters are typically designed for PCs/Macs - and so you might need to establish the transmitter/speaker pairing using software on a PC/Mac before it can be used with your phone.
This setup also requires a USB hub/dock like this one from Plugable now that 2 USB devices (audio transmitter + macropad) need to simultaneously connect to your phone.
Example hardware (optional)
If you are looking for a more complete setup, a well selected USB-C hub/dock can turn your phone into a much better connected "media station".
To build on the direct-pair solution (section above), I personally suggest using a Bluetooth® audio transmitter as a central component to the media station.
Additionally, you can leverage your USB hub's built-in connections like Ethernet, and HDMI out:
- Wiring up your media station with Ethernet/RJ45 is great in areas where WiFi is less reliable.
- Sending HDMI to your living room TV can make it easier to watch videos and share recent pictures with others.
Finally, many USB-C hubs support power delivery to charge up your phone while it is connected. Surely a bonus for some setups.
To hide all the cabling of the "media hub", you can search for enclosures called "cable management boxes". Some are made of plastic, some made from wood. I don't suggest getting metal boxes if you are planning to use your media hub with Bluetooth® speakers. Metal impairs wireless signals.
I personally found wooden boxes give a project a more solid feel (pleasant to use). You can even build your own if you don't like the available options.
Disable USB drive
By default, CircuitPython automatically mounts microcontrollers like the RP2040 Macropad as a USB drive. This can be a bit confusing/irritating to users that don't expect a drive to show up when connecting to a media controller.
To circumvent this auto-mount behaviour, CircuitPython provides the storage.disable_usb_drive() command, which should be added to the microcontroller boot.py file. For more information, see:
- Customizing USB Devices in CircuitPython (Section: CIRCUITPY Mass Storage Device)
- You might also want to check out section "Don't Lock Yourself Out!" (further below).
In his learn guide, Dan Halbert explains how you can re-enable the USB mount using a button press or by forcing the board to start in safe mode. Another alternative is to connect to the device using a serial terminal, switch over to CircuitPython's REPL mode, and run a command to rename/delete the boot.py file.
An example boot.py file is provided here (renamed to avoid accidental activation).
Optional IR receiver
On the side of the RP2040 macropad is a STEMMA-QT port (4-pin JST-SH) available for some additional expansion. Using this port, it is relatively straightforward to expand your media hub to support control through IR remote as well.
Simply connect an IR receiver module (#5939) as described in the "Pico-Swirly-5939" section of the note called "Build patterns: IR receiver variants". The code to activate the IR receiver is already present in the sample code for this project (see section: Program your device). It just needs to be activated (set ENABLE_IR = True).
This page (Media hub: Media control w/opt Bluetooth) was last updated on September 07, 2025.