Based on
this document, I would read three Holding Registers (see Background below) starting at Siemens-convention address 1837 using a minimal program, with just the MB_MASTER instruction, in the S7-1214C as a Modbus Master/Client and the PM5110 meter as the Modbus Slave. I do not know if 1836 in the S7 will retrieve the 1836th Holding Register in the PM5110 memory model, or if it will retrieve the 1837th Holding Register in the PM5110 memory model that is offset by 1836 Holding Registers from the first Holding Register. However, I do know that,
- If the second register retrieved has a value of 2000 or greater, then I would know that both the Siemens and the PM5110 document use the same one- or zero-based addressing, and I can go on my merry way treating the register addresses from the PM5110 document as 1:1 in sync with the addressing scheme used in the S7-1214C
- If the first register retrieved has a value of 2000 or greater, and the third register retrieved has a value of 31 or less, then I would know that the PM5110 document addresses are one-based, and the S7:1214C addressing scheme is zero-based, and I have to subtract 1 to any address from the PM5110 document to get the correct corresponding address to use in the S7-1214C.
- If neither of those two cases holds, then the third register retrieved will have a value of 2000 or greater, and I would know that the PM5110 document addresses are zero-based, and the S7-1214C addressing scheme is one-based, and I have to add 1 to any address from the PM5110 document to get the correct corresponding address to use in the S7-1214C.
Background
There are two types of devices in Modbus communications:
- One or more Slave/Server devices
- The Data Tables (see below) reside on the Slave/Server device
- One* Master/Client device
* There will usually be only one Master/Client device in Modbus RTU (serial comms); there may be multiple Master/Client devices for Modbus TCP.
There are four** pieces to every Modbus data transfer:
- Transfer direction, expressed from the point of view of the Modbus master/client
- Read - data are transferred from slave/server device to master/client
- Write - data are transferred from master/client to slave/server device
- The slave/server device Data Table from or to which data are transferred
- 1-bit Discrete Inputs
- 1-bit Coils (Discrete Outputs)
- 16-bit Input Registers
- 16-bit Holding Registers
- The address of the first element in the Data Table to be transferred
- The Length - how many data to transfer
** a fifth piece is the Modbus station ID, which I will ignore for now
There are typically two ways to specify any particular combination of those three items:
- Function Code, Address, and Length
- Function Code encodes both [Transfer Direction] and [Data Table], and sometimes length
- e.g. Function Code 0x03 Reads multiple 16-bit Holding Registers
- e.g. Function Code 0x05 Writes a Single Coil; length is implicit as 1
- Address specifies which of 65536 possible data is the first to be transferred
- It is usually specified as a decimal number, but it may be specified in hexadecimal
- It may be specified as a zero-based offset from the start of the data, so the range is 0-65535
- It may be specified as a one-based ordinal of the first datum to be transferred, so 1-65535(-65536?)
- Length is the cardinal number of data (Coils, Registers, etc.) to be transferred, starting at the specified Address
- Length may be implicit in the Function Code
- Transfer Direction, [Data Table + Address], Length
- Transfer direction is as described above i.e. Read or Write
- Write is not applicable to all Data Types
- E.g. there is typically no way to Write to Discrete Inputs
- Data Table + Address encodes both Data Table and Address into a single entity
- Data Table is implied the a prefix digit of the entity
- N.B. this is a de facto convention and is not part of the formal Modbus specification
- Specifically, interpreting these prefixes, if used, as a numerical part of the address will only end in tragedy
- '0' for writable coils,
- '1' for read-only discrete inputs,
- '3' for read-only input registers,
- '4' for writable holding registers
- The Address is the rest of the entity after the prefix, and is a 4- or 5-digit number that specifies which of the 65536 possible data is the first to be transferred
- It is usually specified as a decimal number, but sometimes in hexadecimal
- It may be specified as a zero-based offset from the start of the data, so the range is 0-65535
- It may be specified as a one-based ordinal of the first datum to be transferred, so 1-65535(-65536?)
- E.g. the first datum in the Holding Register Data table may be '4'00001 or '4'00000
- Length is the cardinal number of data (Coils, Registers, etc.) to be transferred, starting at the specified Address
Those are the two most common ways to define a Modbus transfer. The memory model of, i.e. the layout of the Data tables in, a slave/server device is arbitrary and up to the vendor/maker of the device; e.g. two or mor Data Tables could map to the same physical memory, and it does not matter which Data Table is used for a transfer.
The most common confusion in Modbus transfers is how either device interprets the Address: one-based vs. zero-based. Another common error is interpreting the Data Table prefix of the encoded [Data Table + Address] entity as a numerical part of the address.