Since Modbus is designed to work with industrial automation, data exchange with Modbus devices occurs through registers. They are divided into inputs and outputs. It can only read information, and results are read and write. There are 1-bit Modbus registers for describing discrete inputs/outputs (Discrete Inputs and Coils) and 16-bit registers for analog inputs/outputs (Input Registers and Holding Registers). Records are accessed using a 16-bit address.
The first element in each group of registers corresponds to address 0. The address of any register can take values from the range 0-65535 (0x0000-0xFFFF in HEX format). At the same time, the protocol specification does not define what physical address spaces are and at which internal device addresses the registers should be available.
In general, the values of registers with the same address but different types differ from each other. Note In the documentation of several manufacturers for some, especially older devices, register addresses can be specified in other formats – where addressing does not start from zero, and the first digit of the address determines the type of register. For example, Input Register with address 0 can be described as 30001, and Holding Register as 40001. In such cases, data packets should transmit addresses in the standard Modbus format, regardless of how they are represented in the documentation.
To obtain the correct address – It is enough to subtract the offset corresponding to the register type. Some software packages include automatic address correction. The Modbus protocol specification defines a PDU structure for each function: what data and in what order should be used in requests and responses. Let’s consider the formation of Modbus RTU packets using the Read Coils function with code one as an example. In addition to transmitting its code, this function requires the first Coil-register’s address in the request and several registers to be read. If the bid is successful, the response will return the function code, the number of bytes required to output the requested Coil registers, and the status of all these registers.
Suppose we need to access the server device with address one and read 19 of its Coil registers numbered 20–38. Registers are addressed from 0, so the address of the first register we need will be 0x13 (this is 19 in the HEX system). The number of records required for reading will also equal 0x13 (19 requested for reading). Specify 01 as the address and function code.
The checksum is generated according to the CRC-16 algorithm based on other fields of the packet. If there are no errors in the response, the server device address and function code will be returned unchanged. To calculate the number of bytes required to return the state of the registers, you need to divide the requested number of records by eight and add 1 to the result if the remainder of the division is not 0. In our case, dividing 19 by 8 is 2, but the rest is positive – therefore, output registers will require 2 + 1 = 3 bytes. Will indicate this value in the response after the function code. And then, 3 bytes will follow, describing the state of the selected registers.
For example, the first byte will represent the state of 8 Coil registers numbered 27-20. If the field contains, for example, the HEX value CD – the status of the corresponding eight registers is as follows: 1100 1101. Suppose an error occurs during the processing of a request on the server device (for example, a non-existent register address is found). In that case, the response will contain the changed function code equal to the original code plus offset 0x80 – in our example 0x81, and the exception code – in our example 03, which means the request format is incorrect. For a complete list of possible exceptions, see the documentation.
Also Read: Advantages And Disadvantages Of Modbus