Try reading / writing PLC registers with SLMP. I wrote about bit access in binary code in this article.
First, make a connection with the PLC.
HOST = '192.168.1.1'
PORT = 1026
BUFSIZE = 4096
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
sock.settimeout(3)
This is a basic parameter to be set in the SLMP request message.
Read the CPU unit register of the PLC that is directly connected to the host PC via Ethernet. In this case, set the PLC access destination as follows according to the SLMP regulations.
Item | Value |
---|---|
Requested network number | 00h |
Request destination area code | FFh |
Requested unit I / O number | 3FFh |
Request destination multi-drop area code | 0 |
The monitoring timer is set in units of 250ms. This time set it to 4 (1 second).
This time we will use the data register. Word access. The ASCII code is "D *" and the binary code is A8h.
Assemble the request message and send the frame. Use the word access of the Read command (0401h).
In binary code, it is necessary to store the value in little endian except for the subheader. Be careful because only the subheader is big endian for some reason.
Reads the values of the three registers D0001 to D0003.
# '5000 00 FF 03FF 00 0018 0020 0401 0000 D* 000001 0003'
data = [
0x50,0x00, #Subheader
0x00, #Requested network number
0xFF, #Request destination area code
0xFF,0x03, #Requested unit I/O number
0x00, #Request destination multi-drop area code
0x0C,0x00, #Request data length(Set later)
0x20,0x00, #Monitoring timer
0x01,0x04, #command
0x00,0x00, #Subcommand
0x01,0x00,0x00, #First device number
0xA8, #Device code
0x03,0x00 #Device score
]
#Set request data length
data[7] = len(data[9:]) & 0xFF
data[8] = (len(data[9:]) >> 16) & 0xFF
#Send request
sock.send(bytes(data))
#Receive response
res = sock.recv(BUFSIZE)
print (*[format(i,'02X') for i in res])
The received data is as follows. The current register values were all 0.
D0 00 00 FF FF 03 00 08 00 00 00 00 00 00 00 00 00
Assemble the request message and send the frame. Use the word access of the Write command (1401h).
Write values to the five registers D0000 to D0004.
# '5000 00 FF 03FF 00 0018 0020 0401 0000 D* 000000 0005 1122 3344 5566 7788 99AA'
data = [
0x50,0x00, #Subheader
0x00, #Requested network number
0xFF, #Request destination area code
0xFF,0x03, #Requested unit I/O number
0x00, #
0x00,0x00, #Request data length(Set later)
0x04,0x00, #Monitoring timer
0x01,0x14, #command(1401H)
0x00,0x00, #Subcommand
0x00,0x00,0x00, #First device number
0xA8, #Device code
0x05,0x00, #Device score
0x11,0x22, # D0000
0x33,0x44, # D0001
0x55,0x66, # D0002
0x77,0x88, # D0003
0x99,0xAA, # D0004
]
#Set request data length
data[7] = len(data[9:]) & 0xFF
data[8] = (len(data[9:]) >> 16) & 0xFF
#Send request
sock.send(bytes(data))
#Receive response
res = sock.recv(BUFSIZE)
After the write is completed, if you execute the Read command again, the execution result will be as follows.
D0 00 00 FF FF 03 00 08 00 00 00 33 44 55 66 77 88
You can see that writing and reading are done correctly.
sock.close()
Recommended Posts