Python串口通信时decode("utf-8")解码失败问题排查
报错核心原因
触发UnicodeDecodeError本质是你读到的字节流根本不是合法的UTF-8编码数据,问题出在两个配置和逻辑错误上:
- 波特率配置错误:你收发两端写的波特率是
19600,这不是标准串口波特率,常规对应档位的标准值是19200,属于手滑输错参数。串口通信要求两端波特率、校验位、数据位、停止位完全一致才能正确传输字节,波特率不匹配会导致硬件采样错位,本来发出去的0x38(对应字符'8')、0x30(对应字符'0')会被采样成0x98这类完全错误的乱码字节,自然不符合UTF-8编码规则。 - 读取逻辑有缺陷:你调用
ser8.read()且不传参数时,pyserial默认一次只读1个字节。就算波特率配对了,串口是无边界的流传输,既可能混入线路噪声产生的非法字节,也可能在多字节UTF-8字符传输时只读到半截序列,拿到半截字节直接硬解必然会触发解码错误。
修复步骤
- 先统一串口基础参数
把收发两端的波特率从错误的19600改成标准值19200,保持两边数据位8位、停止位1位、无校验(pyserial默认就是这个配置,没特殊需求不用改)。 - 替换逐字节读取的逻辑,用带缓冲的方式读完整数据再解码
如果是传输文本内容,最简单的方式是发送端每次发完内容加换行符\n作为包边界,接收端用readline()一次读一整行,解码时增加错误容忍参数,避免偶发噪声直接导致程序崩溃。
修复后的发送端代码:
import serial from time import sleep ser7 = serial.Serial('COM7', 19200) while True: # 末尾加换行符作为帧边界 ser7.write('80\n'.encode('utf-8')) sleep(1)
修复后的接收端代码:
import serial ser8 = serial.Serial('COM8', 19200) while True: # 按行读取,遇到非法字节直接跳过不抛错 serPrint = ser8.readline().decode("utf-8", errors="ignore").strip() if serPrint: print(serPrint)
补充说明:如果你的场景本身就是传二进制非文本数据,不要硬用UTF-8解码,直接按字节处理原始二进制值即可,只有确认传输的是纯文本内容时才需要做UTF-8解码。
内容的提问来源于stack exchange,提问作者Some Student
相关产品推荐
相关产品推荐

