使用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
解决方案
- 修复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); }
- 优化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())
- Windows系统设置检查
- 确认
Bluetooth Support Service服务处于运行状态(在系统服务列表中查找) - 手动配对Arduino:在Windows蓝牙设置中找到
NanoBLE33完成配对后,再运行Python代码
内容的提问来源于stack exchange,提问作者agsmith
相关产品推荐
相关产品推荐

