Andy Sagraves
Andy Sagraves

Reputation: 1

df1py3 import not working in debian linux

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:

  1. Change serial port permissions
  2. Change serial cable
  3. Change computer (Raspbian to Ubuntu)
  4. Using standard serial import (worked, so i know serial communication in general works)
  5. Change PLC I was speaking to (Micrologix 1200 to SLC500 with 03 CPU)
  6. Go to dependencies and find what was messing stuff up
  7. Posted this to stack overflow

Upvotes: 0

Views: 36

Answers (1)

chris ewing
chris ewing

Reputation: 1

have you tried running the script as root? you will need root privileges to use the serial ports in linux.

after the test with the command 'sudo python3 yourfilename.py', you can add your username to the dialout group.

Upvotes: 0

Related Questions