使用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
相关产品推荐
相关产品推荐

