-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
I have an HMI panel that is Modbus TCP master, my device is Modbus TCP slave.
HMI-master(10.0.0.1)---ethernet-->Device-slave(10.0.0.2:502)
When I run the server I can see transactions in the debug log, tcpdump even shows me interactions happening with the two clients.
However, when I try to connect to the Server locally on the same device with a separate script, I do not get the updated values.
The connection to the HMI was tested as working on a windows laptop running Modbus Slave so the data path is confirmed.
It's also worth noting that when making modifications to the server with my client test code, I do see those changes take place, but not when trying to get at the HMI's values it's sending over.
I feel I may be missing something fundamental here about how the server operates and maps data blocks to registers but I can't be sure.
If anyone can offer up some advice I'd greatly appreciate it.
A brief snippet of tcpdump.
root@device# tcpdump -i eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
16:07:06.623834 IP 10.0.0.1.57102 > 10.0.0.2.502: Flags [P.], seq 2884696980:2884696992, ack 1568911665, win 33580, length 12
16:07:06.924802 IP 10.0.0.1.57102 > 10.0.0.2.502: Flags [P.], seq 12:24, ack 1, win 33580, length 12
16:07:06.974903 IP 10.0.0.1.57090 > 10.0.0.2.502: Flags [FP.], seq 2882294909:2882294957, ack 2982870381, win 33580, length 48
16:07:06.975181 IP 10.0.0.2.502 > 10.0.0.1.57090: Flags [R], seq 2982870381, win 0, length 0
16:07:07.225833 IP 10.0.0.1.57102 > 10.0.0.2.502: Flags [P.], seq 24:36, ack 1, win 33580, length 12
16:07:07.314122 IP 10.0.0.2.502 > 10.0.0.1.57102: Flags [S.], seq 1568911664, ack 2884696968, win 29200, options [mss 1460,nop,nop,sackOK], length 0
16:07:07.314672 IP 10.0.0.1.57102 > 10.0.0.2.502: Flags [.], ack 1, win 33580, length 0
16:07:07.527945 IP 10.0.0.1.57102 > 10.0.0.2.502: Flags [F.], seq 49, ack 1, win 33580, length 0
16:07:07.534481 IP 10.0.0.1.57103 > 10.0.0.2.502: Flags [S], seq 2885027223, win 32768, options [mss 1460,nop,nop,sackOK], length 0
16:07:07.534762 IP 10.0.0.2.502 > 10.0.0.1.57103: Flags [S.], seq 2381535302, ack 2885027224, win 29200, options [mss 1460], length 0
16:07:07.535366 IP 10.0.0.1.57103 > 10.0.0.2.502: Flags [.], ack 1, win 33580, length 0
tcp dump when the server is running
root@device:# tcpdump -i eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
16:19:15.854508 IP 10.0.0.1.58204 > 10.0.0.2.502: Flags [P.], seq 3097935189:3097935201, ack 3309520655, win 32458, length 12
16:19:15.859986 IP 10.0.0.2.502 > 10.0.0.1.58204: Flags [P.], seq 1:50, ack 12, win 29200, length 49
16:19:15.867594 IP 10.0.0.1.58204 > 10.0.0.2.502: Flags [P.], seq 12:24, ack 50, win 32409, length 12
16:19:15.871266 IP 10.0.0.2.502 > 10.0.0.1.58204: Flags [P.], seq 50:99, ack 24, win 29200, length 49
16:19:15.880512 IP 10.0.0.1.58204 > 10.0.0.2.502: Flags [P.], seq 24:36, ack 99, win 32360, length 12
16:19:15.884029 IP 10.0.0.2.502 > 10.0.0.1.58204: Flags [P.], seq 99:112, ack 36, win 29200, length 13
16:19:15.891539 IP 10.0.0.1.58204 > 10.0.0.2.502: Flags [P.], seq 36:48, ack 112, win 32347, length 12
16:19:15.895015 IP 10.0.0.2.502 > 10.0.0.1.58204: Flags [P.], seq 112:123, ack 48, win 29200, length 11
16:19:15.902513 IP 10.0.0.1.58204 > 10.0.0.2.502: Flags [P.], seq 48:60, ack 123, win 32336, length 12
16:19:15.906159 IP 10.0.0.2.502 > 10.0.0.1.58204: Flags [P.], seq 123:172, ack 60, win 29200, length 49
16:19:15.913526 IP 10.0.0.1.58204 > 10.0.0.2.502: Flags [P.], seq 60:72, ack 172, win 32287, length 12
16:19:15.917142 IP 10.0.0.2.502 > 10.0.0.1.58204: Flags [P.], seq 172:221, ack 72, win 29200, length 49
16:19:15.926524 IP 10.0.0.1.58204 > 10.0.0.2.502: Flags [P.], seq 72:84, ack 221, win 32238, length 12
16:19:15.930067 IP 10.0.0.2.502 > 10.0.0.1.58204: Flags [P.], seq 221:234, ack 84, win 29200, length 13
16:19:15.937525 IP 10.0.0.1.58204 > 10.0.0.2.502: Flags [P.], seq 84:96, ack 234, win 32225, length 12
16:19:15.940955 IP 10.0.0.2.502 > 10.0.0.1.58204: Flags [P.], seq 234:245, ack 96, win 29200, length 11
16:19:15.948512 IP 10.0.0.1.58204 > 10.0.0.2.502: Flags [P.], seq 96:108, ack 245, win 32214, length 12
16:19:15.952029 IP 10.0.0.2.502 > 10.0.0.1.58204: Flags [P.], seq 245:294, ack 108, win 29200, length 49
16:19:15.959525 IP 10.0.0.1.58204 > 10.0.0.2.502: Flags [P.], seq 108:120, ack 294, win 32165, length 12
16:19:15.963076 IP 10.0.0.2.502 > 10.0.0.1.58204: Flags [P.], seq 294:343, ack 120, win 29200, length 49
16:19:15.972515 IP 10.0.0.1.58204 > 10.0.0.2.502: Flags [P.], seq 120:132, ack 343, win 33580, length 12
16:19:15.976082 IP 10.0.0.2.502 > 10.0.0.1.58204: Flags [P.], seq 343:356, ack 132, win 29200, length 13
16:19:15.980579 IP 10.0.0.1.58204 > 10.0.0.2.502: Flags [P.], seq 132:144, ack 356, win 33567, length 12
16:19:15.984008 IP 10.0.0.2.502 > 10.0.0.1.58204: Flags [P.], seq 356:367, ack 144, win 29200, length 11
16:19:15.991531 IP 10.0.0.1.58204 > 10.0.0.2.502: Flags [P.], seq 144:156, ack 367, win 33556, length 12
16:19:15.995115 IP 10.0.0.2.502 > 10.0.0.1.58204: Flags [P.], seq 367:416, ack 156, win 29200, length 49
16:19:16.002507 IP 10.0.0.1.58204 > 10.0.0.2.502: Flags [P.], seq 156:168, ack 416, win 33507, length 12
16:19:16.006091 IP 10.0.0.2.502 > 10.0.0.1.58204: Flags [P.], seq 416:465, ack 168, win 29200, length 49
The server debug output
DEBUG:pymodbus.factory:Factory Request[3]
DEBUG:pymodbus.datastore.context:validate[3] 100:20
DEBUG:pymodbus.datastore.context:getValues[3] 100:20
DEBUG:pymodbus.server.sync:send: 46500000002b01032800000000000000000000000000000000000000000000000000000000000000000000000000000000
DEBUG:pymodbus.server.sync:0x46 0xb4 0x0 0x0 0x0 0x6 0x1 0x3 0x0 0x9 0x0 0x1
DEBUG:pymodbus.transaction:0x46 0xb4 0x0 0x0 0x0 0x6 0x1 0x3 0x0 0x9 0x0 0x1
DEBUG:pymodbus.factory:Factory Request[3]
DEBUG:pymodbus.datastore.context:validate[3] 10:1
DEBUG:pymodbus.datastore.context:getValues[3] 10:1
DEBUG:pymodbus.server.sync:send: 46b4000000050103020000
DEBUG:pymodbus.server.sync:0x47 0x18 0x0 0x0 0x0 0x6 0x1 0x3 0x0 0x63 0x0 0x14
DEBUG:pymodbus.transaction:0x47 0x18 0x0 0x0 0x0 0x6 0x1 0x3 0x0 0x63 0x0 0x14
DEBUG:pymodbus.factory:Factory Request[3]
DEBUG:pymodbus.datastore.context:validate[3] 100:20
DEBUG:pymodbus.datastore.context:getValues[3] 100:20
DEBUG:pymodbus.server.sync:send: 47180000002b01032800000000000000000000000000000000000000000000000000000000000000000000000000000000
DEBUG:pymodbus.server.sync:0x47 0x7c 0x0 0x0 0x0 0x6 0x1 0x3 0x0 0x9 0x0 0x1
DEBUG:pymodbus.transaction:0x47 0x7c 0x0 0x0 0x0 0x6 0x1 0x3 0x0 0x9 0x0 0x1
DEBUG:pymodbus.factory:Factory Request[3]
DEBUG:pymodbus.datastore.context:validate[3] 10:1
DEBUG:pymodbus.datastore.context:getValues[3] 10:1
DEBUG:pymodbus.server.sync:send: 477c000000050103020000
DEBUG:pymodbus.server.sync:0x47 0xe0 0x0 0x0 0x0 0x6 0x1 0x3 0x0 0x63 0x0 0x14
DEBUG:pymodbus.transaction:0x47 0xe0 0x0 0x0 0x0 0x6 0x1 0x3 0x0 0x63 0x0 0x14
DEBUG:pymodbus.factory:Factory Request[3]
DEBUG:pymodbus.datastore.context:validate[3] 100:20
The server code, modified from here :
https://github.com/riptideio/pymodbus/blob/master/examples/common/modbus-payload-server.py
#!/usr/bin/env python
#---------------------------------------------------------------------------#
# import the various server implementations
#---------------------------------------------------------------------------#
from pymodbus.server.sync import StartTcpServer
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
#---------------------------------------------------------------------------#
# import the payload builder
#---------------------------------------------------------------------------#
from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.payload import BinaryPayloadBuilder
#---------------------------------------------------------------------------#
# configure the service logging
#---------------------------------------------------------------------------#
import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)
#---------------------------------------------------------------------------#
# Here we use the same reference block for each underlying store.
#---------------------------------------------------------------------------#
store = ModbusSlaveContext(
di = ModbusSequentialDataBlock(0, [0]*10),
co = ModbusSequentialDataBlock(0, [0]*10),
hr = ModbusSequentialDataBlock(0, [0]*220),
ir = ModbusSequentialDataBlock(0, [0]*250)
)
context = ModbusServerContext(slaves=store, single=True)
#---------------------------------------------------------------------------#
# initialize the server information
#---------------------------------------------------------------------------#
# If you don't set this or any fields, they are defaulted to empty strings.
#---------------------------------------------------------------------------#
identity = ModbusDeviceIdentification()
identity.VendorName = 'Pymodbus'
identity.ProductCode = 'PM'
identity.VendorUrl = 'http://github.com/bashwork/pymodbus/'
identity.ProductName = 'Pymodbus Server'
identity.ModelName = 'Pymodbus Server'
identity.MajorMinorRevision = '1.0'
#---------------------------------------------------------------------------#
# run the server you want
#---------------------------------------------------------------------------#
StartTcpServer(context, identity=identity, address=("10.0.0.2", 502))
The client test code (also running on the same machine as the server):
I use this to verify the registers set up by the Server are getting written to by the HMI.
When I run it I cannot find the values that the HMI is supposed to be writing to the server.
from pymodbus.client.sync import ModbusTcpClient as ModbusClient
client = ModbusClient("10.0.0.2", port=502)
for x in xrange(200):
r = client.read_holding_registers(x)
print vars(r)
The variable mappings on the HMI
PROFILE 40100
RATE 40005
CIN 40003
LBS/FT 40004
COLOR 40200
CIN2 40006
RATE2 40001
2LBS/FT 40008
TRIGGER 40010