The Complete Guide To Using Bluetooth With A Raspberry Pi


It wasn’t that long ago that everything had to be physically connected to your Raspberry Pi. Luckily, starting with the Raspberry Pi 3B, Bluetooth and Wifi were added. Now any Raspberry Pi model (excluding the compute modules) comes with these features standard. Here is a thorough guide on what Bluetooth is, why it’s great, and how to use it.

What Is Bluetooth

Bluetooth, named after Harald Bluetooth the 2nd king of Denmark, is a form of wireless connection that is characterized by its very low power consumption. Its initial purpose was to reduce or even eliminate the cables that connected peripherals to a computer.

Because it requires such a small amount of power, it can be used by devices that run off of batteries without quickly draining them. Many Bluetooth mice and keyboards can go months without needing their batteries replaced.

The process of connecting two different devices together via Bluetooth is commonly referred to as “pairing”. Pairing is a secure process that often requires input from both devices in order to establish a connection. The connection is able to send information in both directions and changes radio frequencies while connected to increase security.

The downside to Bluetooth is the shorter broadcasting and connectivity range. Most Bluetooth devices are unable to connect at a distance greater than 30 feet. With walls in the way, that distance is even shorter. This is actually viewed as a positive feature for those who are prioritizing security as it requires anyone with malicious intent to be very close to the device they want to gain access to.

Why Use Bluetooth

There are three main reasons to use Bluetooth with a Raspberry Pi. First and foremost is that it allows you to connect your standard input devices like a mouse and keyboard without using the limited number of USB ports you have access to. With a maximum of 4 USB ports, they are a precious commodity. Anything you can do to keep them available for a different device is worth looking into.

Secondly, Bluetooth is a very low power form of wireless connection. If your project is going to run on batteries, you are going to want it to last as long as possible. It wouldn’t be any fun if you built a robot that only has 10-minutes of battery life. You can expect Bluetooth to use at least 10 times less energy than if you were using Wifi for the same task.

Finally, Bluetooth is also fairly secure. The data being sent and received is always encrypted and there are a number of security features that can be implemented. The most important security feature is the ability to require confirmation before accepting a requested connection. This prevents anyone from automatically connecting to your Raspberry Pi or other Bluetooth devices.

Turning On Bluetooth

Now that we’ve what Bluetooth is and why you would want to use it, lets put it to work on your Raspberry Pi. Bluetooth is usually turned on by default, but you may need to turn it on manually in some cases.

Through Terminal

To get started with Bluetooth in the terminal, you will need to access Bluetooth control

sudo bluetoothctl

After entering this, you will be prompted for the admin password (default is raspberry).

Next, you will want to turn Bluetooth on and scan for devices to pair with.

agent-on
default-agent

scan on

Congratulations, you have successfully turned on Bluetooth through the terminal on your Raspberry Pi.

Through The GUI

While this section is about turning on Bluetooth through the graphical user interface, you will still need to do a little bit of work in Terminal. You will still need to install a Bluetooth controller, but this time we are going to use Bluez. Start by typing this into your terminal:

sudo apt-get install bluetooth bluez blueman

Press enter and your Raspberry Pi will install the packages. Then restart your Raspberry Pi with

sudo reboot

Now when your Raspberry Pi boots up, you can access the Bluetooth settings through the menu. Simply go to Menu -> Preferences -> Bluetooth Manager. From here you can turn Bluetooth on and off, connect to a specific device, or make your Raspberry Pi discoverable.

Connecting A Mouse, Keyboard, Or Speaker

If you are using the GUI, connecting to a keyboard or mouse is as simple as selecting the correct device and pairing. If you are using the terminal method, there are a few steps to take.

First, after you have enabled Bluetooth you will need to scan for devices to connect to. You can do this with the following command:

scan on

This will bring up a list of all of the detected Bluetooth devices with their unique ID code in the format of XX:XX:XX:XX:XX:XX. If your device is discoverable or in pairing mode, you may also see the name of the device. If the name is not available, you will have to use trial and error to determine which device is the one you want to pair with. To pair with the device you will use:

pair XX:XX:XX:XX:XX:XX

For some devices, this is all you will have to do to pair them. For others, like some keyboards, you may need to enter a sequence of characters to confirm the pairing. Once paired, you may be all set but there is a chance that you will need to “deepen” the relationship between your Raspberry Pi and the device you want to connect to. This can be done with the connect command.

connect XX:XX:XX:XX:XX:XX

With this last step, you will have successfully connected your Raspberry Pi to an external device with Bluetooth.

Controlling Your Raspberry Pi With An Android Phone

Using my phone as a remote control for a Raspberry Pi powered RC car was the first time I began working with Bluetooth. Here is how you control the GPIO pins using an Android phone.

First, you will want to make sure that your Raspberry Pi has Bluetooth enabled and is actively scanning. Then you will want to make sure that Bluez and it’s corresponding Python library are installed.

sudo apt-get install bluetooth bluez
sudo apt-get install python-bluz
sudo reboot

Next, you will need to create a Python file that will listen to the Bluetooth connection and perform an action when it is received. I named this file bluetoothtest.py.

importbluetooth
server_sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
port =1
server_sock.bind(("",port))
server_sock.listen(1)
client_sock,address =server_sock.accept()
print"Accepted connection from ",address
whileTrue:
recvdata =client_sock.recv(1024)
print"Received \"%s\" through Bluetooth"%recvdata
if(recvdata =="Q"):
print("Exiting")
break
client_sock.close()
server_sock.close()

Now in Terminal, you need to make sure that Bluetooth is turned on, you Raspberry Pi is discoverable, and run your file.

sudobluetoothctl
power on
discoverable yes
quit
python bluetoothtest.py

At this point, your Raspberry Pi is now looking to be paired and will accept the signals sent to it. For this example, I am using BlueTerm which is free from the Play Store to send individual characters to the Raspberry Pi from an Android phone. On your Android phone, open BlueTerm and connect to your Raspberry Pi. Now you should be able to type a character and see it on your Raspberry Pi’s display. At any point, press the “Q” button to quit the program on your Raspberry Pi.

With this framework in place, you can now set specific Python commands to certain keys on your phone. Simply add the following lines to your python file below

print"Received \"%s\" through Bluetooth"%recvdata

to trigger a command. This example uses the “A” character to call “my_function” which can be defined elsewhere in the file.

if(recvdata =="A"):
my_function()

You could go further with this and create your own android app that includes a GUI to send commands when a button is pressed.

Configuring A Headless Setup

Before I dive into how to configure a headless Raspberry Pi through Bluetooth, I should probably stop and explain what it even means. A headless setup is a term that describes a Raspberry Pi that is not connected to a monitor, mouse, or keyboard. Instead, it is “controlled” by a separate computer that can send and receive information to and from the Raspberry Pi.

This specific tutorial presumes that you do not have access to a spare keyboard, mouse, or monitor and is designed to configure a headless setup from the start by editing the Raspbian image used to boot your Raspberry Pi.

Why Use A Headless Raspberry Pi

A headless Raspberry Pi does not need to be connected to anything other than a power source. It does not need a monitor, a keyboard, or a mouse. This can save you quite a bit if you don’t have those laying around. It also means that you can put your Raspberry Pi anywhere in a room and still use it. It doesn’t have to be sitting front and center with a bunch of cables coming out of it. Overall, a headless Raspberry Pi setup is a great way to save a little money and avoid the clutter of cables.

Preparing The Raspbian Image

To get started, you need to download the latest version of Raspian. You can find it here. Next, you need to mount the image and edit it. You need to edit the EXT4 partition.

Mounting On Windows

On a Windows machine, you will want to download and install Linux Reader by Diskinternals: https://www.diskinternals.com/linux-reader/. This tool should allow you to mount and edit the Raspbian image.

Mounting On Linux

Mounting a Raspbian image on a Linux machine is a little tricky because it has a boot sector and two partitions. The first step in mounting the image is determining the offset of the partitions. This can be done with the following command:

fdisk -l raspbianimagename.img

This should produce all of the information that we need. The first piece of information to take notice of is the unit size. The unit size is found in a line that looks something like this:

Units: sectors of 1 * 512 = 512 bytes

In this instance, the unit size is 512 bytes. The next information you need to grab is the partition start location and type. This can be found on a table that looks like this:

Device Boot Start End Blocks Id System
raspbianimagename.img1 8192 122879 57344 c W95 FAT32 (LBA)
raspbianimagename.img2 122880 5785599 2831360 83 Linux

Now you can determine the offset of the two partitions. This can be done by multiplying the Start location by the unit size. In this example, the locations would be:

  • 8192 * 512 = 4194304
  • 122880 * 512 = 62914560

With all of this, you are now ready to mount your image using the mount and offset commands to mount your image.

mount -v -o offset=4194304 -t vfat raspbianimagename.img /mnt/img/one
mount -v -o offset=62914560 -t ext4 raspbianimagename.img /mnt/img/two

There is a good chance that everything should work. If you end up with an “overlapping loop” error you will need to include the sizelimit command to the first mount. Set the value equal to the “Blocks” value multiplied by the unit size.

Mounting On MAC

This is probably the most difficult operating system to mount the Raspbian image on. This is because MAC OS does not natively support EXT4. There are two ways to mount the image.

  1. Install EXT4 drivers on your MAC device and then mount the image.
  2. Use a virtual machine, install Linux on it, and follow the instructions above.

Of the two options, I strongly recommend the second as EXT4 drivers for MAC are not designed for editing files, only reading them.

Editing The Code

Now that you have the Raspbian image mounted, it’s time to start editing it. Start by creating the script that will create and open the serial port you will connect to via Bluetooth. This will live in the home/pi directory. To create the file type the following into the terminal:

$ sudo nano /home/pi/btserial.sh

Here is what you will want to include in the script.

#!/bin/bash -e

#Edit the display name of the RaspberryPi

echo PRETTY_HOSTNAME=raspberrypi > /etc/machine-info

# Edit /lib/systemd/system/bluetooth.service to enable BT services
sudo sed -i: 's|^Exec.*toothd$| \
ExecStart=/usr/lib/bluetooth/bluetoothd -C \
ExecStartPost=/usr/bin/sdptool add SP \
ExecStartPost=/bin/hciconfig hci0 piscan \
|g' /lib/systemd/system/bluetooth.service

# create /etc/systemd/system/rfcomm.service to enable the Bluetooth serial port from systemctl
sudo cat <<EOF | sudo tee /etc/systemd/system/rfcomm.service > /dev/null
[Unit]
Description=RFCOMM service
After=bluetooth.service
Requires=bluetooth.service

[Service] ExecStart=/usr/bin/rfcomm watch hci0 1 getty rfcomm0 115200 vt100 -a pi

[Install]
WantedBy=multi-user.target
EOF

# enable the rfcomm service
sudo systemctl enable rfcomm

# start the rfcomm service
sudo systemctl restart rfcomm

Save the script. Next, you will need to make the file executable. You can do this with the following command:

$ chmod 755 /home/pi/btserial.sh

Now that the script is ready you can connect to your Raspberry Pi remotely. However, you will still need to boot it up and run the script. To fix that issue, you can run the script on boot. To do this, edit the /etc/rc.local file.

$ sudo nano /etc/rc.local

Then add the following code after the comments:

#Launch bluetooth service startup script /home/pi/btserial.sh
sudo /home/pi/btserial.sh &

Save the file, unmount the image, and you are ready to write it to an SD card. Once you have the SD card in your Raspberry Pi, power it up, wait about 30 seconds, and then pull the power. Wait a few seconds and power it up again. The reason you need to cycle it once is that there can be issues when rebooting the Bluetooth service.

Connecting To Your Raspberry Pi

With your Raspberry Pi up and running, it is now time to connect to it. Start by ensuring that the Bluetooth is enabled on your computer. Select “raspberrypi” when it appears and pair with it.

Open a terminal window on your personal computer so that you can connect to the Bluetooth serial port. Start by typing the following:

$ ls /dev/cu.*

This should produce a list of available serial ports. Identify the serial port associated with your Raspberry Pi and connect to it.

$ screen /dev/cu.raspberrypi-SerialPort 115200

After entering this command, you should be given the prompt for your Raspberry Pi. You’ve done it!

Final Touches On Your Headless Setup

There are a couple of steps you can take to make your connection more user-friendly and more secure. These are not required but are recommended.

Dynamic Window Resizing

If you want your Raspberry Pi terminal to dynamically resize with your local terminal there are a few steps you need to take. Start by activating SSH. To do this, begin by entering the following into the Raspberry Pi terminal:

$ sudo raspi-config

Then select Advanced Config -> SSH -> Activate -> Save and Exit. With this, SSH will be enabled. Next enter the following commands:

$ su pi -
$ ssh localhost

With this, your Raspberry Pi terminal window will now dynamically resize.

Adding Additional Security

Being able to remotely connect to your Raspberry Pi is great the configuration also opens up the risk of someone else taking control of your Raspberry Pi. In order to prevent this from happening, you can turn off discoverability after you have connected to your Raspberry Pi from your computer. To do this, run the following commands:

$sudo bluetoothctl
[bluetooth]#
[bluetooth]#discoverable no
[bluetooth]#pairing no
[bluetooth]#quit
$

These commands will turn off discoverability and pairing to your Raspberry Pi. You will need to run these commands if your Raspberry Pi reboots.

Related Questions

Which Raspberry Pi models have Bluetooth

The Model A, B, 2B, and Zero do not have Bluetooth. All models starting with the 3B including the Zero W have built-in Bluetooth. For the models that do not have integrated Bluetooth, a Bluetooth dongle can be used.

Recent Posts