Search code examples
pythondataframemodbus-tcppymodbus

Calling multiple registers simultaneously in a ModbusRTU using python?


I have a Modbus-RTU thats connected to a Modbus-RTU/TCP-Gateway, which i'm trying to call. Works fine, but I have to read multiple values each reading cycle.

I'm using the pymodbus library.

Say I have 3 Registers to read:

Address, WordLength

1: 0,2

2: 2,2

3: 206, 4

What I'm doing at the moment is calling the register values 1 and 2 together, by starting to read at adress 0, with a word count of 4. But then I have to make another request to register value 3.

Which means, when trying to timestamp the values I encounter the problem that they were actually not read at the exact same time.

The question: Is there a way to call multiple modbus registers simultaneously, say by calling read_holding_registers with a list of registers and a list of their respective word counts in python?

In a way that would work like this:

>> response = gateway.read_holding_registers(address=[0,2,206], count=[2,2,4], unit=unit).registers
>> response
<< [[0,26],[0,27],[0,0,0,3008]]

Solution

  • Short answer: No, there is no way you can poll non-contiguous registers on a single Modbus query. That's a limitation of the Modbus protocol.

    If your device (you don't mention what device in particular you are talking about, so from here on in I'll be guessing) sticks to the Modbus specification then the maximum number of registers you can interrogate on a single query is 125. That's required to comply with the maximum message length, which is 256 bytes according to the spec:

    The quantity of registers to be read, combined with all other fields in the expected response, must not exceed the allowable length of Modbus messages: 256 bytes.

    The lack of synchronization you mention is frequently overcome using one of the following two strategies:

    -At the device (slave) level (for instance, if your device is a PLC where you have the freedom to program whatever you want in it) you sample all sensors (or those you need to keep in sync) at the same time and do not update again for a certain period of time to give room to the Master to read all data (most sensors are not that fast so this is in general not a problem for most industrial settings).

    -At the master level, you can use a multithreading approach to launch two (or more) simultaneous queries (you need to somehow synchronize those queries). This only works for Modbus TCP devices that accept multiple simultaneous connections (most do). Since you seem to be working with the TCP side of your gateway, this solution might work for your time-stamping problem but be aware that, in essence, it would be just smoke and mirrors to keep the fantasy that your sensors are read in sync (not to mention it would be fancy smoke and mirrors because it would take some effort to come up with the code).

    You should recoil a bit and ask yourself what is the reason to have your readings in sync. If you are in a hard real-time environment (where, for instance, you have to take measurements of two sensors at the exact same time because you need to make a calculation using both variables and they change really fast) you need to rethink your data acquisition system to use the first approach I mentioned above (read in sync and freeze).

    I did not mention it earlier because I imagine you don't have access to the Modbus mapping of the final device, but if you do the trivial and smart thing to do is to reorganize the order of the registers according to your needs. Be sure to take a look at the manual of your unit, most high-end and/or real-time devices will actually allow you this kind of change (in an easy way I mean, changing the firmware will always fix your issue).