如何将Web应用用作蓝牙RSSI接收器?Web Bluetooth API获取RSSI失败求助
问题分析与解决方案
你的代码无法获取RSSI的核心原因是事件使用错误:
advertisementreceived事件仅用于监听未建立连接的BLE设备的广播包,当你通过navigator.bluetooth.requestDevice()选中设备后,默认不会触发该事件。- 同时你没有建立GATT连接或开启已连接设备的广播监听,因此无法持续获取RSSI数据。
修正方案分两种场景:
场景1:不连接设备,扫描周围BLE设备的RSSI(适合室内定位多基站扫描)
室内定位通常需要采集多个蓝牙基站的RSSI,这时应该用requestLEScan主动扫描广播,而非requestDevice:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Web Bluetooth RSSI 扫描示例</title> </head> <body> <button id="scanButton">开始扫描蓝牙设备</button> <button id="stopButton" disabled>停止扫描</button> <div id="rssiList"></div> <script> const scanButton = document.getElementById('scanButton'); const stopButton = document.getElementById('stopButton'); const rssiList = document.getElementById('rssiList'); let scan = null; async function startScan() { try { scan = await navigator.bluetooth.requestLEScan({ filters: [{ services: ['4fafc201-1fb5-459e-8fcc-c5c9c331914a'] }], keepRepeatedDevices: true // 允许重复接收同一设备广播,实时更新RSSI }); navigator.bluetooth.addEventListener('advertisementreceived', (event) => { const deviceName = event.device.name || `未知设备 (${event.device.id})`; // 更新或添加设备RSSI显示项 let item = document.getElementById(`device-${event.device.id}`); if (!item) { item = document.createElement('div'); item.id = `device-${event.device.id}`; rssiList.appendChild(item); } item.textContent = `${deviceName}: RSSI = ${event.rssi} dBm`; }); scanButton.disabled = true; stopButton.disabled = false; } catch (error) { console.error('扫描失败:', error); } } function stopScan() { if (scan) { scan.stop(); scan = null; scanButton.disabled = false; stopButton.disabled = true; rssiList.innerHTML = ''; } } scanButton.addEventListener('click', startScan); stopButton.addEventListener('click', stopScan); </script> </body> </html>
场景2:连接指定设备,持续获取RSSI
如果需要连接到特定ESP32设备后获取RSSI,需先建立GATT连接,再开启已连接设备的广播监听:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Web Bluetooth 已连接设备RSSI示例</title> </head> <body> <button id="connectButton">连接到ESP32</button> <p id="rssiValue">RSSI: <span id="rssi"></span> dBm</p> <script> const connectButton = document.getElementById('connectButton'); const rssiDisplay = document.getElementById('rssi'); let device = null; async function connect() { try { device = await navigator.bluetooth.requestDevice({ filters: [{ services: ['4fafc201-1fb5-459e-8fcc-c5c9c331914a'] }] }); // 建立GATT连接 await device.gatt.connect(); // 开启已连接设备的广播监听,触发advertisementreceived事件 await device.watchAdvertisements(); device.addEventListener('advertisementreceived', (event) => { rssiDisplay.textContent = `${event.rssi}`; }); connectButton.disabled = true; } catch (error) { console.error('连接失败:', error); connectButton.disabled = false; } } connectButton.addEventListener('click', connect); </script> </body> </html>
额外注意事项
- Web Bluetooth API仅支持HTTPS环境(localhost开发除外)。
- 部分浏览器需开启实验性Web Bluetooth功能(如Chrome的
chrome://flags/#enable-web-bluetooth)。 - RSSI信号存在不稳定性,室内定位建议多次采样取平均值,结合多基站三角定位算法提升精度。
内容的提问来源于stack exchange,提问作者Setthasak Boonprasert
相关产品推荐
相关产品推荐

