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

使用Pyserial读取Arduino串口时程序卡在ser.readline()如何解决

串口readline阻塞问题解决方案

核心原因说明

你当前代码设置ser.timeout = None,属于永久阻塞模式,只要没有读到符合要求的换行符,程序就会一直停在读取步骤不会退出。

分步解决方案

1. 调整超时配置

将永久阻塞改为有限超时,避免程序无限卡住:

ser.timeout = 3 # 单位为秒,超过3秒未读到数据就返回空值

2. 补全串口通信参数

仅设置波特率不足以完成串口通信,需要确保上位机的串口配置和下位设备完全一致,补充完整串口参数(以下为常用的8N1配置,可根据你的设备实际参数调整):

ser.bytesize = serial.EIGHTBITS    # 数据位8位
ser.parity = serial.PARITY_NONE    # 无校验位
ser.stopbits = serial.STOPBITS_ONE # 停止位1位

3. 适配设备返回格式

readline() 仅在读取到换行符\n/\r\n时才会结束读取,如果你的设备返回数据不带换行符,可以改用两种方案:

  • 固定长度读取:用ser.read(固定字节数)读取指定长度的返回数据
  • 先判断可读数据量再读取:
import time
# 写命令后加100ms延迟,等待设备处理返回
time.sleep(0.1)
if ser.in_waiting > 0:
    p = ser.read(ser.in_waiting) # 读取所有已经到达缓冲区的数据

4. 检查Linux设备权限

/dev/ttyACM*类设备默认需要dialout用户组权限,权限不足会出现能打开设备但无法读写的问题:

  • 临时测试可以执行sudo chmod 666 /dev/ttyACM0(替换为你的实际设备路径)
  • 永久生效可以执行sudo usermod -aG dialout 你的系统用户名,执行后重启系统生效

修正后的参考代码

import serial
import time

ACM = "/dev/ttyACM0" # 替换为你的实际设备路径
cmd = b"your_command\n" # 注意发送的命令建议带换行,符合串口通信惯例

ser = serial.Serial(ACM)
ser.baudrate = 115200
ser.bytesize = serial.EIGHTBITS
ser.parity = serial.PARITY_NONE
ser.stopbits = serial.STOPBITS_ONE
ser.timeout = 3

ser.flushInput()
ser.flushOutput()
ser.write(cmd)
# 等待设备处理返回
time.sleep(0.1)

# 读取所有可用数据
if ser.in_waiting:
    p = ser.read(ser.in_waiting)
    pr = p.decode("utf-8", errors="ignore") # 增加错误忽略,避免非法字符导致解码崩溃
    print(cmd)
    print(pr)
else:
    print("未读取到设备返回数据")

ser.close()
print("Closed")

内容的提问来源于stack exchange,提问作者Naresh rookie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 15:24:04