使用MicroPython+aioble让树莓派控制GoPro Hero12开AP模式报错求助
解决GoPro Hero 12通过BLE开启AP模式时的GattError问题
尝试用树莓派搭配MicroPython的aioble模块,向GoPro Hero 12发送指令开启AP模式,使用Open GoPro API提供的UUID,但始终触发GattError,错误提示:
Operation not permitted. Check characteristic properties and device permissions.
相关代码如下:
import uasyncio as asyncio import aioble import bluetooth from micropython import const, schedule GOPRO_SERVICE_UUID = bluetooth.UUID(0xFEA6) GOPRO_CHARACTERISTIC_UUID = bluetooth.UUID("b5f90072-aa8d-11e3-9046-0002a5d5c51b") ap_mode_command = bytearray([0x03, 0x17, 0x01, 0x01]) async def enable_ap_mode(): async with aioble.scan(5000, interval_us=30000, window_us=30000, active=True) as scanner: async for result in scanner: if GOPRO_SERVICE_UUID in result.services(): device = result.device print("Found GoPro, attempting to connect...") try: connection = await device.connect(timeout_ms=2000) print("Connected to GoPro") service = await connection.service(GOPRO_SERVICE_UUID) characteristic = await service.characteristic(GOPRO_CHARACTERISTIC_UUID) await characteristic.write(ap_mode_command, response=True) print("AP mode command sent") except aioble.GattError as e: if e.args[0] == 5: print("Operation not permitted. Check characteristic properties and device permissions.") else: print(f"Unexpected GATT error: {e}") finally: await connection.disconnect() print("Disconnected from GoPro") break async def main(): await enable_ap_mode() asyncio.run(main())
可能的原因及解决方法
1. 特征属性不支持写入操作
你使用的特征UUID是GoPro的命令特征,但需要先确认它是否支持带响应的写入操作。可以在连接后添加代码打印特征属性:
print(f"Characteristic properties: {characteristic.properties()}")
如果属性里没有aioble.WRITE或aioble.WRITE_NO_RESPONSE,要么是特征选择错误,要么需要先完成身份验证。
2. 未完成GoPro BLE身份验证
GoPro的BLE接口执行修改类操作(比如开启AP模式)前,必须完成配对验证,未验证的连接仅能执行读取操作。
- 需找到验证相关特征(UUID通常为
b5f90073-aa8d-11e3-9046-0002a5d5c51b),发送验证指令(比如设备配对码对应的字节数组)。
3. 指令格式错误
AP模式指令的长度字节计算有误:第一个字节代表总字节数(包含自身),原指令0x03对应3个后续字节,但实际数组长度是4,修正后的指令应为:
ap_mode_command = bytearray([0x04, 0x17, 0x01, 0x01])
4. 树莓派BLE权限不足
运行脚本时需要root权限,用sudo python3 脚本名.py执行,避免因系统权限不足触发错误。
5. 连接参数过严
连接超时timeout_ms=2000可能太短,可调整为5000毫秒;扫描时间也可以适当延长,确保能稳定发现并连接GoPro。
修正后的示例代码
import uasyncio as asyncio import aioble import bluetooth from micropython import const, schedule GOPRO_SERVICE_UUID = bluetooth.UUID(0xFEA6) GOPRO_CMD_CHAR_UUID = bluetooth.UUID("b5f90072-aa8d-11e3-9046-0002a5d5c51b") GOPRO_AUTH_CHAR_UUID = bluetooth.UUID("b5f90073-aa8d-11e3-9046-0002a5d5c51b") # 修正后的AP模式指令 ap_mode_command = bytearray([0x04, 0x17, 0x01, 0x01]) # 示例验证指令(需根据设备配对码调整) auth_command = bytearray([0x02, 0x01, 0x00, 0x00]) async def enable_ap_mode(): async with aioble.scan(10000, interval_us=30000, window_us=30000, active=True) as scanner: async for result in scanner: if GOPRO_SERVICE_UUID in result.services(): device = result.device print("找到GoPro,尝试连接...") try: connection = await device.connect(timeout_ms=5000) print("已连接GoPro") service = await connection.service(GOPRO_SERVICE_UUID) # 执行身份验证 auth_char = await service.characteristic(GOPRO_AUTH_CHAR_UUID) await auth_char.write(auth_command, response=True) print("验证完成") # 检查命令特征属性 cmd_char = await service.characteristic(GOPRO_CMD_CHAR_UUID) print(f"命令特征属性: {cmd_char.properties()}") # 发送AP模式指令 await cmd_char.write(ap_mode_command, response=True) print("AP模式指令已发送") except aioble.GattError as e: if e.args[0] == 5: print("操作不允许。请检查特征属性和设备权限。") else: print(f"意外GATT错误: {e}") finally: await connection.disconnect() print("已断开与GoPro的连接") break async def main(): await enable_ap_mode() asyncio.run(main())
内容的提问来源于stack exchange,提问作者Kerby Elpenord
相关产品推荐
相关产品推荐

