使用pyserial二次连接/dev/ttyS0报错termios.error: (22, 'Invalid argument')
串口重连报错问题解决
问题现象
首次运行Python串口读取脚本无异常,停止后再次运行抛出termios.error: (22, 'Invalid argument')错误,重启socat模拟串口脚本后可再次运行一次。已在代码中调用ser.close(),但仍无法正常重连。
错误日志
Traceback (most recent call last): File "/home/tk/tkworkspace/billing-system-main/test/WeightMachineReading2.py", line 13, in <module> ser = serial.Serial( File "/home/tk/.local/lib/python3.10/site-packages/serial/serialutil.py", line 244, in __init__ self.open() File "/home/tk/.local/lib/python3.10/site-packages/serial/serialposix.py", line 332, in open self._reconfigure_port(force_update=True) File "/home/tk/.local/lib/python3.10/site-packages/serial/serialposix.py", line 517, in _reconfigure_port termios.tcsetattr(termios.error: (22, 'Invalid argument')
使用的Socat模拟脚本
socat -d -d pty,link=/dev/ttyS0,raw,group-late=dialout,mode=660,echo=0 pty,link=/dev/ttyS1,raw,group-late=dialout,mode=660,echo=0
Python串口读取脚本
import time import serial ser = serial.Serial( port='/dev/ttyS0', baudrate=115200, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.SEVENBITS, ) out = '' for i in range(1): waitingQueue = ser.inWaiting() time.sleep(2) if waitingQueue == 0: weight = "-- kg" print(weight.strip()) ser.close()
解决方案
- 修正数据位与校验位不匹配问题:7位数据位通常需要配合奇偶校验使用,无校验模式下应设置8位数据位。修改Python脚本中的
bytesize=serial.EIGHTBITS,这是触发错误的核心原因。 - 确保串口资源彻底释放:在调用
ser.close()前,显式重置串口属性,避免残留配置影响下次连接:import termios # 在ser.close()前添加 termios.tcsetattr(ser.fd, termios.TCSANOW, termios.tcgetattr(ser.fd)) - 调整Socat配置:去掉
raw参数或添加cs8明确指定8位数据位,避免终端模式冲突:socat -d -d pty,link=/dev/ttyS0,cs8,group-late=dialout,mode=660,echo=0 pty,link=/dev/ttyS1,cs8,group-late=dialout,mode=660,echo=0 - 使用上下文管理器自动管理串口:利用Python上下文管理器特性,自动处理串口的打开与关闭,避免手动释放资源遗漏:
import time import serial with serial.Serial( port='/dev/ttyS0', baudrate=115200, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, ) as ser: out = '' for i in range(1): waitingQueue = ser.inWaiting() time.sleep(2) if waitingQueue == 0: weight = "-- kg" print(weight.strip()) # 无需手动调用ser.close(),上下文管理器自动处理
内容的提问来源于stack exchange,提问作者kumar
相关产品推荐
相关产品推荐

