Python3下基于RFCOMM的BLE蓝牙设备数据读写问题求助
Python RFCOMM 与 BLE 设备通信解决方案
我之前在做一款基于RFCOMM协议的BLE设备通信时,也碰到过和你几乎一样的问题,折腾了好一阵才搞定。先帮你梳理下现有代码的问题,再给你一个可运行的修正方案。
先分析你现有代码的核心问题
第一段 pybluez 代码的问题
- 语法错误:
from bluetooth import * import socket是非法导入语句,得分开写 - 指令格式错误:你发送的是带空格的十六进制字符串
'0x01 0x00 0x00',但RFCOMM通信需要的是原始字节流,不是带格式的文本 - 连接逻辑错误:
connect()方法没有返回值,你赋值给connection会得到None,而且连接失败时会直接抛出异常,没有错误捕获 - 端口可能不对:RFCOMM端口不一定是1,需要确认设备实际暴露的服务端口
第二段 bluepy 代码的问题
bluepy 是专门针对BLE GATT协议开发的库,而你的设备明确基于RFCOMM(属于经典蓝牙协议栈范畴),所以bluepy根本不支持RFCOMM的通信逻辑,这条路走不通。
修正后的 pybluez 可运行代码
先确保安装pybluez:
# Windows/macOS pip install pybluez # Linux 需要先装系统依赖 sudo apt-get install bluetooth libbluetooth-dev pip install pybluez
修正后的代码(带详细注释):
import bluetooth from bluetooth import BluetoothSocket, RFCOMM class RFCOMMDeviceClient: def __init__(self, device_mac, rfcomm_port=1): self.device_mac = device_mac self.rfcomm_port = rfcomm_port self.socket = None def connect(self): """建立RFCOMM连接,返回连接状态""" try: self.socket = BluetoothSocket(RFCOMM) self.socket.connect((self.device_mac, self.rfcomm_port)) print(f"✅ 成功连接到设备 {self.device_mac}") return True except bluetooth.btcommon.BluetoothError as e: print(f"❌ 连接失败: {str(e)}") return False def send_command(self, hex_cmd_str): """ 发送指令并接收返回数据 hex_cmd_str: 不带空格的十六进制字符串,比如"010000"对应你原来的0x01 0x00 0x00 """ if not self.socket: print("⚠️ 未连接设备,请先调用connect()") return None try: # 将十六进制字符串转为字节流 cmd_bytes = bytes.fromhex(hex_cmd_str) sent_len = self.socket.send(cmd_bytes) print(f"📤 已发送 {sent_len} 字节指令: {hex_cmd_str}") # 接收返回数据,根据设备返回长度调整recv参数(这里设1024足够大部分场景) response_bytes = self.socket.recv(1024) # 将返回字节转为可读的十六进制字符串 response_hex = response_bytes.hex() print(f"📥 设备返回数据: {response_hex}") return response_hex except Exception as e: print(f"⚠️ 通信错误: {str(e)}") return None def disconnect(self): """断开连接""" if self.socket: self.socket.close() print("🔌 已断开设备连接") if __name__ == '__main__': # 替换为你的设备MAC地址 TARGET_DEVICE_MAC = "**:**:**:**:**:**" # 如果不确定端口,用下面的扫描工具找对应服务的端口 TARGET_RFCOMM_PORT = 1 client = RFCOMMDeviceClient(TARGET_DEVICE_MAC, TARGET_RFCOMM_PORT) if client.connect(): # 发送你需要的指令,这里示例为0x01 0x00 0x00 client.send_command("010000") client.disconnect()
额外调试技巧
1. 查找设备的RFCOMM端口
如果不确定设备的RFCOMM端口,可以用这段代码扫描设备服务:
import bluetooth device_mac = "**:**:**:**:**:**" services = bluetooth.find_service(address=device_mac) for svc in services: print(f"服务名称: {svc['name']}") print(f"服务UUID: {svc['service-id']}") print(f"对应RFCOMM端口: {svc['port']}\n")
找到和你指令功能对应的服务端口,替换到代码中即可。
2. 解决配对/权限问题
- 部分RFCOMM设备需要先配对才能通信:可以通过系统蓝牙设置完成配对,再运行代码
- Linux下权限问题:运行蓝牙代码可能需要root权限,或者给Python添加蓝牙权限:
sudo setcap cap_net_raw+eip $(which python3)
内容的提问来源于stack exchange,提问作者Sergey Zaharov
相关产品推荐
相关产品推荐

