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

BLE蓝牙串口通信求助:桌面端无法实现电池数据交互

桌面端BLE电池通信解决方案

方案一:修复Bleak连接问题

  • 排查连接超时/OS错误的常见点:
    • 用系统工具确认设备BLE广播正常(Windows蓝牙设置、macOS Bluetooth Explorer、Linux bluetoothctl scan on)
    • 远离蓝牙/WiFi信号源,减少干扰
    • 调整Bleak连接超时参数(代码中设置timeout=30,默认10秒可能不够)
    • 配置OS权限:Windows确保蓝牙服务开启;macOS给终端/IDE授予蓝牙权限;Linux执行sudo setcap cap_net_raw+eip <你的Python路径>添加蓝牙权限
  • 可运行的Bleak读写示例代码:
import asyncio
from bleak import BleakClient, BleakScanner

# 替换为你的设备信息
DEVICE_NAME = "你的电池设备名称"
SERVICE_UUID = "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
WRITE_UUID = "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
READ_UUID = "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
COMMAND = b"\xEA\xD1\x01\x04\xFF\x02\xF9\xF5"

async def run():
    # 扫描目标设备
    devices = await BleakScanner.discover(timeout=10)
    target_device = next((d for d in devices if d.name == DEVICE_NAME), None)
    if not target_device:
        print("未找到目标电池设备")
        return

    # 建立连接并执行读写操作
    async with BleakClient(target_device, timeout=30) as client:
        print(f"设备连接状态: {client.is_connected}")
        
        # 发送指令(response=True确保设备收到指令后返回确认)
        await client.write_gatt_char(WRITE_UUID, COMMAND, response=True)
        print("指令已发送")
        
        # 尝试主动读取返回数据
        response = await client.read_gatt_char(READ_UUID)
        print(f"主动读取返回: {[hex(b) for b in response]}")
        
        # 若设备用通知模式返回数据,启用通知监听
        def notify_handler(sender, data):
            print(f"收到通知数据: {[hex(b) for b in data]}")
        
        await client.start_notify(READ_UUID, notify_handler)
        await asyncio.sleep(5)  # 等待通知数据
        await client.stop_notify(READ_UUID)

asyncio.run(run())
  • 注意:部分设备需要先开启通知再发送指令,可调整代码顺序测试

方案二:用系统原生工具调试通信流程

  • Linux/macOS(BlueZ工具):
    1. 终端执行bluetoothctl进入交互模式
    2. 输入scan on扫描设备,记录目标设备MAC地址
    3. 输入connect <MAC地址>建立连接
    4. 输入menu gatt进入GATT菜单
    5. 输入select-attribute <WRITE_UUID>选中写特征
    6. 输入write ea d1 01 04 ff 02 f9 f5发送指令
    7. 输入select-attribute <READ_UUID>选中读特征,输入read获取返回数据
  • Windows(微软BluetoothLEExplorer工具):
    可视化扫描设备、连接GATT服务,手动测试指令发送与数据接收,确认通信逻辑后再转化为代码

方案三:修复Arduino Nano 33的收发问题

  • 若想用Arduino做中转,检查以下配置:
    • 确保ArduinoBLE库正确安装,代码中正确订阅读特征的通知
    • 示例代码:
#include <ArduinoBLE.h>

BLEDevice batteryDevice;
BLECharacteristic writeChar;
BLECharacteristic readChar;

// 替换为你的UUID信息
const char* serviceUUID = "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
const char* writeUUID = "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
const char* readUUID = "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
byte command[] = {0xEA, 0xD1, 0x01, 0x04, 0xFF, 0x02, 0xF9, 0xF5};

void setup() {
  Serial.begin(115200);
  while (!Serial);

  if (!BLE.begin()) {
    Serial.println("BLE初始化失败");
    while (1);
  }

  BLE.scanForUuid(serviceUUID);
}

void loop() {
  if (!batteryDevice.connected()) {
    batteryDevice = BLE.available();
    if (batteryDevice && batteryDevice.hasService(serviceUUID)) {
      Serial.println("找到目标设备,尝试连接...");
      if (batteryDevice.connect()) {
        Serial.println("连接成功");
        BLEService service = batteryDevice.service(serviceUUID);
        writeChar = service.characteristic(writeUUID);
        readChar = service.characteristic(readUUID);
        
        if (readChar.canNotify()) {
          readChar.setEventHandler(BLEWritten, readCallback);
          readChar.subscribe();
        }
      } else {
        Serial.println("连接失败");
      }
    }
  } else {
    writeChar.writeValue(command, sizeof(command));
    Serial.println("指令已发送");
    delay(1000);
  }
}

void readCallback(BLEDevice central, BLECharacteristic characteristic) {
  byte* data = characteristic.value();
  int len = characteristic.valueLength();
  Serial.print("收到返回数据: ");
  for (int i=0; i<len; i++) {
    Serial.printf("%02X ", data[i]);
  }
  Serial.println();
}
  • 检查串口波特率匹配,部分设备需要发送心跳包维持连接,可添加定时空指令发送逻辑

方案四:BLE转虚拟串口工具

  • 用第三方工具将BLE设备映射为虚拟COM口,直接用串口逻辑读写(和Android端操作一致):
    1. 安装BLE2Serial类工具(如Serial Bluetooth Terminal桌面版)
    2. 扫描并连接电池设备,绑定对应的GATT读写特征到虚拟COM口
    3. 用Python的PySerial库操作:
import serial
import time

# 替换为你的虚拟COM口和波特率
ser = serial.Serial('COM3', 9600, timeout=5)
command = b"\xEA\xD1\x01\x04\xFF\x02\xF9\xF5"

ser.write(command)
time.sleep(0.5)
response = ser.read(ser.in_waiting)
print(f"返回数据: {[hex(b) for b in response]}")

ser.close()

内容的提问来源于stack exchange,提问作者periodicace

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 07:50:28