2
votes

We are writing a Windows Service to read the data from PLC using Modbus TCP protocol at the polling interval of 1 sec through Socket programming in c#. Windows Service will receive random registers of the PLC to read the register values. Expected registers randomly such as 40150,40250,40270,40320.

From the above case how to create the Modbus TCP request header? We could found two possible ways:

  1. Using the function code 3, we can read the values of the registers on a specific range, for example from 40150 to 40320, in this way we can read these 40150,40250,40270,40320 register values.
  2. Another way is requesting these 40150,40250,40270,40320 registers one by one(this will cause performance problem).

Am I missing any point here? Is there any better way for reading registers randomly one or more?

2
Your first way is the best way.mrsargent
#mrsargent Is that the way existing applications are reading the data?Vignesh Raagav
Why would you want to read random registers in the first place? if you know the range of the registers you are looking for, you can use option 1 (function code 3) with the quantity of registers you want to read . The problem with random is you will have to make sure you are not reading anything that does not exist. refer read holding register function from modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdfSanju
If you are concerned about performance and if you have multiple Slaves, being the Master, you will want to maintain a separate TCP session for each and every Modbus/TCP Slave device. This way you can poll every device at the 1 second rate without the overhead of re-establishing a TCP connection on every poll.franji1
@franji1 Thank uVignesh Raagav

2 Answers

0
votes

Typical OPC server software such as DASMBTCP from Wonderware would approach this task by attempting to find the most performant combination of requests to retrieve the required data. You could set something like this up and use wireshark to sniff the modbus packets to see the decisions other software are making.

Function code 3 from memory can only give 125 registers at a time so you could request 40150,40250,40270 together but would need a separate request for 40320.

If you are concerned that a range might not be supported by a device (I have come across a device which supports function code 3 but only up to 60 registers) then you would have to make your program adaptive. For example, make the function code 3 and if it fails, mark those registers as requiring individual requests.

In answer to your question you are not missing the point, there isn't any better way to read multiple registers, and your approach is only limited by whether the device you are reading from supports that function code.

0
votes

There are many parts that influence the final speed data reading, for example how many requests per cycle your PLC can answer, I think the only solution to know which way is more effective is to try both.

I recommend that you also evaluate the use of a Modbus OPC UA server or other OPC server compatible with your PLC, with OPC UA it's possible to read non-consecutive memory positions in a single request, although if you have to implement it in your C # code it will probably be more complicated than raw Modbus