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

基于Python与Arduino(HC-06)的蓝牙通信:数据分段接收问题

解决HC-06蓝牙模块与Python通信时数据分段接收的问题

这个问题其实很常见,因为蓝牙RFCOMM本质是流式传输——就像水管里的水流,数据会被拆成若干个数据包发送,而你用sock.recv(10)的时候,它只会返回当前缓冲区里最多10字节的数据,不会等凑够10字节才返回,所以就出现了分段输出的情况。

下面给你两种靠谱的解决办法:

方法1:固定长度接收,凑够完整数据再处理

既然你明确每次发送的是16位字符串,那可以让Python循环接收,直到拿到足够长度的数据:

修改后的Python代码:

import bluetooth

sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
sock.connect(("00:13:04:83:EC:45", 1))
# 设置超时,避免意外卡死(可选,可根据需求调整时长)
sock.settimeout(5)

try:
    while True:
        # 目标接收长度是16字节(你的字符串是16个ASCII字符,每个占1字节)
        target_len = 16
        received = b''
        while len(received) < target_len:
            # 每次只接收剩余需要的字节数
            chunk = sock.recv(target_len - len(received))
            if not chunk:
                # 处理连接断开的情况
                break
            received += chunk
        # 转成字符串输出
        print(received.decode('ascii'))
finally:
    sock.close()

方法2:添加分隔符,按完整消息接收

另一种更灵活的方式是让Arduino发送数据时加上分隔符(比如换行符\n),然后Python那边按分隔符读取完整的一次消息——就算以后发送的字符串长度变了,也不用改代码:

修改后的Arduino代码:

void setup(){
  BTserial.begin(9600);
}

void loop() {
  // 末尾加换行符作为消息结束标记
  BTserial.println("0123456789012345");
  delay(500);
}

对应的Python代码:

import bluetooth

sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
sock.connect(("00:13:04:83:EC:45", 1))
sock.settimeout(5)

try:
    while True:
        # readline会自动读取到换行符为止,拿到完整的一次发送内容
        data = sock.readline().strip()
        if data:
            print(data.decode('ascii'))
finally:
    sock.close()

两种方法都能解决你的问题,方法2更通用,推荐优先使用~

内容的提问来源于stack exchange,提问作者SuperLog GK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:51:19