Skip to content
AppendAutomationPublic

About

Cutler Hammer D50 Communications Library

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pyD50

Read and write Cutler-Hammer D50 PLCs from Python. pyD50 also puts the CPU in RUN or STOP, uploads and downloads the ladder program, and reads the CPU status. It speaks the same serial protocol as Cutler-Hammer Windows GPC (WinGPC), and its API follows pylogix: a PLC object whose methods return Response objects with .TagName, .Value and .Status.

Warning! PLCs control industrial equipment. Writing values, changing the CPU mode or downloading a program to a PLC that is operating equipment should be done with great care and is at your own risk.

Connecting

A D50 has an RS-232 programming port. pyD50 reaches it through a MOXA DE-311 (or any similar serial device server) on the network, or through a local serial port. The connection type is chosen from the address you give:

Address Connection
PLC('100.100.100.254') MOXA in Real COM mode: data port 950, command port 966
PLC('100.100.100.254', port=950) the same, port given explicitly
PLC('100.100.100.254', port=4001) or PLC('100.100.100.254:4001') MOXA in TCP Server mode (raw TCP, any port)
PLC('COM3'), PLC('/dev/ttyUSB0') local serial port (needs pip install pyserial)
  • Real COM mode is the mode used when the MOXA Windows driver maps a virtual COM port. pyD50 speaks the driver's command channel itself, so no driver is needed. A Real COM port serves one client at a time: close any program that has the virtual COM port open (e.g. take WinGPC offline) first.
  • In TCP Server mode the MOXA passes bytes straight through. The MOXA's own serial settings must then be 9600, 8 data bits, no parity, 1 stop bit.
  • transport='realcom' | 'tcp' | 'serial' overrides the automatic choice, e.g. for a Real COM device with a non-default data port.
  • Serial settings default to the D50's 9600 8N1: baudrate, parity, databits and stopbits arguments (or attributes). They are applied to a local serial port, and to the MOXA's port in Real COM mode.
  • cpu_id (attribute CPUID) is the PLC station number, default 255.
  • comm.ConnectionDescription shows what a PLC object will connect to.

Example

from pyd50 import PLC

with PLC('100.100.100.254') as comm:
    print(comm.Read('W0'))                      # W0 1234 Success
    print(comm.Read('W10', 5))                  # five consecutive words
    print(comm.Read('W4', datatype='REAL'))     # W4 1.5 Success
    print(comm.Read('R015.05'))                 # R015.05 False Success
    print(comm.Read(['TC099', 'PV100', 'SR0'])) # several operands, one request

    comm.Write('W0', 1234)
    comm.Write('W2', 100000, 'DWORD')
    comm.Write('M031.15', True)
    comm.Write([('W0', 7), ('W4', 2.5, 'REAL'), ('M031.15', 0)])

    print(comm.GetPLCMode())                    # Mode RUN Success
    comm.Stop()
    comm.Run()

    comm.Upload('program.json')                 # PLC -> file
    print(comm.VerifyProgram('program.json'))   # [] = identical
    comm.Download('program.json')               # file -> PLC

Addresses

Operands are written as WinGPC shows them. Bit numbers are 00-15, in decimal.

Area Example Meaning
R R015.05, R15 I/O relays (bit or word)
M M001.10, M1 internal relays
K K003.00, K3 keep relays
F F000.15, F0 special flags (F000.15 is the RUN flag)
TC TC099 timer/counter done contact (always a bit)
W W0 data words
SV SV10 timer/counter set values
PV PV10 timer/counter present values
SR SR0 system registers (SR0 = CPU ID, SR2 = watchdog, SR3/SR4 = scan time)

Timers and counters

A D50 timer or counter (e.g. the TIM Ch=00100 box in WinGPC) is spread over three areas, all addressed by its channel number. They can be named directly or the pylogix way:

Alias Same as Meaning
T100.PV or T100.ACC PV100 present (accumulated) value
T100.SV or T100.PRE SV100 set value held in the PLC
T100.DN TC100 done contact
T100 — all three in one request: {'PV': 6, 'SV': 10, 'DN': False}

C<n> is the same for counters, since timers and counters share channel numbers. The aliases work wherever an address does: reads, writes, arrays and batches. A whole T100 can be read but not written. Write T100.SV and the other members individually.

PV values are raw counts. WinGPC shows them in hex, and on the test PLC a timer's PV was seen to exceed its SV, so check the units against a known timer before relying on them.

Word operands read as WORD (unsigned 16-bit) unless a datatype is given: INT, DWORD, DINT, REAL (2 words) or LREAL (4 words). Multi-word values are stored low word first, which is how WinGPC's Change Value writes them. Bit operands read and write as True/False.

PLC methods

Method Description
Read(tag, count=1, datatype=None) One operand, count consecutive operands, or a list of operands / (tag, count, datatype) tuples
Write(tag, value, datatype=None) One operand, consecutive operands (value is a list), or a list of (tag, value[, datatype])
GetPLCMode() / SetPLCMode(mode) 'RUN' or 'STOP'
Run() / Stop() Put the CPU in RUN / STOP
GetDeviceProperties() CPU ID, project name, used memory, steps, mode, watchdog, scan times, flags
GetProjectName() Project name stored in the PLC
VerifyPassword(password) True if the password matches the PLC's
GetErrorTable() Raw words SR32-SR46 that WinGPC reads for its error table
Upload(filename=None) Read the program; Value is a Program, saved as JSON if a filename is given
Download(program, run=None) Write a Program or program file. run=None returns to the previous mode
VerifyProgram(program) List of program words that differ from the PLC (empty = identical)
ReadParameter(address, count) / WriteParameter(address, words) Raw parameter/program area access
Message(command, data) Send any D50 command, return the raw reply
Close() Close the connection (also done by with)

Failures never raise: Status says what went wrong, e.g. Timeout - No reply from the PLC, Invalid parameter value - ..., or PLC error - Command 0x06 returned status 02 (the PLC rejects an address beyond the end of an area).

Download safety

Download follows WinGPC's sequence:

  1. Stop the CPU.
  2. Write 0xFC97 over the first program word, which marks the program invalid.
  3. Write the program, the end marker, the project name and the size.
  4. Write the real first word, which marks the program valid.
  5. Restore the previous mode.

If the download is interrupted, the CPU stays in STOP with an invalid program; it never runs a half-written one. Run Download again to finish.

Tuning

These attributes can be changed on the PLC object:

  • SocketTimeout (2 s) and Retries (2) control waiting and retrying. Timeouts and CRC errors are retried.
  • FrameDelay (0.02 s) is the pause between frames.
  • The block sizes are MaxReadWords, MaxReadBits, MaxWriteWords, MaxBatchItems, MaxParameterRead and MaxParameterWrite. Their defaults are the largest sizes WinGPC was seen to use.

The protocol

  • Frame: [dest][source][cmd][len][data...][crc lo][crc hi].
  • CRC: CRC-16/MODBUS.
  • Addresses: the PLC is its CPU ID; the PC is 0xE1.
  • Exchange: each command is acknowledged (0x80 00). The PC then polls (0x00), and the PLC replies with 0x80 | cmd.
Cmd Function
01 / 02 read bits / write one bit
03 / 04 read / write words
05 / 06 random read / write (mixed bit and word items)
07 / 08 read / write the parameter and program area
10 begin program download

A full description is in docs/D50_WinGPC_Serial_Protocol.docx.

Tests

python -m unittest discover tests

The tests use tests/d50_simulator.py, a simulated D50 that listens on TCP. It also works as a stand-in PLC for trying out code:

python tests/d50_simulator.py --port 4001
python -c "from pyd50 import PLC; print(PLC('127.0.0.1:4001').Read('SR0'))"

pyD50 was tested against a D50 CPU-14 (ROM 2.08) through a MOXA DE-311 in Real COM mode. TCP Server mode and local serial ports use the same framing, but they have only been tested against the simulator.

License

MIT. See LICENSE.txt.

About

Cutler Hammer D50 Communications Library

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages