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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:03:36