There are many indoor positioning systems has been developed in past few years ranging from IR based systems up to RF based and Ultra-Wide Band based Indoor positioning systems. Even the modern-day development is working on LiFi based Indoor Positioning systems as well. Today we are going to discuss about the code and algorithm based on NodeMCU ESP8266 based Wi-Fi RSSI based Indoor positioning system with Arduino.
Block Diagram of Indoor Positioning Algorithm
Here is the overall higher level block diagram and flow of the complete indoor positioning algorithm we used in this post.
Calculate WiFi Access Point SSID and RSSI
We can calculate the RSSI of the available Wi-Fi access points using the ESP8266 and for the Arduino code here is the code.
#include <ESP8266WiFi.h>
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA); // Set Wi-Fi to station mode
WiFi.disconnect(); // Disconnect from any network
delay(100);
}
void loop() {
int numNetworks = WiFi.scanNetworks();
for (int i = 0; i < numNetworks; ++i) {
Serial.print("SSID: ");
Serial.print(WiFi.SSID(i));
Serial.print(" | RSSI: ");
Serial.print(WiFi.RSSI(i));
Serial.println(" dBm");
}
delay(5000); // Wait for 5 seconds before scanning again
}
Code language: Arduino (arduino)
Here is the available output example
SSID: Automation Engineering | RSSI: -60 dBm
SSID: project | RSSI: -42 dBm
SSID: ALI TRADERS | RSSI: -71 dBm
SSID: V-DSL Modem | RSSI: -72 dBm
SSID: AB Power | RSSI: -90 dBm
SSID: ok bye | RSSI: -83 dBm
SSID: Real Tech | RSSI: -73 dBm
SSID: DIGITAL | RSSI: -73 dBm
SSID: HAMIDRC | RSSI: -88 dBm
SSID: DAWOOD | RSSI: -87 dBm
SSID: HP-Print-79-LaserJet Pro M201dw | RSSI: -88 dBm
SSID: Hussain raza | RSSI: -64 dBm
SSID: PTCL-BB | RSSI: -76 dBm
SSID: FTC ZUBAIR | RSSI: -59 dBm
SSID: PTCL-DBCE | RSSI: -64 dBm
SSID: Abdul Qadeer | RSSI: -82 dBm
SSID: Infinix HOT 40i | RSSI: -90 dBm
SSID: Automation Engineering | RSSI: -57 dBm
SSID: project | RSSI: -48 dBm
SSID: ALI TRADERS | RSSI: -71 dBm
SSID: V-DSL Modem | RSSI: -80 dBm
SSID: TANVEER TREADERS | RSSI: -80 dBm
SSID: DIGITAL | RSSI: -71 dBm
SSID: Computer.. | RSSI: -88 dBm
SSID: HUAWEI | RSSI: -76 dBm
SSID: ME | RSSI: -87 dBm
SSID: Hussain raza | RSSI: -69 dBm
SSID: V2043 | RSSI: -89 dBm
SSID: FTC ZUBAIR | RSSI: -56 dBm
SSID: PTCL-DBCE | RSSI: -80 dBm
SSID: MAHER ELECTRONICS | RSSI: -82 dBm
SSID: Automation Engineering | RSSI: -63 dBm
SSID: project | RSSI: -55 dBm
SSID: V-DSL Modem | RSSI: -84 dBm
SSID: Real Tech | RSSI: -73 dBm
SSID: ALI TRADERS | RSSI: -76 dBm
SSID: DIGITAL | RSSI: -72 dBm
SSID: Hussain raza | RSSI: -67 dBm
SSID: PTCL-BB | RSSI: -76 dBm
SSID: FTC ZUBAIR | RSSI: -54 dBm
SSID: Abdul Qadeer | RSSI: -85 dBm
SSID: PTCL-DBCE | RSSI: -70 dBm
SSID: Infinix HOT 40i | RSSI: -91 dBm
SSID: Automation Engineering | RSSI: -68 dBm
SSID: project | RSSI: -52 dBm
SSID: ALI TRADERS | RSSI: -69 dBm
SSID: V-DSL Modem | RSSI: -77 dBm
SSID: TANVEER TREADERS | RSSI: -83 dBm
SSID: Real Tech | RSSI: -71 dBm
SSID: Hussain raza | RSSI: -66 dBm
SSID: Abdul Qadeer | RSSI: -78 dBm
SSID: FTC ZUBAIR | RSSI: -56 dBm
SSID: PTCL-DBCE | RSSI: -67 dBm
SSID: PLA | RSSI: -87 dBm
Code language: HTTP (http)
Trilateration Algorithm
This trilateration algorithm estimates the position of a device based on RSSI (Received Signal Strength Indicator) values from three known Wi-Fi access points (APs). First, the device scans for Wi-Fi networks and collects RSSI values for the specified APs. These RSSI values are then converted into distances using a predefined formula. The trilateration equations utilize the distances and known positions of the APs to calculate the unknown position of the device. By solving a series of linear equations, the algorithm determines the device’s coordinates in a 2D space. Finally, the code computes the change in position between iterations to provide distance changes in centimeters, allowing for precise location tracking.
- Example calculation
- Coordinates of Access Points (APs):
- (x1,y1)
- (x2,y2)
- (x3,y3)
- Distances from each AP:
- d1
- d2
- d3
- Coordinates of Access Points (APs):
- Step-by-Step Equations:Step 1: Calculate A, B, C, D, E, and F
- A=2(x2−x1)
- B=2(y2−y1)
- C=d12−d22−x12+x22−y12+y22
- D=2(x3−x2)
- E=2(y3−y2)
- F=d22−d32−x22+x32−y22+y32
- x=C⋅E−F⋅BE⋅A−B⋅D
- y=C⋅D−A⋅FB⋅D−A⋅E
So based on Above available SSIDs and their RSSI values we can estimate things like this.
Sure, let’s break down the data to estimate your position based on the RSSI values collected during your movements:
Step-by-Step Analysis
- Identify Key Access Points (APs):
- We’ll use the three strongest signals for trilateration:
- SSID: Automation Engineering
- SSID: project
- SSID: FTC ZUBAIR 03704195020
- We’ll use the three strongest signals for trilateration:
- Convert RSSI to Distances:
- RSSI to distance conversion is done using a model. Here’s an example formula:
- distance=10(RSSI reference−RSSI)/(10⋅n)
- Assume RSSI reference = -50 dBm at 1 meter, and n=2
- RSSI to distance conversion is done using a model. Here’s an example formula:
- Estimate Distances:
- For simplicity, let’s assume fixed reference points for the APs.
- Example distances (you’ll need to calibrate this for your environment):
- Automation Engineering (-60 dBm) -> d1≈3.16 meters
- project (-42 dBm) -> d2≈0.63 meters
- FTC ZUBAIR 03704195020 (-56 dBm) -> d3≈2.51 meters
- Trilateration Calculation:
- Assume positions:
- AP1 (Automation Engineering): (x1,y1)=(0,0)
- AP2 (project): (x2,y2)=(10,0)
- AP3 (FTC ZUBAIR 03704195020): (x3,y3)=(5,10)
- Use the following simplified equations to solve for x and y:
- A=2⋅(x2−x1)
- B=2⋅(y2−y1)
- C=d12−d22−x12+x22−y12+y22
- D=2⋅(x3−x2)
- E=2⋅(y3−y2)
- F=d22−d32−x22+x32−y22+y32
- Solve for x and y.
- Assume positions:
Indoor Positioning Algorithm Arduino Code
Here is the complete code for the Indoor Positioning system with Wifi based RSSI and Trilateration Algorithm.
#include <ESP8266WiFi.h>
// AP positions (x, y) in centimeters
float x1 = 0, y1_ap = 0; // Example coordinates for AP1
float x2 = 1000, y2_ap = 0; // Example coordinates for AP2
float x3 = 500, y3_ap = 1000; // Example coordinates for AP3
// Function to scan networks and get RSSI
void scanNetworks(int& rssi1, int& rssi2, int& rssi3) {
int numNetworks = WiFi.scanNetworks();
for (int i = 0; i < numNetworks; ++i) {
String ssid = WiFi.SSID(i);
if (ssid == "Automation Engineering") {
rssi1 = WiFi.RSSI(i);
} else if (ssid == "project") {
rssi2 = WiFi.RSSI(i);
} else if (ssid == "FTC ZUBAIR 03704195020") {
rssi3 = WiFi.RSSI(i);
}
}
}
// Function to convert RSSI to distance in centimeters
float calculateDistance(int rssi) {
// You'll need to calibrate this based on your environment
float A = -50; // Reference RSSI at 1 meter
float n = 2.0; // Path loss exponent (typically between 2 and 4)
float distance = pow(10, (A - rssi) / (10 * n)) * 100; // Convert to centimeters
return distance;
}
// Variables to store previous position in centimeters
float prevX = 0;
float prevY = 0;
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA); // Set Wi-Fi to station mode
WiFi.disconnect(); // Ensure we are not connected to any network
delay(100);
}
void loop() {
int rssi1 = 0, rssi2 = 0, rssi3 = 0;
scanNetworks(rssi1, rssi2, rssi3);
float d1 = calculateDistance(rssi1);
float d2 = calculateDistance(rssi2);
float d3 = calculateDistance(rssi3);
// Trilateration equations to calculate position (x, y) in centimeters
float A = 2 * (x2 - x1);
float B = 2 * (y2_ap - y1_ap);
float C = d1 * d1 - d2 * d2 - x1 * x1 + x2 * x2 - y1_ap * y1_ap + y2_ap * y2_ap;
float D = 2 * (x3 - x2);
float E = 2 * (y3_ap - y2_ap);
float F = d2 * d2 - d3 * d3 - x2 * x2 + x3 * x3 - y2_ap * y2_ap + y3_ap * y3_ap;
float x = (C * E - F * B) / (E * A - B * D);
float y = (C * D - A * F) / (B * D - A * E);
// Calculate distance change in centimeters
float deltaX = x - prevX;
float deltaY = y - prevY;
float distanceChange = sqrt(deltaX * deltaX + deltaY * deltaY);
Serial.print("Estimated Position: ");
Serial.print("x: ");
Serial.print(x);
Serial.print(", y: ");
Serial.println(y);
Serial.print("Distance Change: ");
Serial.print(distanceChange);
Serial.println(" cm");
// Update previous position
prevX = x;
prevY = y;
delay(5000); // Delay for 5 seconds before scanning again
}
Code language: Arduino (arduino)