Another really fun thing to do in wireless networks is finding your distance from another transceiver using signal strength values. Because of noise, multipathing, and various things that impede wireless signals (such as fleshy, water-filled human bodies), it is impossible to get very fine-grain estimations from RSSI values alone. From my research, it seems that a resolution of ~1m is as good as it gets. Which means if you don't have a good equation modeling the environment in which your network is deployed, your results will be horrible.
Distance Equation:
After searching all over the internet and the IEEE Xplore library, I have finally found an equation that works relatively well for RSSI/distance estimation from this
journal article.
RSSI = -(10*n*log10(d) + A)
Where
- RSSI is the RSSI value received (dBm)
- n is the path-loss exponent
- d is the distance
- A is the RSSI value at a reference distance
So what is the path-loss exponent? How do you select a value for A?
Path Loss Exponent:
The path loss exponent has to be determined experimentally. The path loss variable ranges from around 2 to 4, where 2 is the free-space value (no obstruction, line of sight) and 4 represents a very lossy environment. A simplified form of the model is represented below from
wikipedia, however, a more detailed one can be found
here.
, where L is the path loss in dB, n is the path loss exponent, d is the distance between transceivers, and C is a constant which accounts for system losses.
This table from this
Zigbee book gives sample path loss exponent values for common environments:
Selecting the Reference Value:
A can be found by measuring the RSSI value at whatever distance you want to reference. My measurements are taken in meters, so
A is the RSSI value received when the receiver is 1 meter in front of the transmitter with no obstacles in between.
Implementation on XBee:
So far this has been all talk. Let's see how this works in a real environment.
I will be testing this formula out using XBee series 2 modules and
these antennas (Digi P\N: A24-HASM-525). This antenna is important, as it is an omni-directional antenna; meaning it has a relatively uniform radiation patter. Most chip antennae have a very non-unimform radiation pattern, causing the RSSI value to fluctuate drastically due to the orientation of the nodes, rendering everything we are trying to do here useless.
My experimental setup involves two series 2 XBees, one coordinator and one end device. The end device is attached to a Sparkfun RedBoard (arduino clone). The coordinator is connected to my laptop using a Sparkfun XBee Xplorer board. The RedBoard is running code written using Atmel Studio and my XBee library which echos back to the sender the RSSI value and estimated distance.
I have set the following function to be called when a new packet arrives using "setNewPacketCB()". This function retrieves the RSSI value and applies the formula above to estimate distance and return it to the sender.
float A = -45.0; // Reference RSSI value at 1 meter
float n = 2.2; // Path-loss exponent
void newPacket()
{
RxPacket rx_data = getPacket();
// Echo rssi value back
int len = 1; // sprintf buffer length
float distance;
char buff[20];
char rssi = getRSSI();
if(rssi != 0xFF) // 0xFF is error code when value is not returned
{
// sign in front of rssi changed to positive because rssi value from XBee is negative
distance = pow(10.0,((A + rssi)/(10.0*n)));
len = sprintf(buff, "%d + %3f\n",(unsigned int)rssi, distance);
ZigBee_TX_Request(0,0,0xFFFF,rx_data.source_addr_16bit, 1, 0, buff, len);
}
}
For this code to work you will need to ensure that you are using the floating point math library and floating point version of printf. To compile properly in AVR/Atmel Studio:
- Go to Project->Properties (ALT+F7) and under AVR/GNU C++ Linker select Libraries. Under Libraries (-Wl,-l) use the Add button twice and insert libprintf_flt then libm
- Go to Miscellaneous and add -Wl,-u,vfprintf -lprintf_flt -lm
After downloading my code to the RedBoard and connecting the coordinator to the laptop, if I open up a terminal using X-CTU connected to the coordinator and hit enter, I get the following output:
Where 51 means the RSSI value received was -51 dBm and the estimated distance was 1.87 meters.
Before testing, I recorded the RSSI value at one meter away, which gave me a value of -45dBm. Plugging this into the A variable in my code and setting n to be 2.2 (Choosing the n value for a retail store from the chart since the building I'm working in is somewhat similar. Sadly, this was a terrible first guess) I downloaded the code and set up my laptop in the hallway of the EPIC building at UNCC. I placed sticky note markers at various lengths to move my end device to for measuring.
Results:
I have unfortunately learned that hallways behave as giant waveguides, so my results were not spectacular. In a hallway, the multipathing effect is very high, so after certain distances away from the transmitter, the receiver begins to hear the same signal reflected back into itself, amplifying the value.
This is very bad for trying to estimate distance because you can't get any information out of the data because it doesn't attenuate as you move farther from the source as it would in free space. The following chart shows my results from the hallway test:
As you can see, the data is all over the place. However, multipathing was not the only problem in the test environment. I needed to reverse calculate the path-loss exponent by using the distance formula to solve for
n by plugging in measured RSSI values at known distances. After changing the path loss exponent to 2, the following values were obtained:
This new
n value caused less fluctuation in distance estimation results, but as the multipathing effect caused the signal to attenuate very slowly, it became indistinguishable at larger distances. I also took fewer data points having realized the hallway was going to produce these results.
I plan to test this code again in a large, open space, so be sure to check back later for those results!