How to Create Bluetooth Entrance Music With a Raspberry Pi

by tmckay1.jackson in Circuits > Raspberry Pi

1032 Views, 1 Favorites, 0 Comments

How to Create Bluetooth Entrance Music With a Raspberry Pi

How to Create Entrance Music: Raspberry Pi Bluetooth Entrance Music | Raspberry Pi Projects

In this article we describe how we used a raspberry pi to create entrance music for different devices. The idea is we will use bluetooth to try to connect to a device on the pi and keep looping to look for a device. If we find one, we'll connect to it with bluetooth and play an audio file, ending the program at the end of the audio clip. For more details, keep reading.

Supplies

1. Raspberry Pi (I used the 4, but you can use any with bluetooth support) - https://amzn.to/3ujCdOE

2. Sound Card - https://amzn.to/3xI4Ebb

3. Aux cord - https://amzn.to/3nMlwc9

Connect the Pi to the Speakers

p4.jpg
p1.jpg
p3.jpg

Assuming you have the Raspberry Pi OS setup and configured correctly, go ahead and connect the pi to the speakers. I never had much luck using the raw headphone jack and auxiliary cable to play audio, so I ended up using a USB sound card and auxiliary cable to connect to the speakers. You could also play in the HDMI cord if you'd like to play outside the TV. Do whatever works for you (will explain how to configure later), but as I said I'll be using an external sound card connected through auxiliary.

Configure the Pi to Output Sound to the Audio Card

p25.jpg
p24.jpg
p26.png

Now you'll need to change the output device to play sound from by specifying the output device index in the alsa.conf file. Now go ahead and specify which index you'd like to have as the default by typing the following on the command line:

sudo vi /usr/share/alsa/alsa.conf

And looking for the following lines:

defaults.ctl.card 0
defaults.pcm.card 0

And changing them to

defaults.ctl.card 2
defaults.pcm.card 2

Since my pi will be outputting audio through the sound card (index 2). Note that the HDMI index will not be there if the pi is not plugged into the HDMI, so your sound card index may be 1 in that case (when HDMI is active 1 is the HDMI index).

You can tell if this change worked by rebooting the pi and navigating to raspi-config by executing the following in the command line:

sudo raspi-config

Then navigate to System settings, and then Audio. This will bring up a screen of output devices and the preference that relates to it. You can see from the screenshot for me, my preferences were 0 - USB Soundcard, 1 - HDMI cable, and 2 - headphones jack.

Note Down Your MAC Address for Devices You'd Like to Trigger Entrance Music

p12.jpg

Since we'll be using the pi to try to initiate a connection to a phone via bluetooth, we need to know the mac addresses of those phones to be able to try to connect to them in code later. To find out what the mac address of your phone or other devices you want to connect, you'll need to go to the command line and run:

bluetoothctl

After running that start scanning for devices in the bluetoothctl shell with:

scan on

Once your device is in range of the pi and shows up, note down the mac address of that device. Do this for every device you'd like to trigger entrance music for.

Configure the Pi to Be Able to Connect to Your Phone

p11.jpg
p10.jpg

By default I had issues connecting my phone to the Pi and so I had to configure the bluez service to be able to connect to my phone. The bluez service is the program the Pi uses to connect to devices with bluetooth. You'll need to modify it's config by running the following on the command line:

sudo vi /etc/systemd/system/dbus-org.bluez.service

This will open up the config. When this opens look for and modify the lines below:

ExecStart=/usr/lib/bluetooth/bluetoothd

Should change to

ExecStart=/usr/lib/bluetooth/bluetoothd -C

And

ExecStartPost=/usr/bin/sdptool

Should change to

ExecStartPost=/usr/bin/sdptool add SP

Pair Your Device With the Pi

p8.jpg
p6.jpg
p5.jpg

The program you'll be running to play entrance music assumes that any device you want to play entrance music for has already paired with the pi before. So you'll need to connect those devices to the Pi at least one time, so the Pi understands what the device is. To do this I marked the Pi as Discoverable in the menu bar of the UI, then on my iPhone I connected to the raspberry pi, and lastly I confirmed in the UI of the Pi to connect to the phone. Once successfully connected, I disconnect the device because all we needed to do was pair.

Understand the Program Architecture

bluetooth_pi_diagram.png
bus.png
bluetooth_pi_diagram_bus.png

Before diving into the code it will help to get an understanding of how the program is supposed to work. The idea is that a main loop will constantly be running on the raspberry pi in the background. It will have a list of mac addresses pointed to an audio file to play for that mac address, and it will constantly be going through that list of mac addresses and trying to connect to it via bluetooth. When it fails to connect to a mac address, it will go to the next mac address and keep trying repeating the list over and over again until a connection is successful. The idea is that the connection will not be successful unless a device is close enough to the pi. After a successful connection, the pi will play the audio file associated with that mac address and end the program.

The main loop of the program in EntranceMusic.py is communicating with the bluetoothctl shell and the auto-agent script through subprocesses. It spawns a subprocess for each one to communicate with the bluetooth interface. The bluetoothctl shell is a well known interface to perform bluetooth actions from the command line, while the auto-agent file is a script I made from copying snippets of code from forums. I chose not to change the majority of the file to preserve the work of the original author, and also to give you an idea of other commands you are able to run with bluetooth (we really only care about connections, but you can do much more). Both of these files communicate with the Bluez service.

The auto-agent file creates a python object that represents a system bus and this is what allows us to communicate with the Bluez service. You can think of this object as a way to communicate between services (versus communicating between applications). Once the object is constructed there are a few methods that need overriding to successfully interface with the system bus. If this is confusing to you, I would recommend skipping over this as the most important part in this file is the hooks that are called when a pair request is successful pair_reply or a pair request fails pair_error. These methods output messages to stdout which the main loop is watching, and based on those messages, the main loop will understand if a connection to the mac address worked or not. If it works, the main loop plays music, otherwise, it cycles through the next mac address and spawns another auto-agent subprocess to attempt a pairing.

Download the Code and Start Up the Program

p15.jpg
p9.jpg
p13.jpg

Github repository: https://github.com/tmckay1/pi_bluetooth_auto_conne...

Clone the github repo and follow the instructions in the README.md. You need to copy the auto-agent script to a system location and change the permissions on the file so it is executable. Note that you can run this file to auto pair to bluetooth devices on pi startup if you wanted (like autoconnecting to bluetooth headphones or speakers on pi startup).

Once this is done open up testAutoPair.py and modify the mac address list and audio files to the correct mac addresses you want to connect to and audio files to play for those mac addresses. Once that is done you should be able to test the program by running

sudo python3 ./testAutoPair.py

While within the base of the project folder. Notice the output of failed connections, and when finally successful, an audio file will play. Enjoy!