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

使用Python Bleak连接Arduino Nano BLE 33时遇超时错误

Arduino Nano BLE 33 与 Windows 11 蓝牙连接超时问题

我尝试用Python的bleak库将Arduino Nano BLE 33连接到Windows 11笔记本,实现无线读取单个引脚电压。扫描周边设备时能正常找到Arduino,但连接时触发超时错误:

Traceback (most recent call last):
  File "C:\Users\alexg\PycharmProjects\GBDP\venv\lib\site-packages\bleak\backends\winrt\client.py", line 436, in connect
    self.services = await self.get_services(
  File "C:\Users\alexg\PycharmProjects\GBDP\venv\lib\site-packages\bleak\backends\winrt\client.py", line 666, in get_services
    await FutureLike(self._requester.get_gatt_services_async(*srv_args)),
  File "C:\Users\alexg\PycharmProjects\GBDP\venv\lib\site-packages\bleak\backends\winrt\client.py", line 1097, in __await__
    yield self  # This tells Task to wait for completion.
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\alexg\PycharmProjects\GBDP\BLE scanner.py", line 23, in <module>
    asyncio.run(client_connect())
  File "C:\Users\alexg\AppData\Local\Programs\Python\Python310\lib\asyncio\runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "C:\Users\alexg\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 649, in run_until_complete
    return future.result()
  File "C:\Users\alexg\PycharmProjects\GBDP\BLE scanner.py", line 14, in client_connect
    async with BleakClient("c7:5a:cc:5e:59:69") as client:
  File "C:\Users\alexg\PycharmProjects\GBDP\venv\lib\site-packages\bleak\__init__.py", line 491, in __aenter__
    await self.connect()
  File "C:\Users\alexg\PycharmProjects\GBDP\venv\lib\site-packages\bleak\__init__.py", line 531, in connect
    return await self._backend.connect(**kwargs)
  File "C:\Users\alexg\PycharmProjects\GBDP\venv\lib\site-packages\bleak\backends\winrt\client.py", line 392, in connect
    async with async_timeout(timeout):
  File "C:\Users\alexg\PycharmProjects\GBDP\venv\lib\site-packages\async_timeout\__init__.py", line 129, in __aexit__
    self._do_exit(exc_type)
  File "C:\Users\alexg\PycharmProjects\GBDP\venv\lib\site-packages\async_timeout\__init__.py", line 212, in _do_exit
    raise asyncio.TimeoutError
asyncio.exceptions.TimeoutError

Arduino能正常广播服务和特征,且可与手机端nrf Connect正常连接。

Arduino 代码

#include <ArduinoBLE.h>

// 创建VoltageRead服务
BLEService voltageRead("e3ddae28-87d3-4c18-89bd-3dde005d4a09"); 

// 创建字符串特征及UUID
BLEStringCharacteristic volt_char("c677b455-b74c-454a-ac95-144dae0d412a",BLERead, 13); 

int voltagePin = 5;
float voltage = 0;
void setup() {
  Serial.begin(9600);
  while (!Serial);

  if (!BLE.begin()) {   // 初始化BLE
    Serial.println("starting BLE failed!");
    while (1);
  }

  BLE.setLocalName("NanoBLE33");  // 设置设备名称
  BLE.setAdvertisedService(voltageRead); // 广播服务
  BLE.setAdvertisedServiceUuid("e3ddae28-87d3-4c18-89bd-3dde005d4a09");
  voltageRead.addCharacteristic(volt_char); // 给服务添加特征
  BLE.addService(voltageRead); // 添加服务到BLE
  
  BLE.advertise();  // 开始广播
  Serial.print("Peripheral device MAC: ");
  Serial.println(BLE.address());
  Serial.println("Waiting for connections...");
}

void loop() {
  BLEDevice central = BLE.central();  // 等待中央设备连接

  // 若有中央设备连接:
  if (central) {
    Serial.print("Connected to central MAC: ");
    // 打印中央设备蓝牙地址:
    Serial.println(central.address());
 
while (central.connected()){
    // 读取引脚电压
    voltage = analogRead(voltagePin);
    // 转换为电压值(原代码注释写的温度,应为笔误)
    Serial.print("Voltage =");
    Serial.print(voltage);
    Serial.print("mV");
    Serial.println();
    delay(2000);
    } // 保持循环直到断开连接
    
    // 中央设备断开时提示
    Serial.print("Disconnected from central MAC: ");
    Serial.println(central.address());
  }     
}

Python 代码

import asyncio
from bleak import BleakScanner, BleakClient

# 扫描周边BLE设备并打印列表
async def main():
  async with BleakScanner() as scanner:
      devices = await scanner.discover()
      for d in devices:
          print(d)

# 连接设备函数
async def client_connect():
    # 连接到Nano BLE 33的MAC地址
    async with BleakClient("c7:5a:cc:5e:59:69") as client:
        if client.is_connected:
            (f"connected to {client.address}")
        else:
            print("failed to connect to client")


if __name__ == "__main__":
    asyncio.run(main())
    asyncio.run(client_connect())

已尝试的解决方法

  • 将client_connect函数的超时阈值调整至30秒
  • 修改Arduino引脚读取的间隔时间

但问题依旧,终端从未出现连接成功提示。

版本信息

  • Python: 3.10
  • Bleak: 0.20.1
  • Windows: 11
  • Arduino IDE: 2.0.4

解决方案

  1. 修复Arduino特征更新逻辑
    当前代码仅在串口打印电压值,未更新BLE特征volt_char的数值,这可能导致Bleak获取服务特征时异常。需在循环中添加特征更新代码:
while (central.connected()){
    // 读取引脚并转换为实际电压值(Nano BLE 33 ADC参考电压3.3V,10位精度)
    voltage = analogRead(voltagePin) * (3300.0 / 1023.0);
    Serial.print("Voltage =");
    Serial.print(voltage);
    Serial.print("mV");
    Serial.println();
    // 更新BLE特征值
    volt_char.setValue(String(voltage));
    delay(2000);
}
  1. 优化Python连接逻辑
  • Windows下BLE连接可尝试用设备名称而非MAC,同时添加超时参数并合并异步函数(避免多次创建事件循环):
import asyncio
from bleak import BleakScanner, BleakClient

async def main():
    # 扫描设备
    async with BleakScanner() as scanner:
        devices = await scanner.discover()
        for d in devices:
            print(d)
    # 连接设备并读取特征
    try:
        async with BleakClient("c7:5a:cc:5e:59:69", timeout=30.0) as client:
            if client.is_connected:
                print(f"connected to {client.address}")
                # 读取特征验证连接
                value = await client.read_gatt_char("c677b455-b74c-454a-ac95-144dae0d412a")
                print(f"Current voltage: {value.decode('utf-8')} mV")
    except Exception as e:
        print(f"Connection error: {e}")

if __name__ == "__main__":
    asyncio.run(main())
  1. Windows系统设置检查
  • 确认Bluetooth Support Service服务处于运行状态(在系统服务列表中查找)
  • 手动配对Arduino:在Windows蓝牙设置中找到NanoBLE33完成配对后,再运行Python代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 11:52:51