Bluetooth Comms between RPi3 and Android

As users of shiny technology we have become used to connecting devices to bluetooth and the routine for doing this – it’s easy, right? That’s because the developers of these technologies, quite rightly, have hidden away the complexity behind the scenes making it straightforward for us users. Whilst developing our robot we’ve uncovered some of the bluetooth complexity and learnt a great deal along the way.

In this post we’ll explain how we configured bluetooth on the pi, connected it to a phone and sent messages between the two via a terminal.

Most of the guides we came across didn’t give an end-to-end example for what we were trying to do – this is largely because you could, and many have, write a whole book or series of books just on bluetooth stack and protocols etc. However, knowing about some of the basics and common misconceptions of how bluetooth works would have saved us many hours of frustration.

We’ve learnt so much through our frustrated efforts we thought we’d try and highlight some of the key points (so we can remember in future). In our example we are aiming to send messages from a phone to the Pi so we can eventually create a UI on the phone and control Mr Bit, our Pi based robot for PiWars 2017.

3 (big) lessons learnt:

  1.  Bluetooth doesn’t connect and stay connected unless it is in use!
    • lots of people share this reported (none) issue (disconnected from device)
    • bluetooth pairs and then only connects when needed via a valid protocol
    • this is not an issue, this is how bluetooth works it’s just that devices generally keep connections active once connected
  2. There must be a serial channel set up on the pi to successfully send and receive messages
    • devices might connect but without a serial channel to communicate on messages will just get lost in the ether
    • there is a bug in the bluetooth service (bluez 5) we are running at time of writing which means we need to edit the config of the service to set this up.
    • if you don’t set up a comms channel then connections are made, messages are sent, but they get lost in the ether.
  3. You need two bluetooth applications running, a client and a server – it doesn’t just work
    • we’re not talking about bluetooth daemon running on the Pi, that’s a given
    • to communicate with a device one of them needs to be the client and one needs to be the server
    • bluetooth server needs to run as an application listening to a channel (see lessons learnt 2)
    • clients need to connect to this server and then, if accepted, messages can be passed between the two

This is how we set up bluetooth and got messages passing between the Pi and Android:

Enable bluetooth on the Pi

We are running Raspbian Jessie (4.4 kernel) on a RPi 3 which means we have onboard bluetooth module. We already have bluez installed which is the bluetooth stack for linux. If you need to install this then $ sudo apt-get install bluetooth bluez First of all we need to see if the bluetooth service is running

If it isn’t it can be started using: $ sudo systemctl start bluetooth

Once started we can see the mac address (unique hardware address of the bluetooth) via the hcitool adaptor

This shows us that the Pi has a bluetooth device connected to hci0 with mac address B8:27:EB:9B:82:AE
Bluetooth devices generally allow themselves to be discovered via inquiry scans which return a list of all the bluetooth services available on a given device (such as audio, phonebook, etc). We can set this up using the configuration commands of hcitool:

Discover and Pair with devices

It is possible o discover and pair with devices via a GUI in Pixel but we are going to use the command line. There’s a bluetooth utility for this we can use called bluetoothctl which abstracts some of the commonly used features of the device (hictool commands).

Try $ sudo bluetoothctl This should open up the bluetooth control command prompt, if not then you can install bluetoothctl with $ sudo apt-get bluez-utils

We will use the utility to power on the bluetooth module, turn on the agent that is used for discovery and scanning, enable the Pi to be paired and then scan for devices nearby with the following commands. (note, ensure the bluetooth device you are pairing with is discoverable, we are using an Android phone).

Once scanning the devices should show up along with their mac addresses. use [bluetooth]# pair xx:xx:xx:xx:xx:xx and once the pairing is complete (you may have to enter/accept codes on the device) use [bluetooth]# trust xx:xx:xx:xx:xx:xx so that the code handshake isn’t required in future.

There is a connect command in bluetoothctl but notice running results in a failure e.g.

We think this is a common point at which people assume they can’t connect to their devices and ask for advice, we certainly got caught out here and started looking for answers too (just one of many). But read on as this isn’t necessarily the case!

Connect and send messages to devices

So, why don’t the devices connect? Turns out it’s because there’s no need to be connected. To establish a connection we need to have a server->client interaction, i.e. the Pi needs to be either the server or the client and the device your connecting to, the opposite. If you’re connecting to a phone then this will act as either client or server – all the behind scenes complexity is hidden on the phone remember… In this example we will make the Pi the server and the phone the client.

When doing this we actually managed to set up a server and a client and tried to make the devices talk to each other only to find out they weren’t talking the same language! After some lessons learnt, using btmon and various head scratching we realised we need to set up a serial channel for the devices to communicate over – for this we use the L2CAP protocol (which is a call and respond type communication) over a serial port called rfcomm (radio frequency communication).

We can set up the rfcomm channel/port or “serial port profile” (spp) via a serial data protocol tool called sdptool:

We can check the channel is set up using the following command:
(note output snippet will be amongst others)

If you get an error such as: Failed to connect to SDP server on FF:FF:FF:00:00:00: No such file or directory This can be fixed by altering the configuration of the bluetooth (bluez) service, this is a known issue (also now known to us!) at time of writing in bluez5. To resolve this we need to edit the config for the service:

and add the –compat flag in the file to make the service backward compatible on the line

Then save and restart the service with the new config setting:

We also need to change permissions on the following $ sudo chmod 777 /var/run/sdp

Note: unfortunately this is probably going to be reverted whenever bluez5 updates via apt-get update and these steps will need to be run again. Good job we have this post to reference in the future 🙂

Once the rfcomm channel is set up we can listen to it for incoming connections using:

We are using an app on our android called Bluetooth Terminal. When successfully connected to the Pi we see the following message:

To view the messages sent we can use the following command in a new terminal window

and we can send messages by piping a string to the rfcomm0 port $ echo hello Android! > /dev/rfcomm0

To get more of a chat like experience between the two devices we can make use of a serial terminal called minicom (originally for logging into modems). First it needs to be installed with $ sudo apt-get mincom

And then the baud rate for comms on a specific serial port to launch $ minicom -b 115200 -o -D /dev/rfcomm0

See a man page for minicom for details about how to make it more user friendly (like ctrl+A then E to echo out messages typed into it and ctrl+A then X to exit).

There seem to be a few tools and applications to manage bluetooth one of which helped us to monitor bluetooth activity. Open up another terminal window and use $ sudo btmon. It seems a lot of people have issues that are common in this post, we can’t be sure the instructions above will work for us in future or with another bluetooth module (usb or similar) though we’re looking forward to using it more as the main comms method between our UI controller and Mr. Bit.

Leave a Reply

Your email address will not be published. Required fields are marked *