ModSlaveSim help v3.06 - C. Mapping coils/discrete inputs overlaid with holding/input registers
Download manual: HTML
Some registers share the same physical address in a device, and in this case the address is said to be overlaid. Although one may overlay holding and input registers, no special configuration is needed. However, when a coil or discrete input is overlaid with a holding or input register, the mapping becomes more complex and it does require special configuration. This is because the individual bits of a holding or input register have to be addressed (as coils or discrete inputs), and that depends on the ordering of the bytes in a 16-bit register. This would not in itself be a problem if the Modbus specification had indicated how they should be ordered, but since it did not, devices differ in how message addresses map to model addresses where individual bits are used i.e. for coils and discrete inputs, so some device-specific configuration is needed. For this section, you may need to refer to the sections Map Addresses and Add Register.
To map your own addresses, check your slave device manual for the Modbus type (holding registers, input registers, coils, discrete inputs), for the base address used and for the number of addresses. Then you can define for a slave the range and mapping to message addresses as described below.
Number of Addresses. This is the same as any other form of address mapping. (see Map Addresses).
Base Address. When registers are not overlaid, the base address is the model address that corresponds to message address 0. However, when coils are overlaid with holding registers (or discrete inputs with input registers) the mapping is more complicated because, as mentioned above, message addresses refer to individual bits, whereas model addresses refer to registers of 16 or more bits. So in this case the base address for a coil or discrete input is the model address of the holding or input register that corresponds to message address zero for a coil or discrete input. To map to a model address, therefore, ModSlaveSim uses the size of the registers in the address space to determine the number of bits in a register, and then uses:
model_address = base_address + message_address / bits_in_register
to find the address of a holding or input register. Note that all the registers in the discrete input or coil address space must be the same size (otherwise the mapping would be a little obscure!). The remainder after dividing by bits_in_register is used to determine which bit in the register the address refers to:
bit_number = message_address modulo bits_in_register
The bits are numbered "from right to left" (i.e. bit 0 is the least significant bit). Table 1 shows a simple example of the address mapping for coils overlaid with holding registers.
Table C.1. Address mapping overlaid coil and holding register
Slave Id Hold: Base Hold: No Input: Base Input: No Disc: Base Disc: No Coil: Base Coil: No 1: Slave with overlaid Coils 0 65536 0 0 0 0 100 96
With this mapping, registers 100..105 would be accessible as holding registers 100..105 and also as coils 0..95. This assumes the use of 16-bit registers - 6 * 16 = 96 bits, 32-bit registers would map to registers 100..102 - 3 * 32 bits = 96. Note that 100..105 are both message and model addresses since the base starts at zero, but 0..95 is a message address only. Using the rules above coil 37 would map to bit 5 (37 (coil message address) modulo 16 (bits in register) of holding register 102 (100 (base address) + (37 (coil message address) / 16 (bits in register))). Coil 37 is indicated by the letter 'B' in the following when the value of holding register 102 is viewed in binary notation. Note that bits within a byte are numbered from zero and from right to left.
Register Address 102: 00000000 00B00000
This example assumes a particular ordering of the bytes, which is a configuration requirement that is the subject of the next section.
C/D Swap. This configures the byte order.
In the example in the previous section, there is an implicit ordering for each pair of bytes within a 16-bit word in which the rightmost, least significant byte, (LSB) is sent first. This means that bits 0-7 in the right byte correspond to coils 32-39 and bits 8-15 in the left most significant byte (MSB) corresponds to coils 40-47. In this case, C/D Swap on the Map Addresses panel is checked, which is the default setting.
If the default ordering is not the way the slave sends the bytes - in other words if it sends the leftmost byte before the right byte, then the C/D:Swap checkbox should be unchecked. With this ordering, bits 8-15 in the leftmost byte now correspond to coils 32-39 and bits 0-7 in the right byte (LSB) correspond to coils 40-47. In the example in the previous section, coil 37 would be in the position indicated by 'B' below when the value of holding register 102 is viewed in binary notation:
Register Address 102: 00B00000 00000000
As well as determining how the values are displayed, the byte order is also important to ensure that you get the correct value when using commands for both holding/input registers, as well as coil/discrete inputs.
You may need to further configure the word-ordering if you use registers larger than 16-bits, by checking or unchecking Little Endian on the Set 32/64-bit Values panel (see Set 32/64-bit Values).
If the byte ordering or word-ordering is not apparent from the slave device documentation, you may need to just try out different combinations of C/D:Swap and Little Endian.