Can RaspberryPi with BLE Dongle detect iBeacons?

user1153660 picture user1153660 · Feb 12, 2014 · Viewed 57.4k times · Source

I bought a developer kit from Radius Networks that includes a ioGear GBU521 BLE 4.0 dongle and a Raspberry Pi. I also bought one of their RadBeacon iBeacons. They both work as advertised, but I was kind of surprised by what I got.

I had assumed that the RaspPi could detect iBeacons. Instead, the kit is setup to create an iBeacon. My use case is to detect when a forklift enters a particular room so I can send work to them. My thought was to put an iBeacon on the forklift then put a RaspPi searching for iBeacons. And when an iBeacon (forklift) was detected, you could conclude that it is nearby. I would wire the RaspPi into the LAN and have it communicate the information via REST or similar. I know I could put a suitable Android or Apple device and accomplish it that way, but I don't see why this dongle can't detect these iBeacons and tell me what their UUID's are? What am I missing?

Answer

jjnebeker picture jjnebeker · Feb 14, 2014

Yes! You can use your Raspberry Pi to scan for iBeacons. We've put together a script below that does this, you can also do it yourself with these steps:

  1. Start a background process that does a bluetooth LE scan:

    sudo hcitool lescan --duplicates &
    

    With the --duplicates setting the scan will not ignore multiple packets from the same iBeacon.

  2. Start an hcidump and pipe the raw output to a script that will filter for iBeacon packets:

    sudo hcidump --raw 
    

The filtering is the tricky part, the raw output from hcidump isn't formatted nicely and also shows packets that aren't iBeacon transmissions. To solve this, we made a filter script that reads in the output line by line and separates out the raw packets from the other output (i.e., MAC addresses, etc.). We've done a lot of research at Radius Networks on the iBeacon bluetooth profile, which we used to identify iBeacon packets and filter them out from packets from other devices.

We've put this all together into an ibeacon_scan script that does everything, including converting the raw identifiers into human-readable form. You can download it here. Soon, we'll include this in the iBeacon Development Kit to add scanning capability.

Here's an example of the output from the script:

$ ./ibeacon_scan
UUID: 74278BDA-B644-4520-8F0C-720EAF059935 MAJOR: 0 MINOR: 73 POWER: -50
UUID: 2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6 MAJOR: 1 MINOR: 6 POWER: -59
UUID: E2C56DB5-DFFB-48D2-B060-D0F5A71096E0 MAJOR: 6 MINOR: 9 POWER: -55

We've also included a -b option for bare output that is easy to parse into other scripts, here's an example:

$ ./ibeacon_scan -b
2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6 1 6 -59
E2C56DB5-DFFB-48D2-B060-D0F5A71096E0 6 9 -55
74278BDA-B644-4520-8F0C-720EAF059935 0 73 -50

You can use this option and pipe the script's output to your script to trigger actions when iBeacons with certain identifiers are detected.

EDIT: We've reworked this script to make it more responsive and robust and incorporated it into the latest version of the development kit. The update is available to download here.

EDIT2: As pointed out by @sai-ramachandran, you can augment this script to capture the RSSI of each iBeacon packet in addition to POWER. To do this, add the following lines to the script:

 RSSI=`echo $packet | sed 's/^.\{132\}\(.\{2\}\).*$/\1/'`
 RSSI=`echo "ibase=16; $RSSI" | bc`
 RSSI=$[RSSI - 256]

and be sure to add RSSI to the output:

 echo "UUID: $UUID MAJOR: $MAJOR MINOR: $MINOR POWER: $POWER RSSI: $RSSI"