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) 04 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 13 CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE 14 LimitNPROC=1 15 16 [Install] 17 WantedBy=bluetooth.target 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 05 06 [Service] 07 ExecStart=/usr/bin/rfcomm watch rfcomm0 1 /sbin/agetty -noclear rfcomm0 9600 vt100 08 09 [Install] 10 WantedBy=multi-user.target
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].
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
.