Getting Rfduino working with Linux

Intro:

I ordered this nifty ‘RFduino’, an arduino-compatible device which was also my first ever kickstarter purchase over a year ago now.
However, when the device arrived, the company behind it seemed exclusively interested in the iPhone handset to the detriment of all other platforms.
Personally, the lock in monopolistic attitude of Apple and its customers really gets my goat, but I digress.

The lack of support and that the device arrived half a year late left me with a sour first taste of Kickstarter.

Since then, I’ve played with the Rfduino using JT’s iGear (no, I don’t know why fell into the Apple pit either) using the only app available to use the sketch it comes with – the internal thermometer

But that’s rather limiting!! I bought this device with plans to build a Wireless ‘Internet of Things’ sensor network for my house.

I have designs on talking to every platform available using protocols such as mqtt, backends like rrdtool and web interfaces for my housemates to see and control the action.

This is something I’ve been dreaming and sketching out  for years, because lets face it, who doesn’t think having the lights turn out when you leave is super cool?

So without further ado, how do we get the RFduino to talk to a linux machine, in my case a Raspberry Pi running Raspbian.

Ingredients:

Hardware:

You will need

  • Internet connection to download tools
  • Bluetooth packages installed (bluez-tools)

Howto:

Power on the  RFduino and linux machine. I used two Alkaline AA batteries to power the RFduino although Rechargeables do work.

Install the Bluetooth 4 usb adaptor on the linux machine
Install the necessary bluetooth programs:

sudo apt-get install bluetooth bluez bluez-utils bluez-firmware

(you may need to reboot the machine afterwards, I don’t believe I did)

Bring up the bluetooth interface:

sudo hciconfig hci0 up

Run a Low Energy scan to find the address of your RFduino:

sudo hcitool lescan

Should elicit results similar to this:
EA:BA:20:48:37:80 (unknown)
88:D8:CD:08:12:FA (unknown)
99:D8:CD:10:66:FA (unknown)
DD:AF:13:17:23:80 RFduino

Select and copy the MAC address given for the RFduino on your system.

(I have no idea why you have to scan as root, someone please leave a comment if you do, and if theres a way to run as a normal user…groups?)

 

Read the temperature attribute from the RFduino using gatttool. Paste your devices MAC address in instead of mine of course.

sudo gatttool –device=DD:AF:13:17:23:80 –interactive
[   ][DD:AF:13:17:23:80][LE]>
[   ][DD:AF:13:17:23:80][LE]> connect
[CON][DD:AF:13:17:23:80]][LE]>char-read-uuid 2221
[CON][DD:AF:13:17:23:80][LE]>
handle: 0x000e value: 00 00 a8 41 00 00 00 00 00 00 00 00
[CON][DD:AF:13:17:23:80][LE]>disconnect
[   ][DD:AF:13:17:23:80][LE]>quit

Now from that exchange with the RFduino, we have gained a long hexadecimal string.
From a post on the RFduino forum, I learned that the value we want is always after the ’00 00′ string (in bold above).
This is the temperature read from the RFduino’s internal sensor * 8.
So we need to convert this to Decimal and divide by eight to retrieve the temperature value in celsius (American readers, why aren’t you on SI units yet? :P).

Convert the hex value to decimal temperature

decimal=$((0xa8))
decimal=$(($decimal/8))
echo $decimal
21

The above method returns an integer value. This is because Bash has limitations working with numbers that are not whole (decimals).
Workarounds use the command bc to interpret string inputs as decimal numbers. I think there is a method to define variable types in bash, but I didn’t get very far with this.

My attitude is that once you start hitting the limitations of a shell scripting language, it’s time to migrate to a proper programming/interpreted language (at least python).
Spending hours and using multitudes of additional programs make it work is often pointless.

Just think, if you had to run the script on a embedded system without most of those commands, wouldn’t it just be better to do it in C++?

 

Next time:

Now that I’ve successfully read the values being sent by the RFDuino I need to figure out how to automate the process – in non-interactive mode.

These commands do the same thing but respond differently

sudo gatttool -b [MAC] –char-read  –handle=0x000e
Characteristic value/descriptor: 00 00 a8 41 00 00 00 00 00 00 00 00

sudo gatttool -b [MAC] –char-read –uuid=2221
handle: 0x000e   value: 00 00 a8 41 00 00 00 00 00 00 00 00

Simple bash script to read temperature in celsius (accuracy is lost here as the decimal is converted to an integer)

#!/bin/bash
stringZ=$(gatttool -b [MAC] –char-read  –handle=0x000e)
stringZ=${stringZ:39:2}
hex=$((0x$stringZ))
decimal=$(($hex/8))
echo $decimal
exit

don’t forget:
chmod +x [whatever you called the script]

and run it as root:
sudo [whatever you called the script]

Afterword:

I won’t pretend to understand the naming conventions of Bluetooth 4.0/LE.
I don’t! I spent a whole day looking into it and could not find a single source that easily explained the structure, naming, and profiles. If someone has seen something good, please post in the comments!

It’s frustratingly close, like I can see there is a neat logic to it, but I just don’t care to spend any more time trying to figure it out, when all I want to do is use it. This does make it slightly more hacky and less neat and quick of course, but that’s life!

 

Sources:

gattool commands to read the sensor:
http://lilyhack.wordpress.com/2014/02/03/ble-read-write-arduino-raspberry-pi/

howto convert hex to decimal on the command line:
http://linuxcommando.blogspot.co.uk/2008/04/quick-hex-decimal-conversion-using-cli.html

howto do calculations on the command line:
http://www.tldp.org/LDP/abs/html/arithexp.html

Hacked up way of using gatttool non-interactively, using ncurses and a python script:
http://thomasolson.com/PROJECTS/BLE/RFduino/LINUX/

Bash string manipulation:

Bash String Manipulation Examples – Length, Substring, Find and Replace

Others:

http://joost.damad.be/2013/08/experiments-with-bluetooth-low-energy.html

10 thoughts on “Getting Rfduino working with Linux

  1. Mats Karlsson

    The Americans are getting closer the SI-unit system, inch by inch. 😉

    I like this article and is looking forward to read more.

  2. John Weir

    I recently bought a RFduino and have been tinkering with it a bit over the last few days. Installed some RFduino app for my phone that seems to be rather inconsistent, and that’s being kind. It works about 20% of the time.

    This provided some insight into connecting the device to a BT 4.0 USB dongle I had purchased. Data came through just fine — the script doesn’t work as the format of the data returned is somewhat different apparently. Don’t really care about that so much, though.

    My intention with the RFduino is to be able to pass I2C/SPI/serial data wirelessly. I have BT serial/SPP adapters that work reasonably well, so that’s not such a requirement.

    I’m just getting into the hobby, so I’m really just poking around at individual components such as sensors and whatnot presently. Interesting stuff.

  3. garreth Post author

    Any progress? I’m thinking of using mine with a dht22 temperature and humidity sensor (i²c) and also ws2812b digital RGB LED (neopixels)

  4. Sam

    Hi,
    Interesting project. thank you for sharing Can we use this techniques for sending live stream of music over BLE4.0 ?
    (connecting music player to Rpi and RFduino to the speaker?

    Thanks

    Regards
    Sam

  5. garreth Post author

    Hi Sam, it’s been a while but i’m replacing my previous rude reply!
    You couldn’t use this technique for audio transmission over bluetooth.
    This is using afaik advertising frames which are transmitted broadcast.

    For bluetooth audio you’d need to be using one of the well defined bluetooth services such as ‘headset’ etc.
    I’ve had a look but it doesn’t look like the rfduino supports this.

    Mainly it’s meant for transmitting basic data at low data rates (and low energy use) for things such as heartrate monitors, cycle computers and such like.

    I really don’t understand all the nomenclature of bluetooth (it makes my head spin every time I look into it), but these ‘GATT Characteristics’ [https://www.bluetooth.com/specifications/gatt/characteristics] are the predefined types of data that could potentially be transmitted/received by the rfduino. As far as i know the rfduino defaults to using generic gatt services [http://forum.rfduino.com/index.php?topic=266.0].

  6. Anonymous

    Americans moving toward SI inch by inch is too fast. We are millimetering instead. Why Americans don’t use SI yet is the same reason America doesn’t have a healthcare system like a developed country yet. We have too many idiots voting for the likes of a Trump. By the time we have either, the Cubs will win another World Series – and we’ll be building starships before that!

  7. garreth Post author

    Hi Anonymous,

    One day SI units will rule the world. Lol

    @Mats, i hope to add a blog post on my current Arduino uses. One is a hardware watchdog for one of my raspberry pis that reboots it if it stops responding to pings.

    My rfduino is sadly in the bottom of my parts bin. I’ve tried several times to get it to do something useful, first with android app & Arduino sketch/library ‘Arduino manager’ and then a few months back Blynk android app & arduino sketch/library.
    Sadly i haven’t been able to get a connection in Blynk with generic bluetooth BLE profile, and Arduino Manager seemed a bit too complicated last time i tried it (I paid for the full version no less).

    I have a couple usb bluetooth dongles lying around somewhere though so I may revive it for use with linux on a raspberry pi, you never know!

Leave a Reply

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