Introduction: Control Bluetooth LE Devices From a Raspberry Pi
Bluetooth Low Energy (aka BLE/Bluetooth 4.0/Bluetooth Smart) is the most recent incarnation of Bluetooth technology developed by the Bluetooth SIG (the organization that maintains the specification). This communication protocol is designed for applications where data needs to be transferred in small amounts at relatively low speed while consuming low amounts of power (e.g., heart rate monitor, step counter, wireless keyboard). This latest version of the protocol is not compatible with its predecessor (Bluetooth classic), as an upside, long gone are the days where pairing devices was necessary!
The goal of this Instructable is to demonstrate how you can setup your Raspberry Pi to read and write data from Bluetooth Low Energy (BLE) devices nearby. Whether you want to read the number of steps from your fitbit, or your heart rate from your iWatch, or read/write any type of data from/to BLE devices, this guide should help you along the way.
Currently, Bluetooth Low Energy (BLE) is not well supported by the standard Raspberry Pi distributions, thus some additional work is required to get it working. We describe in detail the steps you'll need to get your Raspberry Pi ready to start using Bluetooth LE.
Step 1: List of Materials
In this Instructable we'll be using the following materials:
Materials:
1 x Raspberry Pi 2 or 3 with a 5V USB Power Supply
1 x 8GB MicroSD Card
1 x USB Bluetooth 4.0 Adapter – – Most USB BLE adapters are RPi compatible (use CSR chip); check the compatibility here.
Tools (Optional):
Any BLE device (e.g., fitbit, cellphone, smartwatch)
Step 2: Getting the Operating System (Raspbian) on the MicroSD Card
To complete the rest of this tutorial you'll need to have your Raspberry Pi up and running. This process involves roughly 3 steps:
1. Using your computer to flash Raspbian onto the MicroSD Card
2. Inserting the card into the Raspberry Pi and powering the system
3. Running your first programs on the Raspberry Pi
In our "Getting Started with Raspberry Pi" tutorial, we show you how to go from unboxing your Raspberry Pi to running your first applications on it; be sure to check it out.
In addition, we've made a detailed video of the process:
Step 3: Configuring Raspbian to Use Bluetooth LE
By default, the Raspbian distribution comes without a Bluetooth stack. The bluez package is quite old and has patchy support for Low Energy. You can build and install a more modern version as described below.
After the system is up and running open up the Terminal program and a browser window, then start following the commands.
First, do not, I repeat, do NOT use the version available through aptitude. It is a very old version and doesn't work very well.
# Do NOT do this ->sudo apt-get install bluez
In case you have it already installed, go ahead and remove it. If you're not sure if you have it installed, go ahead and do this step anyway:
sudo apt-get --purge remove bluez
Next, we have to determine what's the latest version available. To do this, navigate to the official website https://www.kernel.org/pub/linux/bluetooth/ and look for the package bluez-X.XX.tar.xz where X.XX is the version. At the time of this writing the latest version is 5.34!
Then, go back to the Terminal on the Raspberry Pi and remembering to change X.XX for the latest version we find we enter:
cd ~; wget https://www.kernel.org/pub/linux/bluetooth/bluez-X.XX.tar.xz
Subsequently, we uncompress the package by:
tar xvf bluez-X.XX.tar.xz
We need at this point to make sure all the necessary libraries for running the bluetooth stack:
sudo apt-get install libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev
Are now ready to compile the bluez package:
cd bluez-X.XX
export LDFLAGS=-lrt
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-library -disable-systemd
make
sudo make install
For a strange reason the standard installation process misses installing one of the files to the correct directory. To solve this:
sudo cp attrib/gatttool /usr/bin/
And that's it! We're now ready to test out our Bluetooth LE USB Adapter on our Raspberry Pi!
Step 4: Connecting the Bluetooth LE USB Adapter
This is very straight-forward as the Raspbian Operating System is capable of detecting when the Bluetooth LED USB Adapter is hotplugged (i.e., plugged in when the system is running). This is great as we need not reboot in order to use the adapter. We can simply plug in the USB adapter to an available USB port.
And then ensure that the system has recognized it by going back to the Terminal and entering:
lsusb
The output should show the device as one of the entries.
Step 5: Testing the Bluetooth LE USB Adapter
Now that the Bluetooth LE USB Adapter is recognized by the system and we've successfully installed the Bluetooth stack, we're ready to test that we can access it. From the terminal we can first bring up the interface by:
sudo hciconfig hci0 up
And see if the device is up and running:
hciconfig
Should return the status of the BLE interface, in our case hci0. We can then move to the next step where scan for nearby BLE devices!
Step 6: Scanning for Nearby BLE Devices
After installing the Bluetooth stack and successfully added the Bluetooth LE USB adapter to our Raspberry Pi we're ready to scan for nearby BLE devices.
In our case, we've downloaded a Node.js App to a MacBook called Bleno. This very useful app allows us to set our laptop as a Peripheral Device. We've configured the app so that our peripheral device is named "I <3 Instructables" and echoes any message we send to it (for more details look at the examples in the Bleno repository).
Then, going back to the terminal in our Raspberry Pi, we run:
sudo hcitool lescan
Often times this command runs indefinitely, thus we can hit CTRL+C in order to stop it. From the output, we can pick up the MAC addresses of nearby BLE devices.
We can see that before we hit CTRL+C, the device is present in the output of the scan with a MAC address of 28:37:37:1A:D3:CF. We'll need this address in the next step, so make sure you're able to complete this before moving forward.
Step 7: Connecting to a BLE Device
One of our favorite features of Bluetooth 4.x is that, different than in previous versions, we need not go through the obnoxious pairing process to connect to a device. On our Raspberry Pi, we'll be using the program gatttool to connect to our nearby BLE device, and write/read data to/from it.
In the previous step we were able to get the MAC address 28:37:37:1A:D3:CF of the Peripheral Device that we're running through the Bleno app. To connect to this device we're going to use another tool part of the BLE stack we installed called gatttool. We're able to run this tool in an interactive mode so that we step through the process of issuing commands over BLE to our Peripheral Devices!
sudo gatttool -b 28:37:37:1A:D3:CF -I
Note that your MAC address will likely be different :) Also, you might need to add "-t random" to the list of arguments if you have trouble with the next steps. If you get device busy error simply remove the dongle and reconnect it.
Once you see the interactive prompt you can simply type connect and wait for the connection to be established. After getting the "Connection successful" message on the screen, we're now ready to start writing and reading data to and from the BLE Peripheral Device!
Step 8: Writing Data to a BLE Device
Now that we're connected to our BLE Peripheral Device, which in this case is a laptop running the Bleno Node.js app, we can use the commands primary and char-desc to list all the different services and characteristics available on the device.
In our case, our simple device only has 1 characteristic for writing data to it, and retrieving the last data that it received. The handle for this characteristic is 0x0026, thus within the interactive command line interface for gatttoolwe can:
[28:37:37:1A:D3:CF][LE]>char-write-req 0x0026 1234
This command sends the value "1234" to the handle 0x0026. We can verify that the command is received by looking at the debug messages of our Bleno app. In our case, the app prints out the value "1234" after receiving it!
In our final step, we'll proceed in a similar fashion in order to read back the value we've just written to the device.
Step 9: Reading Data From a BLE Device
Now that we've written some data to our BLE Peripheral Device it's time to read it! For this we make use of the same handle 0x0026, and again within the interactive command line interface for gatttool we can
[28:37:37:1A:D3:CF][LE]>char-read-hnd 0x0026
This command reads the value we last sent (which in this case should be "1234") to the handle 0x0026. We can verify that the request is received by looking at the debug messages of our Bleno app. In our case, the app prints out "EchoCharacteristic - onReadRequest: value = 1234" after receiving it!
16 Comments
Question 8 months ago
thank you for your informative post. I have successfully connected my Bluetooth-oxymeter. But i have a question, may be someone can help me. I want to create a database von SPO2 an Pulsation in my raspberry pi.
I want to take in real time the data of this oximeter on my raspberry Pi 3. Now I don't know how can I recover the displayed values of the oximeter on my Raspberry.
Question 2 years ago
Hello,
Firstly,thank you for this work and post here. It has really useful information. Since I am new at BLE technologies, I have some question on it. Why we use USB Bluetooth dongle instead of classic bluetooth of RPi in this work? Is there any theoritical explanation? I tried to use the classic bluetooth of RPi (BR/EDR), and I took some error after a certain time. But I know that if the RPi has bluez packets and then it can help us to conenct a BLE device.
Have a nice day :-D
3 years ago
If there is a date on the article I have missed it. The date is a really important thing and should be prominent near the title. Please change the site to date all articles clearly. (At least you date the comments, from which I guess this article is from around 2014
Question 4 years ago
Can you explain what these commands do?:
export LDFLAGS=-lrt
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-library -disable-systemd
make
sudo make install
---
iam getting this: :~/bluez-5.45 $ sudo make install
make: *** No rule to make target 'install'. Stop.
5 years ago
I just got a Raspberry Pi Zero W and installed Raspbian GNU/Linux 9.4 (stretch). After doing `sudo apt-get upgrade bluez`, it had an up-to-date version of bluez that ran hcitool and gatttool as described above -- no need to uninstall or compile anything. Happy!
6 years ago
Has anyone managed to talk to those new BLE relay modules available recently? The vendors only supply an android or apple app - no protocol info to drive from arduino or raspberry pi. (This style: http://www.icstation.com/2bit-relay-module-bluetooth-precise-android-apple-smart-home-switch-p-8463.html - there is another style ( http://www.tinyosshop.com/index.php?route=product/product&product_id=369 ) that uses *-bee modules and has a published serial protocol but those modules are much more expensive)
Reply 6 years ago
Hi gtoal,
did you get any further with those BLE relay modules?
I too, would like to control it from a raspberry pi3.
Until now, I have only an android app to switch it on and off.
Reply 6 years ago
I don't have any BLE modules yet. I've driven regular relays from pins on a pi successfully.
6 years ago
Very clear (and working) tutorial, thank you very much acrobotic!!!!
Just one question: how does the RPi 3 on-board Bluetooth module fit into this? E.g. hciconfig doesn't seem to recognise it at all.
Cheers
Reply 6 years ago
I read all the articles about Bluetooth LE on the Pi before I started exploring it on my Pi 3. They all said to compile Bluez but it turns out that there are other bits needed to get the Pi3 working with Bluetooth LE. In fact it seems to work perfectly with the version supplied by Raspbian.
Reply 6 years ago
Thanks brooOose,
Thanks for your response. I too spent a lot of time reading books and articles re BLE, including the Bluez compilation (and more fiddling) bit. After a couple of WEEKS without much progress, I could no longer afford the time and switched to XBEE. The serial comm between Arduino and RPi worked within an hour or so. :).
6 years ago
Fast forward a coulple of years and Raspbian is now based on Jessie and Bluez is on a later version (not the latest but good enough). Also the Pi 3 now has bluetooth buit in, and Raspian has extra stuff built in to support it. My advice now would be to just install everything from apt.
6 years ago
I am wondering whether step 3 is still necessary when using Raspberry Pi 3 (assuming the latest SO version), considering that RPi 3 has a build-in BLE and the SO seems to support it correctly...
7 years ago
I have a problem- for some reason, when I try to run hcitool lescan, I get the error: "set scan parameters failed: descriptor in bad state." How can I fix this?
8 years ago on Introduction
Really useful instructable! And it's also easy to follow. Well done!
It could be a nice addon for my Sphaera project...
Reply 8 years ago on Introduction
Thanks for the kind words! Speaking of useful, easy-to-follow projects... The Sphaera looks great, very well documented with plenty of descriptive pictures. You're right, even though you already have Wi-Fi in there, you could perhaps save a bit of power by adding on BLE for perhaps remote control of the camera. Thanks for sharing!