Modbus Addressing
This page describes how the Address, Data Type and Length fields of tags on Modbus Serial, Modbus Serial over Ethernet and Modbus TCP devices are interpreted. All three Modbus connection types use the same address rules. For channel and device settings, see the Modbus Serial (RTU/ASCII), Modbus Serial over Ethernet and Modbus TCP pages.
Address format
A Modbus tag address consists of a digit that specifies the area type, followed by the register (or bit) number. The common notation has 6 digits (400001); the 5-digit notation (40001) points to the same register. To access a bit inside a register, append a dot and the bit number to the address.
400001 Holding register 1
300010 Input register 10
000005 Coil 5
100003 Discrete input 3
400020.7 Holding register 20, bit 7The address field follows these rules:
- The first digit must be
0,1,3or4. - After the first digit only digits follow, and this number must be in the range 0–65535 (e.g.
400001,40001,465535). No sign, space or extra part is used. - The bit suffix is a number from 0 to 15 after the dot and is used only on Bool register tags (see Bit addressing).
If the address does not match these rules or the tag's data type, the tag table shows a warning such as "Address does not match the ModbusTcp address pattern."; the message contains the device's connection type. The same rule is applied on the server; a tag that breaks the rule is not saved and the error message shows the reason. This check is not made for tags marked as Advanced Tag or for the device system addresses _ConnError and _TagQualityBad (see Tag Management).
Area types
| First digit | Modbus area | Access | Read function | Write function | Allowed data types |
|---|---|---|---|---|---|
0 | Coil (output bit) | Read/Write | FC01 Read Coils | FC05 Write Single Coil | Bool only |
1 | Discrete input (input bit) | Read only | FC02 Read Discrete Inputs | — | Bool only |
3 | Input register | Read only | FC04 Read Input Registers | — | Bool (with a bit suffix) and numeric types |
4 | Holding register | Read/Write | FC03 Read Holding Registers | FC06 / FC16 (see below) | Bool (with a bit suffix) and numeric types |
The function used for holding register writes is chosen according to the number of registers the value occupies:
- Single-register values (Byte, Sbyte, Int, Word): FC06 Write Single Register
- Multi-register values (DInt, DWord, Real, LInt, ULInt, LWord, LReal): FC16 Write Multiple Registers
- A bit inside a register (Bool): the current value of the register is first read with FC03, only the target bit is changed, and the value is written back with FC06.
Addresses that start with 1 and 3 are read-only on the device. Mark these tags as Read Only; even if they are not marked, the service does not send write requests to these addresses and writes the error to the service log.
Zero Based setting
The Zero Based option on the device's Settings tab determines which register in the protocol the number in the address corresponds to.
| Zero Based | Address | Protocol address sent to the device |
|---|---|---|
| Selected (default) | 400001 | 0 |
| Selected (default) | 400100 | 99 |
| Not selected | 400000 | 0 |
| Not selected | 400100 | 100 |
If the device documentation numbers the registers starting from 1 (e.g. "40001"), keep Zero Based selected. If the documentation gives the protocol address starting from 0 (e.g. "address 0x0000"), clear the option. If the values read belong to the register just before or after the expected one, check this setting first.
While Zero Based is selected, the address 400000 also corresponds to register 0; to avoid confusion, start addresses from 1 in this case. The number in the address can be at most 65535. For values that occupy more than one register, the last register must also stay within the device's address range.
Bit addressing
- Coil and discrete input (
0,1): Each address is a single bit. The data type can only be Bool and no bit suffix is written in the address. - Bit inside a register (
3,4): The bit suffix is required on register tags whose data type is Bool. The bit number is between 0 and 15; 0 is the least significant bit. For example,400020.0is the lowest bit of holding register 20. - Non-Bool types: No bit suffix is used on
3and4addresses.
These rules are checked in the tag table and on the server when saving; for example, a bit suffix such as .16, a bit suffix on a coil address, a non-Bool coil tag or an Int tag with a bit suffix is not saved.
Writing to a holding register bit is done with the read-modify-write method. 2WinScada queues its own writes over the same connection; however, it does not protect against the PLC program or another system changing the same register between the two operations.
Data types
| Data Type | Registers occupied | Description |
|---|---|---|
| Bool | 1 bit on a coil/discrete input; 1 bit in a register | A bit suffix is required inside a register |
| Byte | 1 | Low byte of the register (bits 0–7), unsigned |
| Sbyte | 1 | Low byte of the register (bits 0–7), signed |
| Word | 1 | 16-bit unsigned integer |
| Int | 1 | 16-bit signed integer |
| DWord | 2 | 32-bit unsigned integer |
| DInt | 2 | 32-bit signed integer |
| Real | 2 | 32-bit IEEE 754 floating-point number |
| LWord | 4 | 64-bit unsigned integer |
| ULInt | 4 | 64-bit unsigned integer |
| LInt | 4 | 64-bit signed integer |
| LReal | 4 | 64-bit IEEE 754 floating-point number |
When Byte and Sbyte tags are written, the high byte of the register is written as zero. There is no option to read the high byte of a register separately; if you need it, read the register as Word and separate the value with an expression or an advanced tag.
The Automatic option in the Data Type list is not supported on Modbus devices.
Length and String
- Length must always be 1. Arrays (several consecutive values with a single tag) are not supported on Modbus devices; define a separate tag for each value.
- The String data type is not supported on Modbus devices and cannot be selected in the list.
Tags with a length greater than 1 or of type String are rejected in the tag table and on the server.
Tags from earlier versions
Tags saved in an earlier version that do not follow these rules (address, bit suffix, String, Length) are not deleted. They are not read at runtime, stay at Bad quality, and the reason is written to the service log once; writes to these tags are also rejected. To fix them, make the tag's address, data type or length follow the rule and save; saving with only a changed description is rejected.
Word order (32-bit and 64-bit values)
The byte order inside each register is fixed by the Modbus standard (high byte first); there is no setting to change it. For values that occupy more than one register, the order of the registers is set by two options on the device's Settings tab.
In the tables below, R0 is the first register at the tag address and W0 is the least significant word of the value.
32-bit values (DWord, DInt, Real):
| First Word Low 32 Bit | R0 | R1 | Common name |
|---|---|---|---|
| Selected (default) | W0 (low) | W1 (high) | Word swap / CDAB |
| Not selected | W1 (high) | W0 (low) | Big-endian / ABCD |
64-bit values (LInt, ULInt, LWord, LReal):
| First Word Low 32 Bit | First DWord Low 64 Bit | R0 | R1 | R2 | R3 |
|---|---|---|---|---|---|
| Selected | Selected | W0 | W1 | W2 | W3 |
| Selected | Not selected | W2 | W3 | W0 | W1 |
| Not selected | Selected | W1 | W0 | W3 | W2 |
| Not selected | Not selected | W3 | W2 | W1 | W0 |
If the device documentation says "high word first" or "big-endian", clear First Word Low 32 Bit; for 64-bit values, also clear First DWord Low 64 Bit.
First DWord Low 64 Bit selection
If you use 64-bit tags, deliberately select or clear the First DWord Low 64 Bit check box according to the device documentation and then save.
These settings apply to all tags on the same device. If the same device has values with a different word order, read one of them as two Word tags and combine them with an expression.
Read groups and Block Size
When reading tags, 2WinScada combines nearby addresses into a single request to reduce the number of requests:
- First, tags with the same Update Interval[s] value are grouped together; each group is read at its own interval.
- In each group, tags of the same area type (coil, discrete input, input register, holding register) are sorted by address.
- A tag is added to the same request if it is at most 30 addresses away from the end of the previous tag and the total length does not exceed the device's Block Size value; otherwise a new request is started.
Block Size limits the number of registers in register areas and the number of bits in coil and discrete input areas (default 32). The Modbus standard allows reading at most 125 registers and 2000 bits in one request; many devices apply a lower limit. If the device returns an "Illegal Data Address" or "Illegal Data Value" error, or rejects a block that contains undefined addresses, lower the Block Size value.
If a read request fails, the quality of the tags in that request becomes Bad; the other requests continue to be read.
Examples
| Address | Data Type | Length | Read Only | Meaning |
|---|---|---|---|---|
000001 | Bool | 1 | No | Coil 1 (e.g. motor start command) |
100004 | Bool | 1 | Yes | Discrete input 4 (e.g. door contact) |
300001 | Word | 1 | Yes | Input register 1, 16-bit unsigned |
300011 | Real | 1 | Yes | Input registers 11–12, floating-point measurement |
400001 | Int | 1 | No | Holding register 1, 16-bit signed setpoint |
400101 | DInt | 1 | No | Holding registers 101–102, 32-bit counter |
400201 | LReal | 1 | Yes | Holding registers 201–204, 64-bit energy value |
400050.3 | Bool | 1 | No | Bit 3 of holding register 50 |
For scaling, units and the other common tag fields, see the Tag Management page. Reusable Modbus register lists can be defined with Device Profiles.
Troubleshooting
| Symptom | Checks |
|---|---|
| The address is not saved, "does not match the address pattern" warning | Check that the address starts with 0, 1, 3 or 4, that the number is between 0 and 65535, and that the bit suffix follows the bit addressing rules (only on Bool register tags, 0–15). |
| Tag is Bad after an upgrade | The tag does not follow the 2.10 rules (String, Length > 1 or an invalid address). Fix the tag according to the reason in the service log and save. |
| The value appears shifted by one register | Set the Zero Based option according to the numbering in the device documentation. |
| A 32/64-bit value is meaningless or very large | Check the First Word Low 32 Bit and First DWord Low 64 Bit options, the Data Type value and that the Length value is 1. |
| All tags in a group become Bad | One of the addresses in the block may not be defined on the device. Lower the Block Size value or read the undefined addresses separately with a different Update Interval[s]. |
| Writing does not work | Check that the address starts with 0 or 4, the Read Only setting, the user's permission and that the device allows writing. |
| The String type cannot be selected | Modbus String tags are not supported in 2.10; see Length and String. |