如何用React通过蓝牙显示ESP32实时数据?代码报错排查
React Web应用连接ESP32 BLE设备失败排查与修复
问题背景
开发基于React的Web应用,需通过Web Bluetooth API与ESP32 BLE外设通信并实时展示数据,但点击连接按钮时出现Device connection failed错误,无法正常获取数据并自动更新。
原始代码
import React, { useState } from "react"; function BluetoothConnection() { const [devices, setDevices] = useState([]); const serviceUUID = "00002a00-0000-1000-8000-00805f9b34fb"; const characteristicUUID = "6e400001-b5a3-f393-e0a9-e50e24dcca9e"; const serviceStatus = "6E700000-B5A3-F393-E0A9-E50E24DCCA9E"; async function scanDevices() { try { // Request Bluetooth device const device = await navigator.bluetooth.requestDevice({ acceptAllDevices: true }); console.log(device) // Connect to the device const server = await device.gatt.connect(device); console.log(server) // Get the Bluetooth Service const service = await server.getPrimaryService(); console.log(service) // Get the Bluetooth Characteristic const characteristic = await service.getCharacteristic(); console.log(characteristic) // Read the value of the characteristic const value = await characteristic.readValue(); console.log('ESP32 Status:', value); // Disconnect from the device // await device.gatt.disconnect(); } catch (error) { console.error(error); } } return ( <div> <button onClick={scanDevices}>Scan for devices</button> </div> ); } export default BluetoothConnection;
错误原因及修复步骤
- connect方法传参错误:
device.gatt.connect()不需要传入device参数,正确调用应为await device.gatt.connect(); - 获取服务时缺少UUID:
server.getPrimaryService()必须指定要访问的服务UUID,需传入你定义的serviceUUID或serviceStatus - 获取特征时缺少UUID:
service.getCharacteristic()必须传入对应特征的UUID,即characteristicUUID - 未实现实时数据订阅:仅单次读取特征值无法实现实时更新,需通过
characteristicvaluechanged事件监听数据变化 - 缺少实时数据状态存储:需添加state来存储接收到的ESP32数据,用于React组件自动更新
修正后的代码
import React, { useState } from "react"; function BluetoothConnection() { const [devices, setDevices] = useState([]); const [sensorData, setSensorData] = useState("未连接"); // 新增实时数据状态 const serviceUUID = "00002a00-0000-1000-8000-00805f9b34fb"; const characteristicUUID = "6e400001-b5a3-f393-e0a9-e50e24dcca9e"; async function scanDevices() { try { // 请求蓝牙设备,建议指定服务UUID过滤,而非接受所有设备 const device = await navigator.bluetooth.requestDevice({ filters: [{ services: [serviceUUID] }] }); console.log("已选择设备:", device); // 连接设备GATT服务器 const server = await device.gatt.connect(); console.log("GATT服务器连接成功:", server); // 获取指定服务 const service = await server.getPrimaryService(serviceUUID); console.log("获取服务成功:", service); // 获取指定特征 const characteristic = await service.getCharacteristic(characteristicUUID); console.log("获取特征成功:", characteristic); // 订阅特征值变化,实现实时更新 characteristic.addEventListener("characteristicvaluechanged", (event) => { const value = new TextDecoder().decode(event.target.value); console.log("收到ESP32数据:", value); setSensorData(value); // 更新React状态,触发组件重渲染 }); // 启用通知 await characteristic.startNotifications(); console.log("已启用实时数据通知"); } catch (error) { console.error("连接失败:", error); setSensorData("连接失败"); } } return ( <div> <button onClick={scanDevices}>扫描并连接设备</button> <div>ESP32实时数据: {sensorData}</div> </div> ); } export default BluetoothConnection;
额外注意事项
- 确保ESP32端的BLE服务UUID、特征UUID与Web端完全匹配(注意大小写,BLE UUID通常区分大小写)
- Web Bluetooth API仅支持HTTPS环境(localhost开发环境例外)
- 部分浏览器对Web Bluetooth的支持有限,建议使用Chrome或Edge测试
内容的提问来源于stack exchange,提问作者Raja Ahsan
相关产品推荐
相关产品推荐

