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.