使用pyserial接收串口数据时的解码及数据异常问题求助
串口通信问题排查与解决
我来帮你梳理下这两个实际调试中常见的串口问题,一步步来解决~
问题1:接收数据格式异常(出现b'\r0\r\n'、b'350350\r\n'等)
这种情况大概率不是Python代码的核心问题,主要原因集中在两个方向:
可能的原因
- Arduino发送逻辑重复/混乱:比如你的Arduino代码里可能在循环中无限制地调用
Serial.println(),或者在中断、传感器读数的逻辑里重复触发了发送,导致两次数据粘在一起(比如350350就是两次350的发送内容被连在了一起);b'\r0\r\n'这种格式很可能是Arduino端的变量更新不及时,或者发送时的字符串拼接错误。 - Python端串口缓存未清理:如果程序重启前串口有残留数据,
readline()可能会一次性读取到累积的缓存内容,出现异常格式。
解决建议
- 优先检查Arduino代码:
确保发送逻辑是每次只发送一次有效数据,比如传感器读数后只调用一次Serial.println(your_value);,避免在快速循环里重复发送;如果是用中断触发发送,要加标志位避免重复触发。 - 清理Python端串口缓存:
在初始化串口后,加入ser.flushInput()清空输入缓存,避免残留的旧数据干扰:ser = serial.Serial(...) ser.flushInput() # 新增这一行 print("connected to: " + ser.portstr) - 优化数据读取逻辑:
可以尝试用ser.read_until(b'\n')替代readline(),有时候readline()对\r\n的识别会因为时序问题出偏差;另外可以对接收的数据做简单校验,比如用正则提取有效数字:import re # ... 其他代码 data = ser.read_until(b'\n') match = re.search(rb'\d+', data) # 匹配数字部分 if match: valid_data = match.group().decode('ascii') print(f"有效数据: {valid_data}")
问题2:解码后有多余空白,写入文件也存在
你的怀疑是对的!这就是Arduino默认发送的\r\n(回车+换行)导致的——Serial.println()会在数据末尾自动添加\r和\n,解码后这些控制字符就会表现为多余的换行或空白。
解决方法
- 解码后清理空白字符:
用strip()方法可以一次性去掉字符串开头/结尾的所有空白字符(包括\r、\n、空格),或者用rstrip('\r\n')精准去掉换行回车:data_encode = data.decode('ascii').strip() # 或者精准处理:data_encode = data.decode('ascii').rstrip('\r\n') - 优化写入文件的逻辑:
处理后的内容可以按需添加换行,让文件里的内容更整齐,同时避免写入空内容:while True: data = ser.readline() if not data: # 如果没读到数据,跳过循环 continue data_encode = data.decode('ascii').strip() print(f"处理后输出: {data_encode}") with open('output.txt', 'a') as text_file: text_file.write(data_encode + '\n') # 手动添加换行,控制文件格式 time.sleep(0.1) # 加小延时,降低CPU占用 - 解码方式确认:
用ascii解码是完全正确的,因为Arduino发送的是ASCII格式的数字和控制字符,只要你的数据里没有中文或非ASCII字符,就不会有解码错误。
内容的提问来源于stack exchange,提问作者enyo
相关产品推荐
相关产品推荐

