Skip to content

Debugging guide

Martti T edited this page Nov 21, 2020 · 12 revisions

Debugging guide

Follow these steps to pinpoint here your problem lies. It could be:

  • your code has typos (using wrong unitID, wrong IP/port)
  • this library is buggy
  • modbus device is not working as it should/expected (answers very slowly - causing timeouts, addresses are off-by-one)
  • there are network problems (firewall is blocking outgoing packets, incoming packets, packets are lost, fragmented)

0. Double check request arguments

  • is unidID, quantity, ip, port etc correct?

  • are your timeouts set reasonable lengths? There are usually 3 different timeouts involved. If you are using BinaryStreamConnection then these are relevant

    ->setConnectTimeoutSec(1.5) // timeout when establishing connection to the server
    ->setWriteTimeoutSec(0.5) // timeout when writing/sending packet to the server
    ->setReadTimeoutSec(0.3) // timeout when waiting response from server

1. Try this library example

Make request to modbus with Read Holding Register request. If one of it works - it is a good sign.

Using 2 different network codes:

  • examples/fc3.php - uses this library networking code

    Example output (tells us what was sent, what was received):

    2020-11-14 20:46:50.900994: [debug] msg: "Connected"
    2020-11-14 20:46:50.918577: [debug] msg: "Data sent", data: array (
      1 => '19ed00000006000301000006',
    )
    2020-11-14 20:46:50.918623: [debug] msg: "Polling data"
    2020-11-14 20:46:50.918644: [debug] msg: "Stream 31 @ index: 0 received data: ", data: array (
      1 => '19ed0000000f00030c000000000000000000000000',
    )
    
  • examples/example_parallel_requests_reactphp.php - uses ReactPHP for networking and this library for packets

2. Try another modbus client

Make same request with different client - if other clients work then it is not probably this client issue

Modpoll Modbus Simulator is command line modbus client that has both Windows and Linux executables. To send same request as examples/fc3.php use following command

./modpoll -m tcp -a 1 -r 256 -c 6 -t 4 -1 -o 10 xxx.xxx.xxx.xxx
  • -m tcp - use modbus tcp protocol
  • -a 1 - use unit/slave id 1
  • -r 256 - request data from address 256
  • -c 6 - quantity of holding registers to read
  • -t 4 - use read holding register function
  • -1 - request only once
  • -o 10 - set timeout to 10 seconds

Example for case then modbus server does not respond

modpoll 3.6 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright (c) 2002-2018 proconX Pty Ltd
Visit https://www.modbusdriver.com for Modbus libraries and tools.

Protocol configuration: MODBUS/TCP
Slave configuration...: address = 1, start reference = 256, count = 6
Communication.........: xxx.xxx.xxx.xxx, port 502, t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, output (holding) register table

Can't reach server/slave! Check TCP/IP and firewall settings.

3. Try another modbus server

Make request to another modbus server. It could be that your modbus server is behaving wrong or you have network problems. Diagslave Modbus Simulator works for Win/Linux.

Try these 2 variants:

  • start modbus server simulator on same machine/server by ./diagslave -m tcp -p 5020 suitable to be used with examples/fc3.php - this will tell you if clients or and you can atleast make request on same host machine.
  • start simulator on another machine/server - this will tell you if you can make requests out of this host over network.

Capture network traffic to see what is actually send/received

For Windows/Linux GUI users there is WireShark

Example of captured traffic for modbus timeout: problem with timeout

For Linux command line I recommend TCPDUMP

  • sudo yum install tcpdump
  • sudo apt install tcpdump

See https://danielmiessler.com/study/tcpdump/ for examples and guide

Example listen enp7s0 ethernet interface for traffic to/from 192.168.1.100:

sudo tcpdump -i enp7s0 -X host 192.168.1.100 and port 502

or sniff request send to localhost:5020 (diagslave server started by ./diagslave -m tcp -p 5020)

sudo tcpdump -i lo -X port 5020

Output:

22:46:50.900954 IP localhost.37040 > localhost.5020: Flags [S], seq 3293864098, win 65495, options [mss 65495,sackOK,TS val 1562996074 ecr 0,nop,wscale 9], length 0
        0x0000:  4500 003c e2e2 4000 4006 59d7 7f00 0001  E..<..@.@.Y.....
        0x0010:  7f00 0001 90b0 139c c454 60a2 0000 0000  .........T`.....
        0x0020:  a002 ffd7 fe30 0000 0204 ffd7 0402 080a  .....0..........
        0x0030:  5d29 6d6a 0000 0000 0103 0309            ])mj........
22:46:50.900966 IP localhost.5020 > localhost.37040: Flags [S.], seq 241872849, ack 3293864099, win 65483, options [mss 65495,sackOK,TS val 1562996074 ecr 1562996074,nop,wscale 9], length 0
        0x0000:  4500 003c 0000 4000 4006 3cba 7f00 0001  E..<..@.@.<.....
        0x0010:  7f00 0001 139c 90b0 0e6a afd1 c454 60a3  .........j...T`.
        0x0020:  a012 ffcb fe30 0000 0204 ffd7 0402 080a  .....0..........
        0x0030:  5d29 6d6a 5d29 6d6a 0103 0309            ])mj])mj....
22:46:50.900974 IP localhost.37040 > localhost.5020: Flags [.], ack 1, win 128, options [nop,nop,TS val 1562996074 ecr 1562996074], length 0
        0x0000:  4500 0034 e2e3 4000 4006 59de 7f00 0001  E..4..@.@.Y.....
        0x0010:  7f00 0001 90b0 139c c454 60a3 0e6a afd2  .........T`..j..
        0x0020:  8010 0080 fe28 0000 0101 080a 5d29 6d6a  .....(......])mj
        0x0030:  5d29 6d6a                                ])mj
22:46:50.918540 IP localhost.37040 > localhost.5020: Flags [P.], seq 1:13, ack 1, win 128, options [nop,nop,TS val 1562996092 ecr 1562996074], length 12
        0x0000:  4500 0040 e2e4 4000 4006 59d1 7f00 0001  E..@..@.@.Y.....
        0x0010:  7f00 0001 90b0 139c c454 60a3 0e6a afd2  .........T`..j..
        0x0020:  8018 0080 fe34 0000 0101 080a 5d29 6d7c  .....4......])m|
        0x0030:  5d29 6d6a 19ed 0000 0006 0003 0100 0006  ])mj............
22:46:50.918551 IP localhost.5020 > localhost.37040: Flags [.], ack 13, win 128, options [nop,nop,TS val 1562996092 ecr 1562996092], length 0
        0x0000:  4500 0034 ac95 4000 4006 902c 7f00 0001  E..4..@.@..,....
        0x0010:  7f00 0001 139c 90b0 0e6a afd2 c454 60af  .........j...T`.
        0x0020:  8010 0080 fe28 0000 0101 080a 5d29 6d7c  .....(......])m|
        0x0030:  5d29 6d7c                                ])m|
22:46:50.918591 IP localhost.5020 > localhost.37040: Flags [P.], seq 1:22, ack 13, win 128, options [nop,nop,TS val 1562996092 ecr 1562996092], length 21
        0x0000:  4500 0049 ac96 4000 4006 9016 7f00 0001  E..I..@.@.......
        0x0010:  7f00 0001 139c 90b0 0e6a afd2 c454 60af  .........j...T`.
        0x0020:  8018 0080 fe3d 0000 0101 080a 5d29 6d7c  .....=......])m|
        0x0030:  5d29 6d7c 19ed 0000 000f 0003 0c00 0000  ])m|............
        0x0040:  0000 0000 0000 0000 00                   .........
22:46:50.918595 IP localhost.37040 > localhost.5020: Flags [.], ack 22, win 128, options [nop,nop,TS val 1562996092 ecr 1562996092], length 0
        0x0000:  4500 0034 e2e5 4000 4006 59dc 7f00 0001  E..4..@.@.Y.....
        0x0010:  7f00 0001 90b0 139c c454 60af 0e6a afe7  .........T`..j..
        0x0020:  8010 0080 fe28 0000 0101 080a 5d29 6d7c  .....(......])m|
        0x0030:  5d29 6d7c                                ])m|
22:46:50.920927 IP localhost.37040 > localhost.5020: Flags [F.], seq 13, ack 22, win 128, options [nop,nop,TS val 1562996094 ecr 1562996092], length 0
        0x0000:  4500 0034 e2e6 4000 4006 59db 7f00 0001  E..4..@.@.Y.....
        0x0010:  7f00 0001 90b0 139c c454 60af 0e6a afe7  .........T`..j..
        0x0020:  8011 0080 fe28 0000 0101 080a 5d29 6d7e  .....(......])m~
        0x0030:  5d29 6d7c                                ])m|
22:46:50.920986 IP localhost.5020 > localhost.37040: Flags [F.], seq 22, ack 14, win 128, options [nop,nop,TS val 1562996094 ecr 1562996094], length 0
        0x0000:  4500 0034 ac97 4000 4006 902a 7f00 0001  E..4..@.@..*....
        0x0010:  7f00 0001 139c 90b0 0e6a afe7 c454 60b0  .........j...T`.
        0x0020:  8011 0080 fe28 0000 0101 080a 5d29 6d7e  .....(......])m~
        0x0030:  5d29 6d7e                                ])m~
22:46:50.920998 IP localhost.37040 > localhost.5020: Flags [.], ack 23, win 128, options [nop,nop,TS val 1562996094 ecr 1562996094], length 0
        0x0000:  4500 0034 e2e7 4000 4006 59da 7f00 0001  E..4..@.@.Y.....
        0x0010:  7f00 0001 90b0 139c c454 60b0 0e6a afe8  .........T`..j..
        0x0020:  8010 0080 fe28 0000 0101 080a 5d29 6d7e  .....(......])m~
        0x0030:  5d29 6d7e                                ])m~
^C
10 packets captured
20 packets received by filter
0 packets dropped by kernel

Actual FC3 request bytes are 19ed 0000 0006 0003 0100 0006 Full packet:

22:46:50.918540 IP localhost.37040 > localhost.5020: Flags [P.], seq 1:13, ack 1, win 128, options [nop,nop,TS val 1562996092 ecr 1562996074], length 12
        0x0000:  4500 0040 e2e4 4000 4006 59d1 7f00 0001  E..@..@.@.Y.....
        0x0010:  7f00 0001 90b0 139c c454 60a3 0e6a afd2  .........T`..j..
        0x0020:  8018 0080 fe34 0000 0101 080a 5d29 6d7c  .....4......])m|
        0x0030:  5d29 6d6a 19ed 0000 0006 0003 0100 0006  ])mj............

See this for Read holding register packet structure. Each Request and Response class contains packet structure explanation.

So bytes 19ed 0000 0006 0003 0100 0006 is translated to Modbus packet as:

  • 19 ed - transaction id (2 bytes)
  • 00 00 - protocol id (2 bytes)
  • 00 06 - number of bytes in the message (PDU = ProtocolDataUnit) to follow (2 bytes)
  • 00 unit id (1 byte)
  • 03 function code (1 byte)
  • 01 00 - start address (2 bytes)
  • 00 06 - holding registers quantity to return (2 bytes)

I would recommend copying complete flow - from creating tcp connection to connection close and paste it into issue. This would help diagnose problems. In case of timeouts seeing when connection is closed and who closes connections is important.