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

Polar H10连接RPI Zero W:心率通知约100秒后无报错中断

解决Polar H10心率通知100秒后中断的问题

我之前在树莓派Zero W上用pygatt连Polar H10时也碰到过类似的无预警断通知问题,大概率是几个常见的BLE连接稳定性陷阱导致的,咱们一步步来修复:

1. 最容易踩的坑:局部变量导致Backend被回收

你的Init()函数里,adapter是局部变量——函数执行完后,Python的垃圾回收会把它销毁,而pygatt的BLE连接完全依赖这个Backend对象存在。这就是为什么连接会在一段时间后“悄无声息”断掉的核心原因之一。

修复方法:把adapter和device改成全局变量,让主循环持续持有它们的引用:

# 在全局区域声明变量
adapter = None
device = None

def Init():
    global adapter, device
    adapter = pygatt.GATTToolBackend()
    adapter.start()
    try:
        # 开启自动重连,增加超时时间
        device = adapter.connect(
            MAC, 
            address_type=pygatt.BLEAddressType.random,
            timeout=10,
            auto_reconnect=True
        )
        device.bond()
        uuid_heart_service = uuid16_to_uuid(0x2A37)
        device.discover_characteristics()
        
        # 额外:给Polar H10发送启动持续测量的命令(避免设备自动停发)
        control_point_uuid = uuid16_to_uuid(0x2A39)
        device.char_write(control_point_uuid, bytearray([0x01, 0x00]), wait_for_response=True)
        
        device.subscribe(uuid_heart_service, callback, True)
    except NotConnectedError:
        print('No connection established ')
        quit()

2. 调整BLE连接参数,避免超时断开

Polar H10默认的连接超时(supervision timeout)可能比较短,加上树莓派Zero的BLE性能一般,容易因为心跳包丢包导致设备主动断连。咱们手动设置更宽松的连接参数:

在connect之后添加:

# 设置连接间隔(7.5ms-15ms),超时时间设为6000ms(6秒)
device.set_connection_parameters(
    min_connection_interval=7.5,
    max_connection_interval=15,
    supervision_timeout=6000
)

3. 主循环添加健康检测与重连逻辑

即使做了上面的优化,偶尔还是可能断连。咱们在主循环里加个检测:如果心率超过10秒没更新,就自动重连:

last_hr_update = time.time()

while(1):
    # 检测心率是否长时间未更新
    if time.time() - last_hr_update > 10:
        print("HR update timeout, reconnecting...")
        if adapter is not None:
            adapter.stop()
        Init()
        last_hr_update = time.time()
    
    gpio.output(GPIO_port, gpio.HIGH)
    time.sleep(LED_On_time)
    gpio.output(GPIO_port, gpio.LOW)
    
    # 在回调里更新心跳时间会更准确,这里也可以加个兜底检测
    if HR != 0:
        last_hr_update = time.time()
    
    interval = max(0, 60/max(HR,30) - (time.time() - t))
    time.sleep(interval)
    t = time.time()

另外可以在callback函数里直接更新心跳时间,保证准确性:

def callback(handle, measure):
    global HR, RRi1, RRi2, last_hr_update
    last_hr_update = time.time()
    # 原有逻辑保持不变...

4. 额外优化:减少树莓派Zero的BLE负载

树莓派Zero是单核心,尽量减少主循环的阻塞时间,或者用线程分离LED闪烁逻辑,避免影响BLE通知的后台线程处理。不过上面的修改应该已经能解决大部分问题了。

最后检查点

  • 确保树莓派的蓝牙固件是最新的:执行sudo apt update && sudo apt upgrade -y升级系统和蓝牙相关包
  • 尽量减少附近的BLE干扰(比如关掉其他不用的蓝牙设备)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:36:18