Python串口数据读取代码排查:仅能读取首个串口数据求助
排查Python多串口读取代码的问题
先帮你拆解下代码里的核心问题,以及对应的修复方案:
1. 变量覆盖与未定义的低级错误
你这段代码里有明显的变量操作错误:
read_ser1=ser1.readline() read_ser1=ser2.readline() print(read_ser2)
- 第二行直接把
ser2的读取结果覆盖了ser1的数据,导致你永远拿不到ser1的串口内容 - 最后打印的
read_ser2根本没定义过,运行到这里会直接抛出NameError异常
2. 阻塞式读取导致的串口抢占问题
serial.readline()是阻塞式调用——程序会停在这行代码,直到对应串口有数据返回才会继续执行。你的代码逻辑是:先等ser有数据,拿到后再等ser1有数据,拿到后再等ser2有数据。如果ser1或ser2一直没数据,程序就会卡在那里不动,自然永远看不到后面串口的数据。
修复后的代码方案
这里给你两种实用的修复思路,根据你的场景选择:
方案一:非阻塞轮询读取(轻量简单)
通过设置timeout=0让readline()变成非阻塞,没有数据时直接返回空,这样程序可以循环轮询三个串口:
import serial import time # 初始化串口时直接指定波特率和超时,无需重复设置baudrate ser = serial.Serial("/dev/ttyACM0", 9600, timeout=0) ser1 = serial.Serial("/dev/ttyUSB0", 9600, timeout=0) ser2 = serial.Serial("/dev/ttyUSB1", 9600, timeout=0) while True: # 读取并解码数据,去除多余的换行空格 read_ser = ser.readline().decode('utf-8').strip() read_ser1 = ser1.readline().decode('utf-8').strip() read_ser2 = ser2.readline().decode('utf-8').strip() # 只打印有数据的内容,避免空行刷屏 if read_ser: print(f"[ttyACM0] {read_ser}") if read_ser1: print(f"[ttyUSB0] {read_ser1}") if read_ser2: print(f"[ttyUSB1] {read_ser2}") # 加小延迟降低CPU占用 time.sleep(0.01)
方案二:多线程读取(高效稳定)
给每个串口单独开一个线程,各自独立处理读取逻辑,彻底避免阻塞问题:
import serial import threading def monitor_serial(port, baudrate=9600): ser = serial.Serial(port, baudrate, timeout=1) print(f"开始监听串口 {port}...") while True: data = ser.readline().decode('utf-8').strip() if data: print(f"[{port}] {data}") # 启动三个守护线程分别监听三个串口 threading.Thread(target=monitor_serial, args=("/dev/ttyACM0",), daemon=True).start() threading.Thread(target=monitor_serial, args=("/dev/ttyUSB0",), daemon=True).start() threading.Thread(target=monitor_serial, args=("/dev/ttyUSB1",), daemon=True).start() # 主线程保持运行 while True: pass
额外提示
- 确认串口路径正确:可以用
ls /dev/tty*命令查看当前连接的串口设备 - 权限问题:如果提示无法打开串口,执行
sudo usermod -aG dialout $USER,然后重新登录即可 - 乱码处理:如果解码时出错,尝试换成
decode('gbk')或者decode('utf-8', errors='ignore')
内容的提问来源于stack exchange,提问作者Kirill_code
相关产品推荐
相关产品推荐

