BeaconAir iBeacon Portable Pi
Here is a picture of the completed BeaconAir Portable Pi project. It’s not much to look at, but it works. BeaconAir is a Raspberry Pi based project that reads the advertising packets coming from iBeacons and roughly calculates the physical position of BeaconAir by Trilateration. Trilateration is the method of determining the position of a point, given the distance to three control points.
In the BeaconAir case, we wait until we see three iBeacons and then we determine our position based on the relative strengths of the signals compared to their transmitted power at 1M.
iBeacons
Below is a mis-sized MouseAir 3D printed box (more on that later) containing 5 iBeacons. Three Estimote iBeacons and two Particle (KST Technologies) iBeacons.
An iBeacon advertising packet looks like this (after being read and parsed by our python iBeacon scanning software):
cf:68:cc:c7:33:10,b9407f30f5f8466eaff925556b57fe6d,13072,52423,-74,-78
The values are:
- Beacon MAC Address:
cf:68:cc:c7:33:10
- iBeacon UDID
b9407f30f5f8466eaff925556b57fe6d
- iBeacon Major Number
13072
- iBeacon Minor Number
52423
- TX Power at 1m
-74
- RSSI (Received Signal Strength Indication)
-78
Comparing the Tx Power at 1m (-74) to the RSSI of -78, you can see that the iBeacon is a little more than 1m from your current position. Understand that there are a lot of things that can interfere with this reading. Your body, humidity, other people in the room, furniture, cats, etc. It’s not very accurate. More on determining approximate distance and position next week.
Here is my RasPiConnect BeaconAir control panel showing the location of the Pi with a red pin. I love control panels.
Dear John,
It’s very interested topic. Thanks you for your post.
How do you calculate distance and position ? Do you use this formula ?
protected static double calculateAccuracy(int txPower, double rssi) {
if (rssi == 0) {
return -1.0; // if we cannot determine accuracy, return -1.
}
double ratio = rssi*1.0/txPower;
if (ratio < 1.0) {
return Math.pow(ratio,10);
}
else {
double accuracy = (0.89976)*Math.pow(ratio,7.7095) + 0.111;
return accuracy;
}
}
Thanks John.