Debian系Linux中df1py3与Allen-Bradley PLC通信失败求助
我在Ubuntu和Raspberry Pi OS上尝试用Python库df1py3通过DF1协议与Allen-Bradley PLC通信,该库在Windows 10上测试正常,但在这两款Debian系发行版中运行时出现串口写入超时错误。用Python标准serial库测试串口通信正常,说明串口本身无问题。我已使用Python虚拟环境避免系统Python冲突。
错误信息
network-server@network-server-ThinkPad-T470-W10DG:~$ sudo /bin/python3 "/home/network-server/proj/df1py3-1 (2).0a45-py3-none-any/proj.py" [sudo] password for network-server: [INFO] Connecting to MicroLogix 1000 port /dev/ttyUSB0 speed 19200 [WARN] Waiting for clear any comm with PLC... [WARN] Waiting for clear comm- done [INFO] Connect Status: OK Running 1 Exception in thread Serial thread: Traceback (most recent call last): File "/usr/lib/python3.12/threading.py", line 1073, in _bootstrap_inner self.run() File "/usr/lib/python3.12/threading.py", line 1010, in run self._target(*self._args, **self._kwargs) File "/home/network-server/proj/df1py3-1 (2).0a45-py3-none-any/df1/models/df1_serial_plc.py", line 124, in _serial_loop self._send_loop() File "/home/network-server/proj/df1py3-1 (2).0a45-py3-none-any/df1/models/df1_serial_plc.py", line 136, in _send_loop self._serial_send(buffer) File "/home/network-server/proj/df1py3-1 (2).0a45-py3-none-any/df1/models/df1_serial_plc.py", line 141, in _serial_send self._plc.write(buffer) File "/usr/lib/python3/dist-packages/serial/serialposix.py", line 630, in write raise SerialTimeoutException('Write timeout') serial.serialutil.SerialTimeoutException: Write timeout [ERROR] Error send command <df1.models.reply_timeout.ReplyTimeout object at 0x713b7aa61b80> [ERROR] Read integer error [ERROR] Runtime error has happened
测试代码
# Example of how use class to read DF1 protocol (PCCC commands) from Allen Bradley PLC using serial # Authors: # - Jerther Thériault <jtheriault@metalsartigan.com> # - Reyan Valdes <rvaldes@itgtec.com> # Repositories # Original: https://github.com/metalsartigan/pydf1 # Adapted: https://github.com/reyanvaldes/pydf1 import time import serial from df1.models.df1_serial_client import Df1SerialClient from df1.models.df1_base import TIMER, COUNTER, BIT client = Df1SerialClient(plc_type='MicroLogix 1000', src=0x0, dst=0x1, port='/dev/ttyUSB0', baudrate=19200, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=3) client.connect() output =0 for i in range(3): print('Running',i+1) start_time = time.time() output += 1 output = 0 if output>15 else output # Write operations # client.write_binary(start=0,data=[0b1100]) # client.write_output(data=[output]) # 0b1101 # client.write_register(data=[11,25]) # client.write_float(start=0, data=[11.5,26.4]) # Reading operations OK try: print('N7:3-5', client.read_integer(start=90, total_int=8)) # Read Integers OK # print('N7:0-2', client.read_integer(start=0, total_int=3)) # Read Integers OK # print('Timer4:1', client.read_timer(start=1, category=TIMER.ACC)) # Read Timer OK # print('Counter5:0',client.read_counter(start=0, category=COUNTER.PRE)) # Read Counter OK # print('R6:0', client.read_register(start=0, total_int=4)) # Read Registers- CONTROL OK # print('B3:0', client.read_binary(start=0)) # Read Binary bits words OK # out0 = client.read_output(start=0, bit=BIT.ALL, total_int=1) # print('O0:0/1', out0)# , 'bit', client.bit_inspect(out0, BIT.BIT3)) # Read Outputs OK and Bits inspect # print('I1:0', client.read_input(start=0, bit=BIT.BIT1, total_int=2)) # Read Inputs # # Testing # print('Float8:0',client.read_float(start=0, total_float=2)) # Read Float except Exception as e: print('[ERROR] Runtime error has happened',e) client.reconnect() except KeyboardInterrupt: print('Control+C') break end_time = time.time() print('Elapsed(s)', end_time-start_time) print('-------------------') client.close() print('end testing, total reconnect', client.reconnect_total())
已尝试的解决步骤
- 修改串口权限
- 更换串口线缆
- 更换设备(从树莓派OS换到Ubuntu)
- 使用标准
serial库测试(通信正常,确认串口可用) - 更换目标PLC(从MicroLogix 1200换成带03 CPU的SLC500)
- 排查依赖库问题
- 在Stack Overflow发帖求助
解决建议
调整串口写入超时配置
查看df1_serial_plc.py中串口写入的超时设置,Linux下串口超时逻辑与Windows存在差异。尝试在Df1SerialClient初始化时显式添加write_timeout参数(比如write_timeout=5),延长写入等待时间。启用硬件流控
DF1协议通常依赖RTS/CTS硬件流控,Windows可能默认启用该配置,但Linux需要手动设置。在Df1SerialClient的参数中添加rtscts=True,验证是否解决超时问题。替换写入逻辑调试
在_serial_send方法中添加日志,打印待写入的buffer内容和实际写入字节数。尝试用标准serial库的写入代码替换self._plc.write(buffer),对比Windows与Linux下的写入行为差异。降级Python版本
当前使用Python 3.12,df1py3可能对新版本Python的串口库支持存在兼容问题。尝试降级到Python 3.10或3.11版本,重新测试通信。禁用串口硬件缓冲区
Linux串口默认的硬件缓冲区可能导致写入延迟,可在初始化串口后执行self._plc.set_buffer_size(rx_size=0, tx_size=0),或通过系统命令调整缓冲区大小。
内容的提问来源于stack exchange,提问作者Andy Sagraves

