Setting up Bluetooth on the Raspberry Pi 3

Virtual BT Keyboard

Controlling a Rasp Pi with a Bluetooth keyboard can be very useful; however, it does not work with systems that do not have a display screen. A Bluetooth keyboard is connected like a keyboard connected by cable to a local computer. With headless systems, however, access is usually successful through the network. Bluetooth offers an alternative because it also frees a serial port.

Serial ports on computers have been around forever. In the beginning, computers connected to the outside world over dial-up lines, with a terminal at the other end of the line. Both sides still exist today, but they have been virtualized and made completely transparent. Even so, establishing a serial transmission line with Bluetooth requires some work.

To begin, you should copy the service definition

$ sudo cp -a /lib/systemd/system/bluetooth.service /etc/systemd/system

and modify it according to Listing 3. The modification involves calling up the Bluetooth daemon in line 8 with the -C parameter (compatibility mode) and adding line 9, which informs the Bluetooth stack that serial connections are now possible.

Listing 3

Enabling Serial Connections

01 [Unit]
02 Description=Bluetooth service
03 Documentation=man:bluetoothd(8)
05 [Service]
06 Type=dbus
07 BusName=org.bluez
08 ExecStart=/usr/lib/bluetooth/bluetoothd -C
09 ExecStartPost=/usr/bin/sdptool add SP
10 NotifyAccess=main
11 #WatchdogSec=10
12 #Restart=on-failure
14 LimitNPROC=1
16 [Install]
18 Alias=dbus-org.bluez.service

The tool for serial Bluetooth connections is called rfcomm. Listing 4 is a service definition for an automatic start. The lines in this listing should be copied to the new file /etc/systemd/system/rfcomm.service, before executing:

Listing 4

Auto Restart

01 [Unit]
02 Description=RFCOMM service
03 After=bluetooth.service
04 Requires=bluetooth.service
06 [Service]
07 ExecStart=/usr/bin/rfcomm watch rfcomm0 1 /sbin/agetty -noclear rfcomm0 9600 vt100
09 [Install]
sudo systemctl enable rfcomm

After restarting, the Bluetooth daemon runs in compatibility mode, and the RFCOMM service is active. If necessary, you can check this by calling

systemctl status rfcomm

Line 7 in Listing 4 contains all of the magic of the RFCOMM call. The program monitors channel 1 and starts the agetty program if necessary on the /dev/rfcomm0 serial device. The remaining parameters control agetty by setting the baud rate to 9600 and terminal emulation to vt100.

If you have ever experienced network problems on a Rasp Pi that lacks both a keyboard and display screen, you can appreciate this emergency entry. Anything entered on the Bluetooth keyboard is executed immediately. The only other solution is to unplug the power; however, the SD card filesystem will not take kindly to this over time.

You still need Bluetooth terminal emulation on the other side (Figure 5) – for example, the open source Android app Blueterm [9], which works well when used with a keyboard that offers the common Ctrl and Alt shortcut keys [10].

Figure 5: The Blueterm Android app lets you operate a Rasp Pi without a cable and without a network.

The serial connection can also be used for other purposes, like transferring data from one device to another. For this task, you can either modify the service definition or manually start a suitable program once the connection is established. For example,

cat < /dev/rfcomm0 > ~/data.txt

could save the data that has been transmitted to the data.txt file.

Using Bluetooth for Music

In the last example, I want to look at using the Rasp Pi to play music on Bluetooth loudspeakers or earphones. According to the documentation, this is fairly simple and doesn't require much effort; nonetheless, the implementation was not so easy.

At the outset, the documentation says you need a PulseAudio sound server for music streams. This server advertises itself as a virtual sound card between applications such as VLC and physical output devices. Theoretically, PulseAudio connects via Bluetooth with found devices that have already been paired and generates a new output device. The PulseAudio mixer can then output the sound from the new device.

Therefore, it makes sense to install the entire PulseAudio stack first:

$ sudo apt-get install pulseaudio-module-bluetooth pavucontrol mplayer

The command simultaneously installs the pavucontrol mixer and a playback program. An alternative would be VLC, as mentioned previously. If PulseAudio is already available on your computer, you should simply restart it, but not as a root:

$ pulseaudio -k
$ pulseaudio -D

After completing the installation, you should hook up the Bluetooth loudspeaker or the headset. At first, nothing happens, because it takes a few minutes for all of the steps to complete. The Bluetooth stack transfers the new device to PulseAudio, the service generates a connection, and then a new output device becomes available.

Using Pavucontrol, the graphical mixer for PulseAudio, you then decide which output device will receive the sound and set the volume. When a headless system is involved, you use the command-line program pactl.

Buy Raspberry Pi Geek

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content