ETHAN CROOKS

Raspberry Pi Bluetooth Receiver

2026-07-21

I’ve got a hifi setup at home - a turntable, amp and speakers. I can plug my phone in with a few cables, but I’d thought it would be good to connect to it via Bluetooth.

I could’ve bought a Bluetooth receiver, but I had a spare Raspberry Pi 3b with a perfectly serviceable Bluetooth chip sitting in a box doing nothing. It turned out to be a pretty fun project, especially since it’d been a while since I’d messed around with Python.

I’m writing this to note what worked and what tripped me up, so this is going to be pretty train-of-thought. Hopefully it’s helpful!

Setting Up

I started out by following a few guides to get the basic “speaker I can pair and connect to” setup working.

fdanis-oss - Using a Raspberry Pi as a Bluetooth® speaker with PipeWire introt - Bluetooth audio on a headless Raspberry Pi using BlueAlsa

I couldn’t get Pipewire+wireplumber to work on the first guide, so the second guide’s BlueALSA instructions was what I ended up using. If I tried again from the beginning I could probably figure it out now, but ALSA is fine for now.

The first guide included a Python script which acts as an “Agent” which accepts requests to pair new devices. This was ideal for me, since I could have my Pi turned off when I wasn’t using it, and I’d only need to turn it on for it to start accepting connections.

That Python script also pointed me towards the concept of D-Bus, which was how the BlueZ (the Bluetooth daemon) communicated with other stuff on the system.

  • D-Bus Specification, useful for the basic concepts
  • pydbus, a Python library to work with D-Bus objects. I could’ve worked more directly with GLib, but the Python object wrappers made it very nice to tinker with.
  • bluez man pages, once I had the basics down, I could work off the manuals directly.

After learning the basics of D-Bus, I could use busctl to prod at BlueZ’s interface.

DAC Hat

The Pi has a built in 3.5mm jack, which worked ok but was pretty noisy. I bought a DAC Pro hat which improved things a bunch. It also has a convenient pass-through for the GPIO pins.

I was worried about the Blinkt LEDs using the same GPIO pins as the DAC hat. As it turns out, the Blinkt LEDs use pins 23 and 24 for data and clock, which the DAC uses for an optional rotary encoder. Since I’m not using a rotary encoder, I’m in the clear.

Speaker Lights

My Pi has a set of blinkt LEDs, and I wanted to show the Bluetooth state using those.

I wrote a Python script (scrappy code here) which:

  • Reads and builds its own representation of the D-Bus object tree
  • Listens to when an object is added, removed or changed
  • When there is a change somewhere in the tree, picks an animation to play on the LEDs and uses a GLib thread to run the LED animation.

It took me a while to get figured out, but I'm pleased with the results. I could probably lift the D-Bus object tree for use in a future project as well.

While it's searching for a device to connect to, the LED's sweep blue. After connecting, they switch to full blue with a slight breathing effect. An error sets them to full orange.

Here's the animation while a track is playing. The LEDs start off blue and sweep to green to show the progress through the track. The pulsing effect pauses when the track does.

Future plans

There’s a bunch of stuff I want to add to this project:

  • Improvements to the agent script
    • Turning off pairing if there is something connected (currently it just rejects pairing requests)
    • Double check I’m using the best Bluetooth audio codec I could be
  • Better animations with intros, outros and transitions, generally a neater setup
  • A specific intro when a track starts
  • Could be a procedural set of lights derived from the track details
    • Could be a counter showing the track number
  • Adding an infrared receiver so I can control the Pi using my amp’s remote control
  • Could hook up play, pause, skip, repeat, shuffle, seek
    • I could make the stop button disconnect the Bluetooth device, which would be useful
  • Automatically play CDs from a connected USB CD drive
    • I can avoid buying a Bluetooth receiver, I can avoid buying a CD player too!
    • I’ve played CDs using the Pi and it works ok, the main pain is that it keeps spinning the drive up and down which is kinda annoying. cd-paranoia might not be playing nice with my cheap drive, ill need to look into it
  • Adding a web server so I can control the Pi from a Wifi-connected device
  • A box to house it all
    • Could buy a ribbon cable for the GPIO pins to poke the LEDs out Could cut something out of cardboard, or head over to the hackspace to make a nice 3D-printed thing