Arduino经HC-05蓝牙向树莓派传数时字节解码异常问题
HC-05 与树莓派串口蓝牙通信乱码解决方案
按优先级从高到低排查,99%的同类问题都能解决:
1. 第一优先级:确认HC-05实际波特率匹配
- HC-05出厂默认波特率不是统一的9600,市面常见批次默认38400,旧批次有57600的版本。你USB直连Arduino正常是因为走的板载USB转串口链路,和HC-05的蓝牙串口参数完全独立,两边波特率差一倍以上就会全是
b'\xff'、b'\xf9'这类乱码。 - 操作方法:按住HC-05上的KEY按键上电,等指示灯进入慢闪的AT模式后,接USB转TTL连电脑,串口助手发
AT+UART?查询当前实际波特率。要么把Arduino、Python端的串口波特率改成查询到的值,要么发AT+UART=9600,0,0把模块波特率改成9600,改完断电重启模块生效。
2. 第二优先级:检查硬件接线与电平
- HC-05和Arduino的串口必须交叉接:HC-05的TX接Arduino的RX,HC-05的RX接Arduino的TX,同序连接必然收不到正确数据。
- HC-05是3.3V供电、3.3V逻辑,VCC不要接Arduino的5V引脚,Arduino的5V TX输出直接接HC-05的RX会长期过压损坏模块端口,引发随机乱码,建议在HC-05的RX线上串1k电阻做简单降压。
3. 第三优先级:修正两端代码的逻辑bug
你现有代码有两个容易引发解析异常的问题:
- Arduino端
Serial.print(n)发送数字时,输出的是ASCII字符串而非二进制字节,比如n=10会连续发'1'、'0'两个字节,Python端每次只读1个字节必然出现拆包错误。 - Python端用
inWaiting()>0就读单字节的逻辑,在蓝牙串口场景下很容易读到链路碎片数据,没有帧边界标记必然解析混乱。
修正后Arduino测试代码
void setup() { // 波特率必须和HC-05实际参数完全一致 Serial.begin(9600); } void loop() { for (byte n = 0; n < 255; n++) { // 每次发送后加换行符作为帧结束标记 Serial.println(n); delay(50); } }
修正后Python测试代码
import serial import time port = "/dev/rfcomm0" # 波特率和HC-05、Arduino端保持完全一致 serialData = serial.Serial(port, 9600, timeout=1) # 清空上电时缓冲区残留的乱码 serialData.reset_input_buffer() time.sleep(0.5) def run(): while True: try: # 按行读取,遇到换行符才返回,自动处理蓝牙分包问题 line = serialData.readline().decode('utf-8').strip() if line: print(f"收到数据: {line}") except: # 解码失败时清空缓冲区残留垃圾数据,避免持续报错 serialData.reset_input_buffer() if __name__ == "__main__": run()
4. 第四优先级:重置树莓派rfcomm绑定
如果以上步骤做完还是异常,先清除旧的蓝牙配对重新绑定:
- 执行
sudo rfcomm release all释放所有现有rfcomm绑定 - 执行
bluetoothctl进入蓝牙控制台,用remove [HC-05的MAC地址]删掉旧配对记录,重新执行pair、trust、connect完成配对 - 执行
sudo chmod 666 /dev/rfcomm0给串口设备加普通用户读写权限,避免权限不足导致的读数据错误。
排查技巧:先不要接Arduino,把HC-05接USB转TTL连电脑,电脑配对HC-05后开串口助手自发自收,树莓派端读rfcomm0验证链路,先确认蓝牙串口本身传输正常,再接Arduino调试,能大幅缩短排查时间。
内容的提问来源于stack exchange,提问作者PabloUY
相关产品推荐
相关产品推荐

