BLE with RFduino, Linux and Python!!

Spread the love

I was working on a project which needed a nice way of wireless communication with an external device. Well, it was difficult to find any sort of documentation for getting it done, so had to figure it out on my own.
Windows(other than the latest Windows 10) doesn’t have any BLE 4.0 supporting stack, so you will have a tough luck there. MacOSx has lightblue, but I couldn’t get it working on Yosemite.
Getting back, you might ask, what is BLE, and why use it?
BLE stands for Bluetooth Low energy, which is the Bluetooth 4.0 protocol for wireless communication. Bluetooth v2 is designed to work as Serial communication, but BLE is different. It has been designed to connect multiple devices to bluetooth passively. Some of the places that BLE is in use are smart bands, beacons etc.
RFduino here:
When we came across this, we knew that it was exactly what we wanted to use.
Getting it to work
Linux has support for the Bluez stack, which supports Bluetooth 4.0, but the current Ubuntu binaries don’t have this version. So you need to manually get and install it. Not too complicated though.
Steps:
1-  Install Dependencies:
sudo apt-get install libdbus-1-dev libdbus-glib-1-dev libglib2.0-dev                           libical-dev libreadline-dev libudev-dev libusb-dev make

2- Get Bluez and install
wget https://www.kernel.org/pub/linux/bluetooth/bluez-5.32.tar.xz
tar xvf bluez-5.32.tar.xz
cd bluez-5.32
./configure --disable-systemd
make
sudo make install

Test it:
You can test whether everything is properly set up by using hciconfig. It will list all the adapters and their states.
hciconfig

In case your adapter is DOWN, you can get it back up by using:
sudo hciconfig hci0 up

Do a scan for BLE devices using:
sudo hcitool lescan

Coding time: 
Now,  I wanted to use Python to interact with my Rfduino devices. I have used a library that make the job easy – pygattlib
Note: If you want to use Bluetooth 2.0 devices with Python, follow same steps as above, with the library being pybluez and scan command being sudo hcitool scan
Once you have this we are up and running!
pyGATTlib gives 2 objects GATTRequester and GATTResponse to efficiently interact with BLE devices. Let’s set it up for one of our devices:

from gattlib import GATTRequester
req = GATTRequester("XX:XX:XX:XX:XX:XX", False)

Here, the first parameter for the object is the Bluetooth MAC address and the second parameter is whether you want to connect to the device. Connect to the device either by setting it to true or using req.connect(True)
Unfortunately, only a single device can be connected to in PyGATTlib, so to connect to another board, you need to disconnect from the previous one.

req2 = GATTRequester("XX:XX:XX:XX:XX:XX", False)
req.disconnect()
req2.connect(True)

BLE relies on a request response cycle. A device requests the other some data for a handle and gets a response. The handle for RFduino’s transmitted data is 0x000e, and so you can easily get a response by using:

resp = req.read_by_handle(0x000e)

For building an async(non-blocking response), we build a response object for getting our responses from RFduino and get the response. This was essentially helpful for me as I wanted to not block my application(a game) at any time.

response = GATTResponse()
req.read_by_handle_async(0x000e, response)
while True:
  if response.received():
    # Read response
    resp = response.received()[0]
  # Keep doing something else

Finally, RFduino code, it simply is a publisher, which keeps publishing forever. There is an onConnect listener which will trigger the RFduino to keep sending data.

#include <RFduinoBLE.h>
int initialized = 0;
void setup() {
  RFduinoBLE.advertisementData = "my_board";
  // start the BLE stack
  RFduinoBLE.begin();
}
void loop()  {
  if (initialized) {
    RFduinoBLE.send(0xff);
    delay(1000);
  }
}
void RFduinoBLE_onConnect() {
  initialized = 1;
}
void RFduinoBLE_onDisconnect() {
  initialized = 0;
}

Additionally, for a request response cycle, an onReceive listener can be used which gets some data from the requester.

void RFduinoBLE_onReceive(char *data, int len) {
}

And done, you will be able to use RFduino with a PC application.

You may also like...

Leave a Reply

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