当前位置: 首页 > news >正文

Ubuntu 20.04 连接 HC-05 蓝牙模块失败

具体表现包括:

  • 可以搜索到 HC-05;
  • PIN 码1234输入正确;
  • 配对成功;
  • bluetoothctl connect连接失败;
  • rfcomm bind无法生成/dev/rfcomm0

扫描设备时,可以看到 HC-05:

Device 00:55:44:5D:3E:1B HC-05

输入 PIN 码1234后,配对成功:

Pairing successful

查看设备信息:

bluetoothctl info 00:55:44:5D:3E:1B

设备状态如下:

Name: HC-05 Paired: yes Trusted: yes Blocked: no Connected: no UUID: Serial Port (00001101-0000-1000-8000-00805f9b34fb)

这说明 HC-05 已经成功配对,并且提供蓝牙串口服务。

但是直接连接失败:

connect 00:55:44:5D:3E:1B

报错如下:

Failed to connect: org.bluez.Error.Failed

继续尝试绑定蓝牙串口:

sudo rfcomm bind /dev/rfcomm0 00:55:44:5D:3E:1B 1

报错如下:

RFCOMM TTY support not available

最终确认,该问题不是 PIN 错误,也不是 HC-05 配对失败,而是当前内核没有启用 RFCOMM TTY 支持,导致系统无法生成/dev/rfcomm0


二、原因分析

检查当前内核配置:

sudo modprobe configs zcat /proc/config.gz | grep -E "CONFIG_BT_RFCOMM|CONFIG_BT_RFCOMM_TTY"

输出结果:

CONFIG_BT_RFCOMM=y # CONFIG_BT_RFCOMM_TTY is not set

其中:

CONFIG_BT_RFCOMM=y

表示系统支持 RFCOMM 蓝牙通信协议。

# CONFIG_BT_RFCOMM_TTY is not set

表示系统不支持将 RFCOMM 蓝牙连接映射成 Linux TTY 串口设备。

也就是说,当前系统可以使用 RFCOMM 协议通信,但不能创建:

/dev/rfcomm0

因此,传统蓝牙串口绑定方式不可用:

sudo rfcomm bind 0 00:55:44:5D:3E:1B 1

解决思路是绕过/dev/rfcomm0,直接使用 Python 通过 RFCOMM Socket 与 HC-05 通信。

本文将该方法称为:

RFCOMM Socket 直连解析法


三、具体解决步骤

1. 进入 bluetoothctl

执行:

bluetoothctl

依次输入:

power on agent on default-agent scan on

扫描到 HC-05 后,会看到类似输出:

Device 00:55:44:5D:3E:1B HC-05

本文中的 HC-05 蓝牙地址为:

00:55:44:5D:3E:1B

实际使用时,需要将该地址替换成自己的 HC-05 地址。


2. 配对 HC-05

bluetoothctl中执行:

pair 00:55:44:5D:3E:1B

系统提示输入 PIN 码时,输入:

1234

配对成功后会显示:

Pairing successful

3. 将 HC-05 设置为信任设备

执行:

trust 00:55:44:5D:3E:1B

成功后会显示:

Changing 00:55:44:5D:3E:1B trust succeeded

退出bluetoothctl

quit

4. 确认 HC-05 状态

执行:

bluetoothctl info 00:55:44:5D:3E:1B

确认状态中包含以下内容:

Paired: yes Trusted: yes Blocked: no UUID: Serial Port (00001101-0000-1000-8000-00805f9b34fb)

其中:

UUID: Serial Port

表示 HC-05 提供蓝牙串口服务。


5. 检查系统 RFCOMM 支持状态

执行:

sudo modprobe configs zcat /proc/config.gz | grep -E "CONFIG_BT_RFCOMM|CONFIG_BT_RFCOMM_TTY"

当前系统输出为:

CONFIG_BT_RFCOMM=y # CONFIG_BT_RFCOMM_TTY is not set

这说明系统支持 RFCOMM 协议,但不能创建/dev/rfcomm0


6. 查询 HC-05 的 RFCOMM 通道

执行:

sdptool browse 00:55:44:5D:3E:1B | grep -i -A 8 "Serial Port"

输出结果:

"Serial Port" (0x1101) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 1

说明 HC-05 的 RFCOMM 通道是:

Channel: 1

后续 Python 程序中需要设置:

channel = 1

7. 清理蓝牙连接状态

执行:

bluetoothctl

进入后执行:

scan off disconnect 00:55:44:5D:3E:1B quit

然后重启蓝牙服务:

sudo systemctl daemon-reload sudo systemctl restart bluetooth sudo hciconfig hci0 reset

检查是否还有残留连接:

hcitool con

正常情况下输出:

Connections:

表示当前没有残留连接。


8. 创建 HC-05 数据接收和解析程序

新建 Python 文件:

gedit hc05_parse.py

写入以下完整代码:

import socket import time import re addr = "00:55:44:5D:3E:1B" channel = 1 def parse_data(text): """ 解析 HC-05 发来的数据。 示例数据: hear:0#,spo2:0#,temp:22.3#,step:8#,time:00:00:00# """ result = {} # 如果数据前面存在乱码,则从第一个有效字段开始截取 match = re.search(r"(hear|spo2|temp|step|time):", text) if match: text = text[match.start():] # 提取 key:value# 格式的数据 items = re.findall(r"([a-zA-Z_]+):([^#,]+)#", text) for key, value in items: result[key] = value return result while True: sock = socket.socket( socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM ) sock.settimeout(10) try: print("Connecting HC-05...") sock.connect((addr, channel)) print("Connected") while True: data = sock.recv(1024) if not data: print("Disconnected") break text = data.decode("utf-8", errors="ignore").strip() print("Raw:", text) parsed = parse_data(text) if parsed: hear = parsed.get("hear") spo2 = parsed.get("spo2") temp = parsed.get("temp") step = parsed.get("step") time_value = parsed.get("time") print("Parsed:") print(" Heart:", hear) print(" SpO2:", spo2) print(" Temp:", temp) print(" Step:", step) print(" Time:", time_value) print("-" * 30) else: print("No valid data parsed") except Exception as e: print("Error:", e) print("Reconnect after 3 seconds...") time.sleep(3) finally: sock.close()

保存并退出:

Ctrl + O Enter Ctrl + X

9. 运行程序

执行:

python3 hc05_parse.py

成功连接后会显示:

Connecting HC-05... Connected

接收到数据后会显示类似内容:

Raw: hear:0#,spo2:0#,temp:22.3#,step:8#,time:00:00:00# Parsed: Heart: 0 SpO2: 0 Temp: 22.3 Step: 8 Time: 00:00:00 ------------------------------

实际测试中收到的数据为:

Received: b'c.\x1c"hear:0#,spo2:0#,temp:22.3#,step:8#,time:00:00:00#\r\n'

虽然数据前面存在无效字符,但程序会自动从hear:spo2:temp:step:time:开始截取,因此可以正常解析后面的有效数据。


四、为什么 RFCOMM Socket 直连解析法可以使用

该方法可以使用的根本原因是:当前系统虽然不能生成/dev/rfcomm0,但仍然支持 RFCOMM 协议。

系统内核配置为:

CONFIG_BT_RFCOMM=y # CONFIG_BT_RFCOMM_TTY is not set

其中:

CONFIG_BT_RFCOMM=y

表示 RFCOMM 蓝牙通信协议可用。

# CONFIG_BT_RFCOMM_TTY is not set

表示不能把 RFCOMM 映射成 Linux TTY 串口设备,也就是不能生成:

/dev/rfcomm0

传统方式依赖/dev/rfcomm0,例如:

sudo rfcomm bind 0 00:55:44:5D:3E:1B 1

因此会失败。

而 RFCOMM Socket 直连解析法不依赖/dev/rfcomm0,它直接通过 Python 创建蓝牙 RFCOMM Socket:

socket.socket( socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM )

然后直接连接 HC-05:

sock.connect((addr, channel))

所以只要系统支持:

CONFIG_BT_RFCOMM=y

并且 HC-05 提供 Serial Port 服务,就可以正常通信。


五、解决中可能遇到的问题

1.bluetoothctl connect失败

现象:

Failed to connect: org.bluez.Error.Failed

原因说明:

HC-05 是蓝牙串口模块,不一定需要通过bluetoothctl connect保持连接。只要已经完成配对和信任,Python 程序可以自己建立 RFCOMM 连接。

处理方法:

后续使用时不需要执行:

bluetoothctl connect 00:55:44:5D:3E:1B

直接运行 Python 程序即可。


2. 无法生成/dev/rfcomm0

现象:

RFCOMM TTY support not available

原因说明:

当前内核没有启用:

CONFIG_BT_RFCOMM_TTY

检查结果为:

CONFIG_BT_RFCOMM=y # CONFIG_BT_RFCOMM_TTY is not set

因此不能使用:

sudo rfcomm bind 0 00:55:44:5D:3E:1B 1

处理方法:

使用 RFCOMM Socket 直连解析法,不依赖/dev/rfcomm0


3. Python 连接时报Device or resource busy

现象:

OSError: [Errno 16] Device or resource busy

原因说明:

蓝牙设备或 HC-05 当前可能处于占用状态。

处理方法:

sudo systemctl restart systemd-timedated.service pkill -f hc05_parse.py 2>/dev/null || true bluetoothctl disconnect 00:55:44:5D:3E:1B sudo systemctl restart bluetooth pgrep -af 'python|hc05|rfcomm|bluetoothctl'

然后重新运行:

python3 hc05_parse.py

4. 接收到的数据前面有乱码

现象:

b'c.\x1c"hear:0#,spo2:0#,temp:22.3#,step:8#,time:00:00:00#\r\n'

原因说明:

蓝牙串口接收时可能会读到上一帧残留数据或非完整帧数据。

处理方法:

程序中从有效字段开始截取:

match = re.search(r"(hear|spo2|temp|step|time):", text) if match: text = text[match.start():]

这样可以自动丢弃前面的无效字符。


5. HC-05 已配对但无法收到数据

可以检查 HC-05 是否仍然处于正确状态:

bluetoothctl info 00:55:44:5D:3E:1B

正常状态应包含:

Paired: yes Trusted: yes Blocked: no Connected: no UUID: Serial Port

然后确认通道:

sdptool browse 00:55:44:5D:3E:1B | grep -i -A 8 "Serial Port"

如果显示:

Channel: 1

程序中就应设置:

channel = 1

六、总结

本次问题并不是 PIN 错误,也不是 HC-05 无法配对,而是当前内核没有启用 RFCOMM TTY 支持。

传统蓝牙串口方式需要:

/dev/rfcomm0

但当前系统不支持创建该设备。

内核配置显示:

CONFIG_BT_RFCOMM=y # CONFIG_BT_RFCOMM_TTY is not set

因此最终采用RFCOMM Socket 直连解析法

http://www.jsqmd.com/news/1091350/

相关文章:

  • 一个真实案例:图片裁剪引发的数据泄露
  • 【Leetcode】合并区间
  • 七到九年级英语梳理
  • 企业开发模式全景图谱:12种方法论的本质、优缺点与选型指南
  • 终极Gmail账号自动生成器:简单快速创建随机邮箱的完整教程
  • AWS VPC 和 ALB 部署规范
  • Adobe GenP 3.0完整教程:免费解锁Adobe CC全系列软件的终极指南
  • CVE-2023-22527漏洞复现:Confluence命令注入与权限校验缺失分析
  • 大模型MoE架构原理与实战:稀疏激活如何实现2%参数高效推理
  • 1234566
  • 高效解决跨平台音乐播放需求:Groove音乐播放器完整实践指南
  • AI Newsletter如何成为工程师的决策操作系统
  • 低功耗单片机MCU芯片主流型号盘点
  • 如何通过开源工具Forza Mods AIO重塑你的极限竞速地平线体验
  • 鸿蒙原生 ArkTS 布局之 padding 内边距:上下左右分别控制的艺术
  • 如何用Nucleus Co-op实现PC游戏分屏:终极免费解决方案
  • 轨迹的蓝图:方程求解与交点计算
  • 探索用 SlideML 让大模型生成 PPT 的实验方法
  • NVMe-snsd性能优化指南:如何调优以获得最佳存储网络性能
  • 众包平台中数据标注任务的质检体系设计——以帮帮星球为例
  • 统计学、数据科学、大数据管理,哪个更适合做数据?2026大学生选方向不迷路
  • Kettle 定时任务实战:从Kitchen/Pan脚本到系统调度全解析
  • 3个颠覆性改变:NoFences如何重构你的Windows桌面思维
  • 记录无人机的安全按键以及安全指示灯
  • 互联网大厂Java面试实录:JVM、Spring Cloud、Redis高并发、Kafka与AI RAG综合能力全考察
  • AI 编程工具怎么系统学习?从 Cursor、Codex 到 Claude Code、Kiro
  • 如何在3分钟内免费获取百度文库完整文档?127行代码的完美解决方案
  • Ansible工作架构与原理详解
  • 【锦图简历 · 简历诊断与面试助手】HR 视角七维自查:让简历脱颖而出
  • SpringBoot自动装配和starter