How to establish Bluetooth serial communication between two Pi 3’s

This is a guide on how to get Bluetooth communication working between two Pi 3’s using the on-board Bluetooth chips which was made possible by the raspberry pi forum and the user Douglas6 (Thanks again!).

Also I saw that somebody asked for something like this a few days ago so hopefully it help that person too.


This guide assumes that you are using Raspbian but since all the pairing and whatnot will be handled from the terminal (using generic programs) and not the GUI, I bet it would work for other distros.

Your bluetooth chip needs to be detected and working in order for this tutorial to be any use, there are a lot of posts on this sub to help you with that 🙂

I haven’t swapped out a Pi zero W for one of the Pi 3’s in this configuration, but I imagine the instructions for this would work for a zero W as well.


You’ll want to get familiar with bluetoothctl as it’s pretty important and very helpful when you know what the commands do. The help function tells you about all you need to know.

bluetoothctl
[bluetooth]#  help

Step 1: Update both your boards using and make sure that bluez and pi-bluetooth are installed (do this on each board)

sudo apt-get dist-upgrade
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install bluez pi-bluetooth python-bluez

Step 2: (Only sometimes necessary) Make sure that both the Bluetooth chips are not blocked using (on each)

sudo rfkill unblock all

Step 3: Pair the boards with one another First, make sure the Buetooth controller is powered (it usually already is)

bluetoothctl
[bluetooth]#  power on

Make the board discover-able

[bluetooth]# discoverable on

Set board as pair-able

[bluetooth]# pairable on

Repeat for the other board.

Now turn scanning on for one or both boards

[bluetooth]#  scan on

Since both boards are discover able, at this point you should see Bluetooth addresses popping up like this

Discovery started
[CHG] Controller B8:27:EB:7B:F3:62 Discovering: yes
[NEW] Device 80:7A:BF:0D:A8:68 HTC BS 681DC1
[NEW] Device 80:7A:BF:10:D4:D4 HTC BS D4D068
[NEW] Device B8:27:EB:25:95:F5 raspberrypi

That last one is the other R pi. Notice the Bluetooth address listed. I’ll refer to in a general sense with <bdaddr>.

Pair the boards with one another

[bluetooth]# pair <bdaddr>

Remember that <bdaddr> is the address of the other board, the one you are pairing with. It should pair and then you’ll get a GUI message asking you to pair and whatnot.

Answer yes to all of these.

An error gets thrown and the devices will disconnect. This is normal at this point

In one of the terminals you should have gotten a message that says

[CHG] Device <bdaddr> Paired: yes
Pairing successful
[CHG] Device <bdaddr> Trusted: yes

The devices need to be paired and trusted before moving on. To make sure that they are, run

bluetooth]# info <bdaddr>

and it should look something like this

[bluetooth]# info B8:27:EB:25:95:F5
Device B8:27:EB:25:95:F5
    Name: raspberrypi
    Alias: raspberrypi
    Paired: yes
    Trusted: yes
    Blocked: no
    Connected: no
    LegacyPairing: no
    UUID: Serial Port               (00001101-0000-1000-8000-00805f9b34fb)
    UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
    UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
    UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
    UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
    UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
    Modalias: usb:v1D6Bp0246d0517

If they aren’t trusted, use

    bluetooth]# trust <bdaddr>

So that both are trusted


Ok, hopefully that all worked out. Up until this point, everything could have been done through the GUI but now some additional work is required to prevent errors from being thrown when we try to connect.

Note: We have paired and trusted these devices to one another. This is a ‚permanent‘ action in that it lasts until you de-pair and de-trust them a.k.a. remove the device. Connecting is a different process that must be done each time they are turned off, taken out of range of one another, disconnected, etc.

Connecting is the persistent issue we run into at this point. Some config editing is required to fix it.


Step 4: Edit /etc/systemd/system/dbus-org.bluez.service

sudo nano /etc/systemd/system/dbus-org.bluez.service

Add a -C to the line

ExecStart=/usr/lib/bluetooth/bluetoothd

So that it looks like

ExecStart=/usr/lib/bluetooth/bluetoothd -C

And then add the following line below it

ExecStartPost=/usr/bin/sdptool add SP

So now the file has

ExecStart=/usr/lib/bluetooth/bluetoothd -C

ExecStartPost=/usr/bin/sdptool add SP

Do this on both and then reboot them. What this did was add a compatibility flag so that the chips run in compatibility mode and then we added a Serial Port Service (SPP) such that these things happen each time we boot.


Now that they are rebooted, we need to check and make sure that the SPP is actually running like we want it to. Use

sudo sdptool browse local

And you should see

Browsing FF:FF:FF:00:00:00 ...
Service Search failed: Invalid argument
Service Name: Serial Port
Service Description: COM Port
Service Provider: BlueZ
Service RecHandle: 0x10001
Service Class ID List:
  "Serial Port" (0x1101)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 1
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "Serial Port" (0x1101)
    Version: 0x0100

A lot of this info is not important but I included so you could recognise this particular block of text it in the terminal.


Ok, now that SPP is running on both boards, we can begin setting up our connection.

Step 5: Create server and client.

You can quickly test whether the boards accept a connection by running

sudo rfcomm watch hci0

on one board and then after that (do this on the other board)

sudo rfcomm connect hci0 <bdaddr>

where <bdaddr> is the address of the board ‚watching‘. If all goes well, on the server (1st) board you should see

Waiting for connection on channel 1
Connection from B8:27:EB:25:95:F5 to /dev/rfcomm0
Press CTRL-C for hangup

And on the client board you should see

Connected to /dev/rfcomm0 to B8:27:EB:7B:F3:62 on channel 1
Press CTRL-C for hangup

If you are here then you are basically home free. If you want to test out sending text over this serial connection, close the existing connection (this disconnects the boards) and then navigate to

/usr/share/doc/python-bluez/examples/simple/

And find the files named rfcomm-server.py and rfcomm-client.py.

Move copies of these files to your desktop (if you want). Edit the client file and set the addr variable equal to <bdaddr> of the other board (it’s a string so use „ADDRESS“).

Remaining paired and trusted (but not connected), run the sever file as root on one Pi and the client on the other. You should get a connection and be able to type stuff and receive it on the other. Congrats, you did it! Now feel free to edit the example files to suit your needs or roll your own using something other than pyserial.

Schreibe einen Kommentar