Search code examples
swiftxcodebluetoothcore-bluetoothrssi

Swift - Converting RSSI to Distance


I was doing some work using the CoreBluetooth API and ran into a problem. All of the places I have looked, they say that to convert RSSI (Signal Strength of Bluetooth), you must do things like:

Distance = 10 ^ ((Measured Power – RSSI)/(10 * N))

And:

var txPower = -59 //hard coded power value. Usually ranges between -59 to -65

if (rssi == 0) {
  return -1.0; 
}

var ratio = rssi*1.0/txPower;
if (ratio < 1.0) {
  return Math.pow(ratio,10);
}
else {
  var distance =  (0.89976)*Math.pow(ratio,7.7095) + 0.111;    
  return distance;
}

I have tried all of the above and everything I could find. None of it gets me the accurate measurements from about 0.5 meters to around 5 - 7 meters of distance between.

My code to do so is making both phones using the app as a central and peripheral Bluetooth and in my didDiscoverPeripheral callback from CentralManager, I get the RSSI - which I want to convert to a distance (meter, feet).

Along with that:

I also need to find out how to get the Measured Power (RSSI Strength at 1 meter) of iPhones as it would really help in the accurate calculations.

Also, what does environmental factor mean in terms of Bluetooth? What do the different environmental factors mean (which have the range of 2-4). Is there a way to change or increase the Broadcasting Power value of the Apple Device?

Basically, I am looking for an accurate RSSI to distance formula which works from distances from 0.5 meter to 5-7 meters

Thank you so much!


Solution

  • This is what is a common solution:

    pow(10, ((-56-Double(rssi))/(10*2)))*3.2808
    

    It was good for most distances but got very inaccurate as you get close or too far, so I ended up using bins kind of like Apple's iBeacons (Unknown, Far, Near, Immediate). If the raw RSSI is less than -80, then it is far, if it is more than -50, then it is immediate, and if it is between those two, it is near. This solution worked for me.