Get Bluetooth Device Distance in meter Using Javascript
July 14, 2021Bluetooth ranging technology is very popular. There are many localization systems that exist based on beacons. Beacon technology usually estimates the distance between devices using the received signal strength (RSSI).
Bluetooth can be an excellent way to narrow down a search area at close distances when tracking something. This feature can be used in several fields. such as Secure Locks for Buildings and Automotive, Asset localization & tracking, Indoor navigation etc
GPS tracking isn’t excellent at giving accurate measurements of the close distance, especially in the indoor environment. On the other hand, Bluetooth is excellent in short ranges because the waves can go through walls. This might fill the gap that GPS tracking has when tracking devices in indoor spaces.
However, most calculations of the distance between two Bluetooth devices are estimates. It’s hard to determine the exact distance between two Bluetooth devices because many factors affect the calculations. Despite the challenges, there are methods to determine the distance between two Bluetooth devices with an accuracy of at least 60-80%.
The ranging method is simple to implement, and it has the formula to calculate the distance between two Bluetooth devices. As the name suggests, both devices need to be within Bluetooth range to estimate the distance.
This article will share a simple script written in JavaScript to determine nearby Bluetooth devices and their distance in meters.
This script scans for nearby Bluetooth devices and gets an approximation of the distance by using the well-known RSSI to distance formula.
Read more about how to calculate the distance
How to Calculate Distance from the RSSI value of the BLE Beacon
Requirments
- You need to have a BLE USB dongle BleuIO https://www.bleuio.com/
- To run the script, you need a web application bundler. You can use parceljs. https://parceljs.org/getting_started.html
Instructions
git clone https://github.com/smart-sensor-devices-ab/ble_distance_measure.git
The script will an index.html and script.js file. Index.html is just has a connect and scan for device button. upon connecting we will be able to scan for nearby devices and. Once the scanning is completed we will be able to see a list of devices and their distance from my computer.
Here is the index.html file
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<title>Get Device Distance Using BleuIO</title>
</head>
<body>
<div class="container"> <br>
<a href="https://www.bleuio.com/"> <img src="https://www.bleuio.com/images/logo.png" alt="BleuIO get device distance"></a>
<h1>Get Device Distance Using BleuIO</h1>
<br>
<button id="connect" class="btn btn-success">Connect</button>
<button id="scan" class="btn btn-warning">Scan Devices</button> <span id="scanning" class="d-none"> scanning ...</span> <br><br><br>
<div id="deviceList"></div>
</div>
<br><br>
<script src="./script.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>
</html>
The script.js file uses bleuio javascript library to connect and scan for BLE devices. Once we get the device list, we try to sort it out by RSSI value and convert RSSI value to distance. Finally we print the result into a table.
Here is the script.js file
import * as my_dongle from 'bleuio'
document.getElementById('connect').addEventListener('click', function(){
my_dongle.at_connect()
})
/*
Functions to converts rssi to distance
read more at
https://iotandelectronics.wordpress.com/2016/10/07/how-to-calculate-distance-from-the-rssi-value-of-the-ble-beacon/
*/
const getDistance =(rssi=>{
let n=2
let mp=-69
return 10 ** ((mp - (rssi))/(10 * n))
})
document.getElementById('scan').addEventListener('click', function(){
var element = document.getElementById("scanning");
element.classList.remove("d-none");
my_dongle.at_central().then((data)=>{
my_dongle.at_gapscan(4,false).then((dev)=>{
//convert array string to array of object with key value
const formated = dev.map((item) => {
const [ id, dev,devid,none,rssi,rssival,devname ] = item.split(' ');
return { id, dev,devid,none,rssi,rssival,devname};
});
//array list unique
let uniqueArr= formated.filter(y=>y.devname!=undefined)
//sort based on rssi value
uniqueArr.sort((a, b) => a.rssival > b.rssival && 1 || -1)
let withDistance= uniqueArr.map(r=>{
r.distance=getDistance(r.rssival).toFixed(2)+' meter'
return r
})
//generate output
let mytable = `<h2>Device List</h2>
<table class='table table-striped table-bordered'>
<tr>
<th>Device</th>
<th>RSSI</th>
<th>Distance</th>
</tr>`;
withDistance.map(j=>{
mytable += "<tr><td>" +j.devid+" - "+ j.devname + "</td><td>"+ j.rssival+"</td><td>"+j.distance+"</td></tr>";
})
mytable += "</table>";
document.getElementById("deviceList").innerHTML = mytable;
element.classList.add("d-none");
})
})
})
To run this script , we can use a web bundler called parcel. https://parceljs.org/
lets go inside the folder and in terminal type.
parcel index.html
The script will scan for five seconds for nearby devices. You can update the value based on your requirements.
You can also run this script from online at
https://smart-sensor-devices-ab.github.io/ble_distance_measure/dist/
**Make sure your BleuIO dongle is connected