-----------------------------------------------------------------------------------------------------------------------

 Description of Modbus TCP protocol for TAx6xx and PAx6xx Web Sensors

 v1.0 for firmware 11-0-0-0 or higher

-----------------------------------------------------------------------------------------------------------------------

1.  History of changes

    |-----------------------|--------------------|--------------------------------------------------------------------|
    | Date                  | Version            | Description of changes                                             |
    |                       |                    |                                                                    |
    |-----------------------|--------------------|--------------------------------------------------------------------|
    | 2026-03-19            | v1.0               | Initial revision of the document                                   |
    |-----------------------|--------------------|--------------------------------------------------------------------|


2.  Modbus TCP description

    This document describes the Modbus TCP registers of PAx6xx/TAx6xx Web Sensors, enabling integration with 
    third-party software. The Modbus TCP server supports up to two simultaneous connections (sockets). The default TCP 
    port is 502, and the Modbus device address (Unit Identifier) can be set to any value. The Modbus TCP server 
    supports the modes described in the table below. A brief description of the Modbus protocol can be found in the 
    Python example located in the "code-examples" directory. The full specification of the Modbus TCP protocol can be 
    downloaded from https://www.modbus.org/modbus-specifications

    Modbus TCP modes and supported Modbus function codes:

    |-------------------------|-----------------------------------|---------------------------------------------------|
    | Mode                    | Function code                     | Description                                       |
    |                         |                                   |                                                   |
    |-------------------------|-----------------------------------|---------------------------------------------------|
    | Read-only               | 0x03 - Read Holding Registers     | Read measured values, states and identification   |
    |                         |-----------------------------------|---------------------------------------------------|
    |                         | 0x04 - Read Input Registers       | Read measured values, states and identification   |
    |-------------------------|-----------------------------------|---------------------------------------------------|
    | Enabled write for mute  | 0x03 - Read Holding Registers     | Read measured values, states and identification   |
    |                         |-----------------------------------|---------------------------------------------------|
    |                         | 0x04 - Read Input Registers       | Read measured values, states and identification   |
    |                         |-----------------------------------|---------------------------------------------------|
    |                         | 0x10 - Write Holding Registers    | Allowed write for mute acoustic                   |
    |-------------------------|-----------------------------------|---------------------------------------------------|
    | Enabled write to alarm  | 0x03 - Read Holding Registers     | Read measured values, states and identification   |
    | limits and mute         |-----------------------------------|---------------------------------------------------|
    |                         | 0x04 - Read Input Registers       | Read measured values, states and identification   |
    |                         |-----------------------------------|---------------------------------------------------|
    |                         | 0x10 - Write Holding Registers    | Allowed write to registers to change alarm limits |
    |                         |                                   | and mute acoustic                                 |
    |-------------------------|-----------------------------------|---------------------------------------------------|


3.  Tables of Modbus registers

    Depending on the communication library used, it may be necessary to use the register number instead of the register 
    address. The register number is equal to the register address plus one. For example, a register with number 0x9C41 
    corresponds to the Modbus address 0x9C40. Inside Modbus TCP frames, the register address (starting from 0) is
    physically sent.

3.1 Device identification

    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Variable                          | Adr.   | Adr.  | Nr. | Type  | Acc. | Description                           |
    |                                   | [HEX]  | [DEC] |     | *)    | **)  |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Serial number                     | 0x9C22 | 39970 | 1   | BCD   | RO   | 1st two digits of serial number       |
    |                                   | 0x9C23 | 39971 | 1   | BCD   | RO   | 2nd two digits of serial number       |
    |                                   | 0x9C24 | 39972 | 1   | BCD   | RO   | 3rd two digits of serial number       |
    |                                   | 0x9C25 | 39973 | 1   | BCD   | RO   | 4th two digits of serial number       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Device type                       | 0x9C26 | 39974 | 1   | HEX   | RO   | 0x0001 - TA3610                       |
    |                                   |        |       |     |       |      | 0x0002 - TA3611                       |
    |                                   |        |       |     |       |      | 0x0003 - TA7610                       |
    |                                   |        |       |     |       |      | 0x0004 - TA4611                       |
    |                                   |        |       |     |       |      | 0x0005 - TA0610                       |
    |                                   |        |       |     |       |      | 0x0006 - reserved                     |
    |                                   |        |       |     |       |      | 0x0007 - TA7611                       |
    |                                   |        |       |     |       |      | 0x0008 - TA5640                       |
    |                                   |        |       |     |       |      | 0x0009 - TA4621                       |
    |                                   |        |       |     |       |      | 0x000A - TA3621                       |
    |                                   |        |       |     |       |      | 0x000B - TA3645                       |
    |                                   |        |       |     |       |      | 0x000C - TA7640                       |
    |                                   |        |       |     |       |      | 0x0080 - PA8652                       |
    |                                   |        |       |     |       |      | 0x0081 - PA8611                       |
    |                                   |        |       |     |       |      | 0x0082 - PA8641                       |
    |                                   |        |       |     |       |      | 0x0083 - PA8610                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|


3.2 Device states

    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Variable                          | Adr.   | Adr.  | Nr. | Type  | Acc. | Description                           |
    |                                   | [HEX]  | [DEC] |     | *)    | **)  |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Internal acoustic signaling       | 0x9C27 | 39975 | 1   | INT   | RO   | 1 - active                            |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Optical LED signaling             | 0x9C28 | 39976 | 1   | INT   | RO   | 1 - active                            |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Acoustic alarm mute               | 0x9C29 | 39977 | 1   | INT   | R/W  | Write 1 to activate acoustic mute     |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Configuration error               | 0x9C2A | 39978 | 1   | INT   | RO   | 1 - configuration error               |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | System alarm - measurement error  | 0x9C2B | 39979 | 1   | INT   | RO   | 1 - measurement error                 |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Low voltage of RTC battery        | 0x9C2C | 39980 | 1   | INT   | RO   | 1 - battery error                     |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|


3.3 Measured values

    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Variable                          | Adr.   | Adr.  | Nr. | Type  | Acc. | Description                           |
    |                                   | [HEX]  | [DEC] |     | *)    | **)  |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Measured value for channel 1      | 0x9C40 | 40000 | 1   | INT*X | RO   | 16bit register in format INT*X - see  |
    |                                   |        |       |     |       |      | table ***); error value <= -32000     |
    |               ....                |  ...   |  ...  |     |       |      |                                       |
    |                                   |        |       |     |       |      |                                       |
    | Measured value for channel 8      | 0x9C47 | 40007 |     |       |      |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | State of alarm 1 at channel 1     | 0x9C48 | 40008 | 1   | INT   | RO   | 0 - alarm inactive                    |
    |                                   |        |       |     |       |      | 1 - alarm active                      |
    |               ....                |  ...   |  ...  |     |       |      |                                       |
    |                                   |        |       |     |       |      |                                       |
    | State of alarm 1 at channel 8     | 0x9C4F | 40015 |     |       |      |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | State of alarm 2 at channel 1     | 0x9C50 | 40016 | 1   | INT   | RO   | 0 - alarm inactive                    |
    |                                   |        |       |     |       |      | 1 - alarm active                      |
    |               ....                |  ...   |  ...  |     |       |      |                                       |
    |                                   |        |       |     |       |      |                                       |
    | State of alarm 2 at channel 8     | 0x9C57 | 40023 |     |       |      |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Unit for channel 1                | 0x9C58 | 40024 | 1   | STR   | RO   | First two characters from channel     |
    |                                   |        |       |     |       |      | unit                                  |
    |               ....                |  ...   |  ...  |     |       |      |                                       |
    |                                   |        |       |     |       |      |                                       |
    | Unit for channel 8                | 0x9C5F | 40031 |     |       |      |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Number of decimal places for ch1  | 0x9C60 | 40032 | 1   | INT   | RO   | Number of decimal places for value    |
    |                                   |        |       |     |       |      | in format INT*X - see table ***)      |
    |               ....                |  ...   |  ...  |     |       |      |                                       |
    |                                   |        |       |     |       |      |                                       |
    | Number of decimal places for ch8  | 0x9C67 | 40039 |     |       |      |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Measured value for channel 1      | 0x9C68 | 40040 | 2   | 32b   | RO   | 32bit measured value at format        |
    |                                   |        |       |     | INT*  |      | INT*(X+2); MSW at first register;     |
    |               ....                |  ...   |  ...  |     | (X+2) |      | error <= -320000000                   |
    |                                   |        |       |     |       |      |                                       |
    | Measured value for channel 8      | 0x9C77 | 40055 |     |       |      |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Measured value for channel 1      | 0x9C78 | 40056 | 2   | IEEE  | RO   | 32bit float IEEE754 value; LSW at     |
    |                                   |        |       |     | 754   |      | first register                        |
    |               ....                |  ...   |  ...  |     | FLOAT |      |                                       |
    |                                   |        |       |     |       |      |                                       |
    | Measured value for channel 8      | 0x9C87 | 40071 |     |       |      |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Min. value for channel 1          | 0x9C88 | 40072 | 1   | INT*X | RO   | 16bit register in format INT*X - see  |
    |                                   |        |       |     |       |      | table ***); error value <= -32000     |
    |               ....                |  ...   |  ...  |     |       |      |                                       |
    |                                   |        |       |     |       |      |                                       |
    | Min. value for channel 8          | 0x9C8F | 40079 |     |       |      |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Max. value for channel 1          | 0x9C90 | 40080 | 1   | INT*X | RO   | 16bit register in format INT*X - see  |
    |                                   |        |       |     |       |      | table ***); error value <= -32000     |
    |               ....                |  ...   |  ...  |     |       |      |                                       |
    |                                   |        |       |     |       |      |                                       |
    | Max. value for channel 8          | 0x9C97 | 40087 |     |       |      |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|


3.4 Alarm limits

    All registers for alarm limits support read and write access. To enable writing, the Modbus server mode must be 
    set to "Enabled write to alarm limits and mute". Writing to any of these registers triggers an update of the 
    device's alarm limits. For this reason, the interval between two consecutive writes must not be shorter than 
    15 seconds. If consecutive writes occur faster than allowed, the Modbus server will raise an exception. When 
    changing multiple alarm limits, it is recommended to use a read-modify-write approach across multiple registers
    at once.
      

    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Variable                          | Adr.   | Adr.  | Nr. | Type  | Acc. | Description                           |
    |                                   | [HEX]  | [DEC] |     | *)    | **)  |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Alarm 1 mode for channel 1        | 0x9CA4 | 40100 | 1   | INT   | R/W  | 0 - alarm disabled                    |
    |               ....                |  ...   |  ...  |     |       |      | 1 - lower than limit                  |
    | Alarm 1 mode for channel 8        | 0x9CAB | 40107 |     |       |      | 2 - higher than limit                 |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Alarm 2 mode for channel 1        | 0x9CAC | 40108 | 1   | INT   | R/W  | 0 - alarm disabled                    |
    |               ....                |  ...   |  ...  |     |       |      | 1 - lower than limit                  |
    | Alarm 2 mode for channel 8        | 0x9CB3 | 40115 |     |       |      | 2 - higher than limit                 |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Alarm 1 limit channel 1           | 0x9CB4 | 40116 | 1   | INT*X | R/W  | 16bit register in format INT*X - see  |
    |               ....                |  ...   |  ...  |     |       |      | table ***); not used for BIN inputs   |
    | Alarm 1 limit channel 8           | 0x9CBB | 40123 |     |       |      |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Alarm 2 limit channel 1           | 0x9CBC | 40124 | 1   | INT*X | R/W  | 16bit register in format INT*X - see  |
    |               ....                |  ...   |  ...  |     |       |      | table ***); not used for BIN inputs   |
    | Alarm 2 limit channel 8           | 0x9CC3 | 40131 |     |       |      |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Alarm 1 delay channel 1           | 0x9CC4 | 40132 | 1   | INT   | R/W  | delay for alarm activation in sec     |
    |               ....                |  ...   |  ...  |     |       |      |                                       |
    | Alarm 1 delay channel 8           | 0x9CCB | 40139 |     |       |      |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Alarm 2 delay channel 1           | 0x9CCC | 40140 | 1   | INT   | R/W  | delay for alarm activation in sec     |
    |               ....                |  ...   |  ...  |     |       |      |                                       |
    | Alarm 2 delay channel 8           | 0x9CD3 | 40147 |     |       |      |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Alarm 1 hysteresis channel 1      | 0x9CD4 | 40148 | 1   | INT*X | R/W  | 16bit register in format INT*X - see  |
    |               ....                |  ...   |  ...  |     |       |      | table ***); not used for BIN inputs   |
    | Alarm 1 hysteresis channel 8      | 0x9CDB | 40155 |     |       |      |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    | Alarm 2 hysteresis channel 1      | 0x9CDC | 40156 | 1   | INT*X | R/W  | 16bit register in format INT*X - see  |
    |               ....                |  ...   |  ...  |     |       |      | table ***); not used for BIN inputs   |
    | Alarm 2 hysteresis channel 8      | 0x9CE3 | 40163 |     |       |      |                                       |
    |-----------------------------------|--------|-------|-----|-------|------|---------------------------------------|
    

4.  Notice

    *)  Type:

        BCD ......... register is in BCD format (16bit)
        HEX ......... number in hexadecimal format (16bit)
        INT ......... register is a signed 16bit integer in the range -32768 to 32767
        INT*X ....... register is a signed 16bit integer. To increase the resolution of the transmitted value,
                      the measured value is multiplied by a factor X. The number of decimal places can be obtained 
                      from registers 40032-40039 or from the table below ***).
                      For example, if the number of decimal places is 1, then a temperature value of 238 from the 
                      register corresponds to 23.8 °C. Error values are transmitted as numbers lower than -32000 
                      (e.g. -32005 = Error 5).
        STR ......... two-byte text stored in one 16bit Modbus register
        INT*(X+2) ... 32bit measured value with increased resolution by two decimal places. The value is transmitted 
                      via two 16-bit Modbus registers. The most significant part of the number is transmitted first
                      (e.g. value 22.825 -> reg1: 0, reg2: 22825). Error values are transmitted as numbers lower 
                      than -320000000 (e.g. -320000011 = Error 11).
        IEEE 754 .... value is a 32-bit IEEE 754 floating-point number transmitted via two Modbus registers.
                      Value 22.704 is transmitted as reg1: 0xA317 and reg2: 0x41B5.

    **)  Access:
 
         RO .......... register is read-only (supported function codes 0x03, 0x04)
         R/W ......... read/write register (supported function codes 0x03, 0x04, 0x10)


    ***) Table of decimal places for INT*X:

        |-----------------------------------|----------------|--------------|-----------------------------------------|
        | Measured value                    | Number of dec. | Unit         | Example                                 |
        |                                   | places (mult)  |              |                                         |
        |-----------------------------------|----------------|--------------|-----------------------------------------|
        | Temperature                       | 1 (*10)        | [ C] or [ F] | 125   = 12.5 C                          |
        |-----------------------------------|----------------|--------------|-----------------------------------------|
        | Relative humidity                 | 1 (*10)        | [%RH]        | 801   = 80.1 %RH                        |
        |-----------------------------------|----------------|--------------|-----------------------------------------|
        | Dew point                         | 1 (*10)        | [ C] or [ F] | 93    = 9.3 C                           |
        | Absolute humidity                 |                | [g/m^3]      | 85    = 8.5 g/m^3                       |
        | Specific humidity                 |                | [g/kg]       | 76    = 7.6 g/kg                        |
        | Mixing ratio                      |                | [g/kg]       | 78    = 7.8 g/kg                        |
        | Specific enthalpy                 |                | [kJ/kg]      | 445   = 44.5 kJ/kg                      |
        | Humidex                           |                | [-]          | 301   = 30.0                            |
        | Heat index                        |                | [ C] or [ F] | 218   = 21.8 C                          |
        |-----------------------------------|----------------|--------------|-----------------------------------------|
        | Barometric pressure               | 1 (*10)        | [hPa]        | 10117 = 1011.7 hPa                      |
        |                                   | 2 (*100)       | [kPa]        | 10117 = 101.17 kPa                      |
        |                                   | 1 (*10)        | [mBar]       | 10118 = 1011.8 mBar                     |
        |                                   | 1 (*10)        | [mmHg]       | 7588  = 758.8 mmHg                      |
        |                                   | 2 (*100)       | [inHg]       | 2988  = 29.88 inHg                      |
        |                                   | 1 (*10)        | [inH2O]      | 4062  = 406.2 inH2O                     |
        |                                   | 3 (*1000)      | [PSI]        | 14675 = 14.675 PSI                      |
        |                                   | 1 (*10)        | [oz/in^2]    | 2348  = 234.8 oz/in^2                   |
        |-----------------------------------|----------------|--------------|-----------------------------------------|
        | CO2 level                         | 0 (*1)         | [ppm]        | 890   = 890 ppm                         |
        |-----------------------------------|----------------|--------------|-----------------------------------------|
        | Binary input                      | 0 (*1)         | [-]          | 1     = Closed,  0 = Open               |
        |                                   |                |              | 1     = High,    0 = Low                |
        |                                   |                |              | 1     = Flooded, 0 = Dry                |
        |-----------------------------------|----------------|--------------|-----------------------------------------|

