Hinweis: Diesen Blog schreibe ich ausnahmsweise auf Englisch, weil das Thema für viele Rasperry-Pi-Bastler interessant sein könnte.
Some days ago I started a project where I assembled a Bluetooth low energy (BLE) device that sends out some sensor data. In addition to reading these data with a smartphone I also want to receive and process them with a Raspberry Pi. However, it turned out that working with BLE on the Raspberry Pi is not as easy as I thought, especially if you want to write applications in Java or C/C++.
Finally I found a way to do it, and I would like to share it here for people who are looking for an easy entry into the world of BLE on the Raspberry Pi.
As prerequisites you need nothing more than a current Raspbian Jessie installation and a Bluetooth LE capable USB stick. The latter might not be necessary for a Raspberry Pi 3 since it should have Bluetooth already on board. And of course, a BLE device to test your setup is also quite helpful.
The setup procedure for the stuff you need to develop BLE applications consists of three steps:
- Install and test the bluez software stack
- Install cmake
- Install and test the tinyb library from the Intel® IoT Developer Kit.
If you want to work with Python you can stop already after the first step and try for instance the library from Adafruit (https://github.com/adafruit/Adafruit_Python_BluefruitLE) or the one from Ian Harvey (https://github.com/IanHarvey/bluepy).
1. Install and test bluez
If you look at the bluez web page (www.bluez.org) you will find that it is the “official Linux Bluetooth stack”. But what does that mean?
After installing bluez you can communicate with Bluetooth devices by using the D-Bus message bus system. A good introduction to that topic can be found in the paper “Playing BlueZ on the D-Bus”.
You might notice that the Raspbian Jessie installation already comes with bluez installed. However, it is an old version and BLE support is still patchy. So it’s best to remove it and install the latest version, which was 5.43 at the time of writing. The following command does the job:
> sudo apt-get --purge remove bluez
After you removed the old bluez installation you can do the following:
> sudo apt-get update > sudo apt-get install -y libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev > cd ~ > wget https://www.kernel.org/pub/linux/bluetooth/bluez-5.43.tar.gz > tar xvf bluez-5.43.tar.gz > cd bluez-5.43 > export LDFLAGS=-lrt > ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-library -disable-systemd > make > sudo make install > sudo cp attrib/gatttool /usr/bin/ > sudo cp ./src/bluetoothd /usr/local/bin/ > hash -r > sudo nano /etc/rc.local
Scroll to the end of file and just before the ‚exit 0‘ line add the following line
/usr/local/bin/bluetoothd --experimental &
Press Ctrl-O and enter to save the file, then Ctrl-X to exit the editor. The experimental parameter is important since without it some needed plugins will not be loaded.
After you have done all that you should be able to communicate with your BLE device. But first you might have to switch on the BLE stick on the Raspberry.
Check if the Bluetooth hardware is switched on by entering
If it is down just enter
> sudo hciconfig hci0 up
After that try the following
> sudo hcitool lescan
If you see your BLE devices listed you are nearly done. You should now test if you can connect to a device in the list. But take care: It is important to choose the correct address type (random or public). My device had “random” device address which means that the module uses a 48-bit address that was randomly generated during the manufacturing process.
To test the connection to a BLE device that was discovered by the scan you can enter:
> sudo hcitool lecc --random <address>
where you replace <address> with the BLE device address (MAC address format XX:XX:XX:XX:XX:XX). Alternatively, for an interactive session you can use:
> sudo gatttool -t random -b <address> -I
In both commands you should omit the “random” parameters if your device has a public address.
2. Install cmake
Although cmake can be installed by using the package manager (apt-get) you will only get an old version. To install the tinyb library later we need a newer version that can be installed by the following commands.
If you already installed the version from the repository remove it with
> sudo apt-get --purge autoremove cmake
Afterwards just execute the following lines (assuming 3.6.2 is the current stable release):
> sudo apt-get install build-essential > cd ~ > wget http://www.cmake.org/files/v3.6/cmake-3.6.2.tar.gz > tar xvf cmake-3.6.2.tar.gz > cd cmake-3.6.2 > ./configure > make > sudo make install > hash -r
Consider having some coffee during installation since it really takes time to configure the Makefile and build cmake.
Since cmake does not configure the currently installed JDK you can either manually correct the following file
or (as I did) just export the following variables (replace the path with your JDK installation directory; I used Java 8 JDK from Oracle):
export JAVA_HOME=/usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt export JAVA_AWT_LIBRARY=/usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt/jre/lib/arm/libawt.so export JAVA_JVM_LIBRARY=/usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt/jre/lib/arm/server/libjvm.so export JAVA_INCLUDE_PATH=/usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt/include export JAVA_INCLUDE_PATH2=/usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt/include/linux export JAVA_AWT_INCLUDE_PATH=/usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt/include
These export statements are important to correctly build the tinyb library for Java.
3. Install tinyb
tinyb (https://github.com/intel-iot-devkit/tinyb/) is a BLE library from the Intel® IoT Developer Kit. If you want to develop applications in Java or C/C++ and do not want play with D-Bus yourself it is extremely helpful. With bluez and cmake set up as described before it should be a piece of cake.
Just do the following:
> cd ~ > git clone https://github.com/intel-iot-devkit/tinyb > cd tinyb > mkdir build > cd build > cmake -DBUILDJAVA=ON .. > make > sudo make install
That should have been everything. To test if tinyb is working you can execute the following commands:
> cd ~/tinyb/build > sudo ./examples/hellotinyb <address>
Or for Java:
> cd ~/tinyb/build > sudo su > export LD_LIBRARY_PATH=/usr/local/lib > java -cp examples/java/HelloTinyB.jar:/usr/local/lib/java/tinyb.jar HelloTinyB <address> > exit
Although the HelloTinyB programs were designed to work with the TI sensor tag they should be able to discover the BLE device and list its services.
The Java and C++ examples coming with the tinyb library should be sufficient to start building your own applications. In addition the Intel web page https://software.intel.com/en-us/java-for-bluetooth-le-apps contains an introduction for how to write a BLE Java application.
I hope this little blog can help you to start writing BLE applications quickly without spending too much time to setup the BLE basic stack on the Raspberry Pi. If you find it helpful please leave me a comment.
And finally, for a general introduction to BLE I can highly recommend this guide from Adafruit: https://learn.adafruit.com/introduction-to-bluetooth-low-energy/introduction.
PS: Stay tuned for the blog about setting up my BLE sensor project.