You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 17:02:09