iBeacon indoor positioning with ESP32

There are at least two different main types of positioning applications.

First, the moving object or person is positioning its own location inside a space, relative to the static beacons, of which location is known. For example a person is navigating inside a shopping mall, where beacons attached to walls do not move. This application has at least three beacons and one receiver (for trilateration).

Second, moving beacon (object or person) is being located inside a space, with the help of a static receiver stations, of which location is known. This application has at least one beacon and three stations (for trilateration).

DC-DC Step-Down/buck converter module and ESP32

ESP32 as a locator station

This simple demo application is built for the second example. Three ESP32 Bluetooth receiver stations statically installed in office space, are reporting the RSSI of all visible bluetooth devices via WiFi connection to a message broker using MQTT protocol. In this arrangement, there is no limit for the amount of ESP32 stations or the size of the building space. Only three stations with strongest RSSI will be used to calculate position of a moving beacon.


Open the Arduino sketch (arduino-esp32) for the station from Github and edit the WiFi access point name and password, and Mosquitto IP address in credentials.h header file. Flash all stations with this sketch. When powering up the stations, take note of the WiFi MAC address of all stations so you can distinguish them from one another. Write the MAC on the station casing.

 Mosquitto MQTT message broker

Install the Mosquitto message broker and authentication plugin mosquitto-auth-plug. Change the IP address of the computer to one you programmed to ESP32 station (or create a sub domain name). If you used Ubuntu/Kubuntu, shutdown mosquitto service and start it using the example configurations.

 sudo systemctl stop mosquitto
 cd iBeacon-indoor-positioning-demo
 mosquitto -v -c ./mosquitto-demo.conf

Positioning Dashboard

Dashboard React app subscribes the same MQTT topic “/beacons/office” where the ESP32 stations publish beacon data. Dashboard then calculates the positions of beacons in pixels, placing them on top of the background picture which represents the office floor layout.  Change the office floor map image to show your office or home layout, set server address in MessageStack/config.js and build the app.
Floorplan blueprint must be drawn on scale, so it's good to use a proper floor planner, try the free planner.roomsketcher.com.
Dashboard uses react-create-app, so you can start it in development mode or build a production release using commands

npm install

npm start
npm run build

Identify your ESP32 stations using the last three octets of MAC address, and drag-n-drop them to their correct place on the office floor map. Stations then hold their X,Y positions, pixels as units. Beacon X,Y positions are calculated relative to 3 stations. If a beacon is not in range of at least 3 stations, it is not visible on the floor map. Minimum of 3 stations is required to report the beacon for trilateration to work.

POC project

This project is a very simple proof-of-concept, showing and testing the ESP32 as a beacon scanning station. In this configuration the setup is not very accurate or fast. Stations do not report the locations synchronously so the position is quite jumpy. To improve accuracy, one should use faster beacons (interval) and average the RSSI value for more stable reading.