Bluetooth allows you to wirelessly connect peripheral devices like headphones, speakers, keyboards, and more to your Raspberry Pi. It‘s a convenient way to interact with your Pi without dealing with a lot of cables.
In this comprehensive 2600+ word guide, I‘ll cover everything you need to know about adding Bluetooth capabilities to your Raspberry Pi.
An Introduction to Bluetooth
Bluetooth is a short-range wireless communication standard used for transmitting data between fixed and mobile devices. It operates in the 2.4 GHz band and can maintain connections up to 10 meters away typically.
The Bluetooth Core Specification defines the protocol stack from the physical layer up through the application layer. Here is a quick overview of some key components:
Physical Layer
The physical layer handles translation between digital bits and Bluetooth radio frequencies using Gaussian frequency-shift keying (GFSK) modulation. Physical channels are separated by spacing of at least 1 MHz.
Link Layer
The link layer manages device discovery, connection establishment, authentication, and data transmission between devices. Connections can be point-to-point between two devices or point-to-multipoint.
Host Controller Interface (HCI)
HCI provides a command interface to the baseband controller and link manager. It‘s used primarily in Bluetooth hardware like modules and controllers. Communication happens over the HCI UART transport protocol typically.
Logical Link Control and Adaptation Protocol (L2CAP)
L2CAP handles data segmentation into packets and reassembly on top of asynchronous serial connections. It also multiplexes and demultiplexes data streams between higher layer protocols.
Service Discovery Protocol (SDP)
SDP allows devices to discover available services before making connections. This info gets stored in service records accessible via SDP queries.
There are additional protocols like RFCOMM, Audio/Video Distribution Transport Protocol, and more which provide transport channels…but the above covers some of the key layers for general Bluetooth connectivity.
With an overview of the Bluetooth standard complete, let‘s jump into some hardware specifics around using Bluetooth on a Raspberry Pi.
Bluetooth Hardware Support on Raspberry Pi Models
The Raspberry Pi Foundation has steadily improved integrated Bluetooth support with each new board revision.
Here is a breakdown of built-in Bluetooth capabilities for mainstream Pi models:
| Model | Integrated Bluetooth | Version | Chip |
|---|---|---|---|
| Raspberry Pi 1 A+/B+, Pi Zero | No | N/A | N/A |
| Raspberry Pi 2 B | No | N/A | N/A |
| Raspberry Pi 3 A+/B+ | Yes | Bluetooth 4.2 | Cypress CYW43438 |
| Raspberry Pi 4 (all) | Yes | Bluetooth 5.0 | Cypress CYW43455 |
For Pi‘s without built-in Bluetooth like the Pi 1 or Pi 2, you can add support via a USB dongle. I typically recommend the Plugable Bluetooth adapter which works seamlessly for around $13 USD.
If using an external USB Bluetooth adapter, be sure to budget the additional power draw from the USB port (around 50-100 mA typically).
You can use vcgencmd measure_temp to monitor SoC temperatures when under load. Throttling kicks in above 80 C typically to prevent overheating damage.
Now with an overview of hardware capabilities complete, let‘s take a hands-on look at setup…
Step-by-Step Raspberry Pi Bluetooth Setup
Here I‘ll walk through the entire process of taking a Raspberry Pi from stock Raspbian install to fully functioning Bluetooth connectivity.
Install Required Bluetooth Software
Start by updating packages and installing the Bluetooth stack:
sudo apt update
sudo apt full-upgrade -y
sudo apt install -y pi-bluetooth
The pi-bluetooth meta-package grabs bluez (Bluetooth stack), blueman (Bluetooth manager), and additional tools we‘ll make use of later.
Next, enable the bluetooth systemd service so it starts automatically on each reboot:
sudo systemctl enable bluetooth
Reboot your Pi to load the updated service.
With the core software now in place, we can move on to device configuration.
Configure Basic Bluetooth Settings
There are a few tweakable settings related to Bluetooth functionality living in /etc/bluetooth.
First, open the main bluetoothd daemon configuration file:
sudo nano /etc/bluetooth/main.conf
In here, we need to enable user mode device access. Find the line with:
#EnableUserMode = true
And remove the # comment character to enable:
EnableUserMode = true
This will allow normal pi users to manage Bluetooth without needing root permissions.
Save and exit the file after making the change.
Next, open the audio.conf configuration file:
sudo nano /etc/bluetooth/audio.conf
Uncomment the lines for both A2DP and HFP/HSP profiles:
Enable=Source,Sink,Media,Socket
SBCSources=1
SBCSinks=1
This enables high quality stereo audio and headset capabilities via Bluetooth.
Finally, open input.conf to allow Bluetooth keyboards and mice:
sudo nano /etc/bluetooth/input.conf
And add the following:
[General]
EnableSetkeys=true
[Device]
Enable=true
Save all config changes and reboot your Pi again to apply them.
Now your Raspberry Pi‘s Bluetooth adapter is configured and ready for connections!
Scan and Connect to Bluetooth Devices
With the setup complete, we can start discovering and pairing with Bluetooth peripherals like headphones, speakers, and more.
Scan for nearby discoverable Bluetooth devices with the bluetoothctl tool:
$ bluetoothctl
Agent registered
[bluetooth]# scan on
Discovery started
[CHG] Controller XX:XX:XX:XX:XX:XX Discovering: yes
You‘ll begin seeing device MAC addresses and names show up as the scan runs for 60 seconds by default.
Once you find the address of the device you want to pair, initiate the connection process by specifying its MAC:
[bluetooth]# pair XX:XX:XX:XX:XX:XX
Attempting to pair with XX:XX:XX:XX:XX:XX
[CHG] Device XX:XX:XX:XX:XX:XX Connected: yes
Follow any additional pairing instructions shown on the device itself, which may entail entering a PIN code.
Finally, connect to the now paired device:
[bluetooth]# connect XX:XX:XX:XX:XX:XX
[CHG] Device XX:XX:XX:XX:XX:XX Connected: yes
And you now have a wireless connection to your Bluetooth peripheral!
I‘d recommend creating simple Bash alias functions to simplify connections once paired. For example:
alias connect_headphones=‘bluetoothctl connect XX:XX:XX:XX:XX:XX‘
Makes it easy to run connect_headphones whenever you want to connect.
Stream Audio to Bluetooth Devices
Once connected to a wireless audio device like headphones or a speaker, you can configure Bluetooth as the default audio output:
amixer -D bluealsa cset name=‘bluealsa‘
aplay -D bluealsa /usr/share/sounds/alsa/Rear_Center.wav
This sets bluealsa as the ALSA plugin for Bluetooth audio rendering, and sends a test sound clip.
To simplify switching between normal audio and Bluetooth audio, create two toggling alias functions in your ~/.bashrc:
change_output_normal() {
amixer -D pulse cset name=‘output‘
echo "Switched to local audio output"
}
change_output_bluetooth() {
amixer -D bluealsa cset name=‘bluealsa‘
echo "Switched to Bluetooth audio output"
}
Then when you want to play audio through Bluetooth instead of Pi headphone jack for example, run change_output_bluetooth.
And change_output_normal to go back to the standard output.
This makes it easy to change where audio gets routed to meet your use case needs!
Advanced Bluetooth Considerations
While basic Bluetooth functionality is pretty straightforward on a Raspberry Pi, there are some additional things to keep in mind for production applications.
Power Management & Consumption
Bluetooth can draw 60-100mA+ continuous depending on activity levels. This is fine for most modern Pi‘s, but can overstress marginal power supplies or lightweight batteries/solar setups.
If running on battery power, make use of the built-in Bluetooth power management capabilities:
sudo nano /lib/systemd/system/bluetooth.service
And set appropriate values for maximum transmit power and discoverability modes:
ExecStart=/usr/lib/bluetooth/bluetoothd --class 0x240404 --px 6 --pic 800-1000 -m id
This will restrict the Bluetooth controller to 6dBm transmit power with 800ms advertisements up to once per second max. Extending battery runtime significantly.
See the bluetoothd documentation for additional details on available arguments around power savings.
Bluetooth Coexistence & Interference
The 2.4Ghz spectrum Bluetooth shares with WiFi, Zigbee, microwave ovens and more can get quite crowded and noisy in home environments. As well as industrial environments flooded with wireless sensors.
Make use of Bluetooth 5.0 LE features like frequency hopping, forward error correction, and coding scheme improvements when possible for noise resilience.
For Raspberry Pi‘s without Bluetooth 5.0 LE, you may need to optimize WiFi AP channel selection and Zigbee mesh routing to reduce collisions and achieve reliable throughput.
Security Risks
While Bluetooth includes authentication and encryption mechanisms, researchers have demonstrated security weaknesses around brute forcing passkeys along with bluebugging attacks.
I‘d recommend some best practices around Bluetooth security on Pi projects:
- Use long alphanumeric passwords/passkeys when pairing devices
- Adjust discoverable timeouts to be as short as viable
- Disable Bluetooth entirely if functionality not regularly needed
- Run
bluetoothctl removeand re-pair devices periodically - Utilize SSH instead of Bluetooth where sensitive data transfer needed
Keep security considerations in mind if dealing with private user data over Bluetooth links.
Integrating Bluetooth Support into Python Applications
Once you have Bluetooth functionality working on a base Raspberry Pi OS install, many intriguing possibilities open up around integrating Bluetooth wireless capabilities into custom Python applications with the PyBluez module.
For example, you could build Python scripts to automate discovery, pairing, and data transmission with peripheral devices. Here is some sample code to get started:
Discover Nearby Devices
import bluetooth
print("Searching for devices...")
devices = bluetooth.discover_devices(lookup_names=True)
print("Found {} devices".format(len(devices)))
for addr, name in devices:
print(" {} - {}".format(addr, name))
Initiate Pairing
pairing_code=‘5309‘ #some devices require this
target_mac=‘XX:XX:XX:XX:XX:XX‘
print("Attempting to pair with {}...".format(target_mac))
paired=bluetooth.pair_device(target_mac, pairing_code, 10) #10sec timeout
if paired:
print("Successfully paired!")
else:
print("Unable to pair with device...")
Transmit Data
data_to_send="Hello from RPi!"
sock=bluetooth.BluetoothSocket(bluetooth.RFCOMM)
sock.connect((target_mac, 1))
sock.send(data_to_send)
print("Data transmitted successfully!")
sock.close()
Tons of possibilities for custom solutions leveraging Bluetooth + Python code together on a Raspberry Pi!
Closing Thoughts on Pi Bluetooth Projects
Adding Bluetooth support to a Raspberry Pi opens up projects around wireless headphones, IoT sensors, hands-free voice control, automation systems, and more.
With Bluetooth configurations tuned for low energy usage, interference minimized, and security policies followed, you can reliably utilize Bluetooth connections in your Raspberry Pi applications.
Integrating the capabilities exposed from PyBluez into Python scripts unlocks even more opportunities.
I hope this guide gave you a solid foundation for working with Bluetooth effectively on your future Raspberry Pi builds! Let me know if you have any other questions.


