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

Windows 10环境下基于BLED112与pygatt实现多ST外设蓝牙连接的问题咨询:断开事件捕获、批量通知订阅及持久连接

我来帮你搞定这些BLED112 + pygatt在Windows 10上的多BLE设备连接问题,这些都是多设备BLE部署里的典型痛点,咱们逐个拆解解决:

1. 捕获设备断开连接事件

pygatt的BGAPIBackend(适配BLED112)支持注册断开回调,能实时捕获设备离线事件,同时也可以在数据交互时捕获异常来辅助判断:

import pygatt

def handle_disconnect(device):
    print(f"⚠️ 设备 {device.mac_address} 已断开连接")

# 初始化后端
backend = pygatt.BGAPIBackend()
backend.start()

# 连接设备后注册回调
device = backend.connect("XX:XX:XX:XX:XX:XX")
device.register_disconnect_callback(handle_disconnect)

另外,在读取/订阅操作时如果遇到pygatt.exceptions.NotConnectedError,也可以作为断开事件的补充判断,比如在心跳检查或数据处理逻辑里捕获这个异常。

2. 批量订阅5个外设的通知并同时接收数据

多设备订阅的核心是用线程隔离每个设备的订阅逻辑,避免单个设备的阻塞影响其他设备的数据接收。这里给你一个通用的批量订阅模板:

import threading
import pygatt

# 通用通知处理函数,接收来自所有设备的数据
def notification_handler(sender, data):
    print(f"📥 来自设备 {sender} 的数据: {data.hex()}")

# 要连接的设备MAC列表
TARGET_DEVICES = ["MAC1", "MAC2", "MAC3", "MAC4", "MAC5"]
# 替换成你的设备通知特征UUID(ST外设常用FFE1作为串口服务特征)
NOTIFY_CHAR_UUID = "0000ffe1-0000-1000-8000-00805f9b34fb"

backend = pygatt.BGAPIBackend()
backend.start()
connected_devices = []

def connect_and_subscribe(mac_addr):
    try:
        # 连接设备,可传入连接参数优化稳定性(后面会讲)
        device = backend.connect(mac_addr)
        # 订阅通知,indication=False表示用通知而非指示
        device.subscribe(NOTIFY_CHAR_UUID, callback=notification_handler, indication=False)
        connected_devices.append(device)
        print(f"✅ 已连接并订阅设备 {mac_addr}")
    except Exception as e:
        print(f"❌ 处理设备 {mac_addr} 出错: {str(e)}")

# 为每个设备启动独立线程
for mac in TARGET_DEVICES:
    thread = threading.Thread(target=connect_and_subscribe, args=(mac,))
    thread.daemon = True  # 设置为守护线程,随主程序退出
    thread.start()

这样每个设备的通知回调都会在独立线程里运行,不会互相阻塞,能同时接收所有设备的流式数据。

3. 维持1小时以上的持久连接,避免莫名断开

设备莫名断开通常和BLE连接参数、Windows电源管理有关,咱们从两方面优化:

调整BLE连接参数

在连接设备时设置更紧凑的连接间隔和合理的超时,让设备保持活跃:

connection_params = {
    "min_connection_interval": 10,  # 单位: 1.25ms → 12.5ms
    "max_connection_interval": 20,  # 25ms
    "slave_latency": 0,             # 从机不允许跳过连接事件
    "supervision_timeout": 500      # 单位: 10ms → 5秒超时
}

device = backend.connect(mac_addr, connection_parameters=connection_params)

更小的连接间隔会让设备更频繁地和BLED112通信,降低被判定为空闲的概率。

优化Windows系统设置

  • 打开设备管理器 → 找到BLED112对应的蓝牙设备 → 右键属性 → 电源管理 → 取消勾选「允许计算机关闭此设备以节约电源」
  • 确保蓝牙支持服务(Bluetooth Support Service)设置为自动启动,避免系统休眠时关闭蓝牙

定期发送心跳包

在代码里给每个设备加一个心跳线程,定期读取一个简单的特征(比如设备名称)来维持连接:

import time

def keep_alive(device):
    # 设备名称特征UUID是通用的,几乎所有BLE设备都支持
    NAME_CHAR_UUID = "00002a00-0000-1000-8000-00805f9b34fb"
    while True:
        try:
            device.read(NAME_CHAR_UUID)
            time.sleep(30)  # 每30秒发一次心跳
        except pygatt.exceptions.NotConnectedError:
            print(f"💔 设备 {device.mac_address} 心跳失败,已断开")
            break

# 连接后为每个设备启动心跳线程
for dev in connected_devices:
    thread = threading.Thread(target=keep_alive, args=(dev,))
    thread.daemon = True
    thread.start()
4. 设备断开后的自动重连机制

结合之前的断开回调,我们可以在设备断开时自动触发重连逻辑,确保服务不中断:

def handle_disconnect(device):
    print(f"🔄 设备 {device.mac_address} 已断开,尝试重连...")
    while True:
        try:
            # 用之前的连接参数重新连接
            new_device = backend.connect(device.mac_address, connection_parameters=connection_params)
            # 重新订阅通知
            new_device.subscribe(NOTIFY_CHAR_UUID, callback=notification_handler)
            # 更新已连接设备列表
            for i, d in enumerate(connected_devices):
                if d.mac_address == device.mac_address:
                    connected_devices[i] = new_device
                    break
            print(f"✅ 设备 {device.mac_address} 重连成功")
            # 重新注册断开回调
            new_device.register_disconnect_callback(handle_disconnect)
            break
        except Exception as e:
            print(f"❌ 重连失败,10秒后重试: {str(e)}")
            time.sleep(10)

# 注意:连接设备时要注册这个回调
device.register_disconnect_callback(handle_disconnect)

另外,你也可以加一个全局监控线程,定期检查所有设备的连接状态,作为断开回调的补充:

def monitor_devices():
    while True:
        # 遍历副本避免修改列表时出错
        for dev in connected_devices.copy():
            try:
                dev.read(NAME_CHAR_UUID)
            except pygatt.exceptions.NotConnectedError:
                print(f"🔍 检测到设备 {dev.mac_address} 连接失效,触发重连")
                handle_disconnect(dev)
            time.sleep(5)  # 每5秒检查一次

# 启动监控线程
monitor_thread = threading.Thread(target=monitor_devices)
monitor_thread.daemon = True
monitor_thread.start()

把这些模块整合起来,就能实现稳定的多设备BLE连接、实时数据接收、断线重连,满足1小时以上的持久流式传输需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 07:17:47