I have Ubuntu and Raspberry Pi OS machines that I am trying to use to talk with Allen-Bradley PLCs using df1 protocol. There is a python import aptly called df1py3 that can communicate with these PLCs, and is capable with working on windows (I have tested it successfully on Windows 10). However, when I try it in both Linux distros, I get a helluva error message that seems to amount to: 'you can't talk over the serial port.' However, I am able to communicate using the standard serial import in python, so the serial ports do work. I've spent quite a bit of time on this and am at a loss, so any help would be greatly appreciated. It shoudl be noted that I am using a python virtual environment to keep from conflicting with the preinstalled python config. Here's the code and the error:
Error message:
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
Code:
Example of how use class to read DF1 protocol (PCCC commands) from Allen Bradley PLC using serial
# Authors:
# - Jerther Thériault <[email protected]>
# - Reyan Valdes <[email protected]>
# 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())
Tried:
- Change serial port permissions
- Change serial cable
- Change computer (Raspbian to Ubuntu)
- Using standard serial import (worked, so i know serial communication in general works)
- Change PLC I was speaking to (Micrologix 1200 to SLC500 with 03 CPU)
- Go to dependencies and find what was messing stuff up
- Posted this to stack overflow