Help with pyModbusTCP

Hello all, modbus amateur here. This question has a duplicate in https://stackoverflow.com/questions/72959652/unkown-cause-of-pymodbustcp-timeout

I have an equipment connected via ethernet cable to the network and i am trying to check if i can get some information from it. Its manual says it accepts modbusTCP via its ethernet interface and modbus RTU via its serial interface. I know its I.P. and scanning it with nmap reveals that port 502 is open with mbap service. Therefore, following the equipment's registers map (i attach an image of the desired register) i tried implementing the python code:


from pyModbusTCP.client import ModbusClient
client = ModbusClient(host="device_IP", port = 502, auto_open=True,debug=True)
client.open()
client.read_holding_registers(4096,32)

To which i only get

Tx
[F4 2E 00 00 00 06 01] 03 10 00 00 02
timeout error

Am i doing something wrong? Since im only doing this to test if communication with device is ok, would anyone suggest other debug tool? Thanks in advance for any help.
 

Attachments

Can you provide a link to the manual for the Modbus device you're using?

The only thing that comes to mind that could cause a timeout in Modbus/TCP is an incorrect Unit Identifier. From your TX packet, it seems pyModbus uses 1 by default. Perhaps your Modbus device requires a different Unit Identifier. Typical Unit Identifier values used by Modbus/TCP server devices are 0, 1, and 255.

I believe you specify the Unit Identifier like this in pyModbus:
client.read_holding_registers(4096, 32, unit=UNIT_IDENTIFIER)
where UNIT_IDENTIFIER is the specific value you would like to use.

Another potential cause of the issue you're seeing is that you may be requesting too many registers (some of which may not exist on the device) and instead of properly returning an exception code, your Modbus device simply doesn't respond. Try requesting only 2 registers instead of 32, like this:
client.read_holding_registers(4096, 2)
 
Thanks for the help!
Sorry for deleting last comment, @jschulze. The device in question is https://www.saesgetters.com/sites/default/files/NEG POWER MINI_NEG POWER MULTICONTROLLER.pdf. I do not have any links to its manual since i only have the files given by the manufacturer (and i think they have strict copyrights, im not sure if it would be problematic to share).

About the unit, indeed pyModBusTCP has a unit specifier in the client initialization. I adapted my code to


#!/usr/bin/python3
import sys
from pyModbusTCP.client import ModbusClient
for i in range(0,255):
print(i)
client = ModbusClient(host="device_IP", port = 502, auto_open=True,debug=True, unit_id=i,timeout=2)
client.open()
client.read_holding_registers(4096,1)

but still got timeout for every i value. I also changed the registers values from 32 to 1 and to 2 but to no different results. I was trying 32 because pymodbusTCP documentation says its the number of bits to be read, not registers, but i tried it anyway...
 
It would be very poor form for a manufacturer to not freely provide their Modbus documentation (let alone a user's manual), as this is required by anyone who wishes to communicate with the product. At any rate, a quick Google search does turn up a manual, though the information in there is also very limited.

According to that manual, there are apparently Modbus Server Settings where you need to select between RS232, RS485, or TCP/IP. Does your device have TCP/IP selected?
1657747124831.png

Regarding the pyModbusTCP library, are you not using this library?
https://pymodbustcp.readthedocs.io/en/latest/package/class_ModbusClient.html

According to the documentation there, the read_holding_registers function takes a number of registers, not bits.

Also, at the risk of stating the obvious, I assume you've already confirmed that your computer and the Modbus device are both configured for compatible IP addresses on the same logical subnet and that you're not actually using "device_IP" in your script, but an actual IP address?
 
...
Also, at the risk of stating the obvious, I assume you've already confirmed that your computer and the Modbus device are both configured for compatible IP addresses on the same logical subnet and that you're not actually using "device_IP" in your script, but an actual IP address?
That is exactly what confuses me.

If device_IP is a variable, it should be probably:
Code:
client = ModbusClient(host=device_IP, port = 502, auto_open=True,debug=True)
Or you may enter the IP address of the server directly, e.g.:
Code:
client = ModbusClient(host="192.168.0.1", port = 502, auto_open=True,debug=True)
If this does not help, consider the unit_id parameter as mentioned before.
 
It would be very poor form for a manufacturer to not freely provide their Modbus documentation (let alone a user's manual), as this is required by anyone who wishes to communicate with the product. At any rate, a quick Google search does turn up a manual, though the information in there is also very limited.

According to that manual, there are apparently Modbus Server Settings where you need to select between RS232, RS485, or TCP/IP. Does your device have TCP/IP selected?
View attachment 2234

Regarding the pyModbusTCP library, are you not using this library?
https://pymodbustcp.readthedocs.io/en/latest/package/class_ModbusClient.html

According to the documentation there, the read_holding_registers function takes a number of registers, not bits.

Also, at the risk of stating the obvious, I assume you've already confirmed that your computer and the Modbus device are both configured for compatible IP addresses on the same logical subnet and that you're not actually using "device_IP" in your script, but an actual IP address?
Yes, the modbus settings is set to tcp and nmap shows a status change on port 502 of the device when i disable the tcp option, so i figure it is configured. About the library, it seems i misread it, sorry.
About the subnet i got news: i am using the actual device I.P. address. I tried connecting to the device directly via cable and setting my computer I.P. manually to something in the same subnet. It worked and i got a response instead of a timeout. When i get back to my desk and connect my computer to the net via wi-fi and cable the device to a physical port, then i get timeouts. I did nmap in the subnet gateway and it accused that the gateway 502 port is closed. Is that the problem? Should i ask the network manager to open this port?
 
That is exactly what confuses me.

If device_IP is a variable, it should be probably:
Code:
client = ModbusClient(host=device_IP, port = 502, auto_open=True,debug=True)
Or you may enter the IP address of the server directly, e.g.:
Code:
client = ModbusClient(host="192.168.0.1", port = 502, auto_open=True,debug=True)
If this does not help, consider the unit_id parameter as mentioned before.
Sorry if i wasnt clear. It is not a variable, its an actual I.P. address. I just changed here to have an example code.
I think i have issues with the subnet gateway, im investigating it right now.
 
This certainly sounds like a network/IT issue. However, I'm not really sure what you mean by "subnet gateway" or what device you're referring to as the "gateway" that seems to have port 502 closed.

There should be 3 settings for both your computer's network interface card (NIC) and the Modbus device:
  • IP Address
  • Subnet Mask
  • Default Gateway

The Default Gateway is only important if there are Ethernet routers between your computer and the Modbus device, such that each device is on a different subnet (i.e. the network portion of the IP addresses are not the same, refer to this for details http://cisco.num.edu.mn/CCNA_R&S1/course/module8/8.1.2.1/8.1.2.1.html)

Assuming both your computer and the Modbus device are on the same local network, the Subnet Mask and Default Gateway settings should be identical for both devices. The IP Addresses of each device must be unique and must be part of the same logical subnet. You can calculate the available IP addresses in a subnet using this tool:
https://www.calculator.net/ip-subnet-calculator.html

Note that your computer has two NIC's - one for wired Ethernet and another for WiFi. Make sure you're looking at the proper NIC.

I know you have already tried using Nmap from your computer to scan port 502, but the more commonly used method is to try pinging the Modbus device from your computer. If you can ping the device, then this proves they are on the same logical subnet and have a physical connection to each other. If you can ping, but Modbus communications still does not work, this is likely a firewall issue and your IT administrator will need to get involved to open up ports or any other items preventing communication from working.
 
Hi guys thanks for the help. It turns out i didnt know how netmask worked properly and that was the issue. The equipment had an I.P. of 10.20.41.90 and my computer I.P. was 10.0.X.Y. Since the netmask of the equipment was 24, communication didnt happen.
Setting the equipment's I.P. to 8 solved the issue.
 
Top