7.3. Modbus Protocol (RS-485)#
Protocol Overview#
The AX500 instrument responds to Modbus RTU requests over the RS-485 data line. Communication parameters such as baud rate, parity, stop bits, and device ID are configured through the PC application or via Modbus itself. The default settings are:
Baud rate: 115200Data bits: 8Parity: NoneStop bits: 1Slave ID: 1
Modbus is a request-response protocol. A master device (such as a data logger or PLC) sends requests, and the slave device (the AX500 instrument) responds. The master can either read the value of one or more holding registers (using Modbus function code 0x03), or write the value of a holding register (function code 0x06), or write more holding registers (function code 0x10). All registers in the AX500 are Holding Registers (40001-range in Modbus convention).
IMPORTANT: Register Address vs. Register Number
The Modbus protocol uses zero-based register addressing in the actual request and response frames transmitted on the wire. This means that the first holding register is addressed as 0, the second as 1, and so on. However, many tools and documentation refer to one-based register numbers.
register number = register address + 1
For example, the first register has address 0 and register number 1. The modpoll utility and most Modbus configuration tools use the 1-based register number.
To further complicate things, certain PLC software packages use 40001-based addressing. In this convention, holding registers are labeled starting from 40001, so that the register number 40001 corresponds to the first holding register at address 0. It is important to understand that the leading “4” in addresses such as 40001 does not form part of the address transmitted over Modbus. Instead, it indicates the register type (4 = Holding Register, not to be confused with function 3 for reading holding registers). The actual address sent in the Modbus frame is zero-based and does not include this prefix.
PLC register number = register address + 40001
Modbus is a very old protocol, so please do not judge its quirks too harshly.
Throughout this document, both the zero-based register address and the corresponding one-based register number are shown for clarity.
Each Modbus register holds a single 16-bit (2-byte) value. The AX500 uses the following data types:
uint16 / int16 (1 register)
A single 16-bit value occupying one register. Unsigned values (uint16) range from 0 to 65535. Signed values (int16) range from -32768 to 32767.
uint32 (2 registers)
A 32-bit unsigned integer spanning two consecutive registers. The low word is in the first (even-addressed) register, and the high word is in the second (odd-addressed) register.
Example: Value 0x00000003 would be transmitted as pair of registers 0x0003 and 0x0000.
Reading Registers with modpoll#
modpoll is a command-line utility for reading and writing Modbus registers from a PC.
To read the five int32 measurement values (NO, NO2, CO, SO2, O3) from the AX500, run modpoll with the following arguments:
modpoll -m rtu -a 1 -r 1 -c 10 -t 4 -e -b 9600 -d 8 -p even -s 1 COM3
To read a single uint16 configuration register (e.g., measurement unit at register 28):
modpoll -m rtu -a 1 -r 1 -c 1 -t 4 -b 9600 -d 8 -p even -s 1 COM3
These examples were tested with modpoll version 3.10.
Flag |
Meaning |
|---|---|
|
Slave address 1 |
|
Start at register number 1 (address 0x00) |
|
Read 10 registers |
|
Interpret as 16-bit |
|
Little-endian word order (low word first) |
|
Baud rate 9600 |
|
8 data bits |
|
Even parity |
|
1 stop bit |
|
Serial port (use /dev/ttyUSB0 on Linux) |
Table 4. Modbus register map
Address(es) |
Reg # |
Data Type |
Description |
|---|---|---|---|
2
0x02
|
3
0x03
|
uint16 R/W |
Serial baud rate register. Used to read and change the baud rate of the RS-232 port. Caution: changing this will require the master to reconnect at the new baud rate. See RS-232 Baud Rate for the detailed setting description.
Available values:
0 = 4800,1 = 9600,2 = 14400,3 = 19200,4 = 38400,5 = 57600,6 = 115200.Default value:
6 (115200) |
3
0x03
|
4
0x04
|
uint16 R/W |
Modbus slave address. Must be unique on the RS-485 bus.
Valid range:
1–247.Default value:
1 |
4
0x04
|
5
0x05
|
uint16 R/W |
Modbus RS-485 baud rate. Caution: changing this will require the master to reconnect at the new baud rate. See RS-485 Baud Rate for the detailed setting description.
Available values:
0 = 4800,1 = 9600,2 = 14400,3 = 19200,4 = 38400,5 = 57600,6 = 115200.Default value:
1 (9600 bps) |
5
0x05
|
6
0x06
|
uint16 R/W |
Modbus RS-485 parity and stopbits setting. Caution: changing this will require the master to reconnect with the new port settings.
Available values:
0 = no parity, 1 stop bit,1 = no parity, 2 stop bits,2 = odd parity, 1 stop bit,3 = odd parity, 2 stop bits,4 = even parity, 1 stop bit,5 = even parity, 2 stop bits.Default value:
4 (even parity, 1 stop bit) |
6
0x06
|
7
0x07
|
uint16 R/W |
SDI-12 sensor address. The value is stored as a numeric integer (0–61) in the register. SDI-12 addressing is character-based, so the numeric value from the register is converted to the corresponding SDI-12 address character according to the following mapping:
0–9: Characters '0'–'9'10–35: Characters 'A'–'Z'36–61: Characters 'a'–'z'Default value:
0 |
7
0x07
|
8
0x08
|
uint16 RO |
device type
|
7
0x0A
|
10
0x0B
|
uint16 RO |
Serial number 1st part (first two digits)
|
11
0x0B
|
12
0x0C
|
uint16 RO |
Serial number 2nd part (middle two digits)
|
12
0x0C
|
13
0x0D
|
uint16 RO |
Serial number 3rd par (last two digits)
|
13
0x0D
|
14
0x0E
|
uint16 RO |
Current firmware version number. Read-only.
Example: if the firmware version is 1.2.3 this register holds 123.
|
14
0x0E
|
15
0x0F
|
uint16 RO |
Current Hardware version number. Read-only.
Example: if the firmware version is RevA this register holds A.
|
15
0x0F
|
16
0x10
|
int16 RO |
Air temperature, in °C, multiplied by 100.
Example: if the temperature is 20.15 °C, the register pair will hold the int16 value 2015.
|
16
0x0F
|
17
0x11
|
int16 RO |
Relative humidity, in %, multiplied by 100.
Example: if the relative humidity is 42.1%, the register pair will hold the int16 value 4210.
|
17,18
0x11,0x12
|
18,19
0x12,0x13
|
int32 RO |
Atmospheric pressure in Pa, multiplied by 100.
(Optional)
|
19
0x13
|
20
0x14
|
int16 RO |
AQI – Air Quality index
|
20
0x14
|
21
0x15
|
int16 RO |
vin average [mV]. Average input voltage in mV
|
21,22
0x15,0x16
|
22,23
0x16,0x17
|
int32 RO |
PM1 measurement, in µg/m³, multiplied by 100.
|
23,24
0x17,0x18
|
24,25
0x18,0x19
|
int32 RO |
PM2.5 measurement, in µg/m³, multiplied by 100.
|
25,26
0x19,0x1A
|
26,27
0x1A,0x1B
|
int32 RO |
PM10 measurement, in µg/m³, multiplied by 100.
|
27,28
0x1B,0x1C
|
28,29
0x1C,0x1D
|
int32 RO |
NO concentration measurement, in µg/m³, multiplied by 100.
|
29,30
0x1D,0x1E
|
30,31
0x1E,0x1F
|
int32 RO |
NO2 concentration measurement, in µg/m³, multiplied by 100.
|
31,32
0x1F,0x20
|
32,33
0x20,0x21
|
int32 RO |
CO concentration measurement, in µg/m³, multiplied by 100.
|
33,34
0x21,0x22
|
34,35
0x22,0x23
|
int32 RO |
SO2 concentration measurement, in µg/m³, multiplied by 100.
|
35,36
0x23,0x24
|
36,37
0x24,0x25
|
int32 RO |
O3 concentration measurement, in µg/m³, multiplied by 100.
|
47
0x2F
|
48
0x30
|
int16 RO |
Sensor status bitmask. Bit value
0 marks inactive sensor; bit value 1 marks active sensor.Bit at position 0 corresponds to the first gas sensor (NO), bit at position 1 corresponds to the second gas sensor (NO2), and so on.
|
48
0x30
|
49
0x31
|
int16 RO |
Sensor measurement validity bitmask. Bit value
0 marks invalid measurement; bit value 1 marks valid measurement.Bit at position 0 corresponds to the first gas sensor (NO), bit at position 1 corresponds to the second gas sensor (NO2), and so on.
|
49
0x31
|
50
0x32
|
int16 RO |
Blowout faults. Indicates blowout system driver faults detected since device startup.
The value is a bit field where bit 0 represents a pump driver fault and bit 1 represents a valve driver fault.
If a bit is set, the corresponding driver has faulted at least once since startup.
|
55
0x37
|
56
0x38
|
int16 WO |
Command: Writing value
1 to this register will immediately start the blowout self-cleaning procedure.This register always reads
0. |
56
0x38
|
57
0x39
|
int16 RW |
Sensor blowout period in minutes. If set to zero, the blowout self-cleaning will not be performed periodically.
If set to a value, every specified number of minutes, the sensor will perform blowout self-cleaning.
Default value:
0 |
57
0x39
|
58
0x3A
|
int16 RW |
Enables or disables NMEA output.
The value
0 disables NMEA output, while 1 enables NMEA output.Default value:
1 |
59
0x3B
|
60
0x3C
|
int16 RW |
Factory reset command register.
This register always reads
0.Writing
1 resets all device settings to factory default values. |
60
0x3C
|
61
0x3D
|
int16 RW |
Enables or disables SDI-12 sleep mode.
The value
0 disables SDI-12 sleep mode, while 1 enables SDI-12 sleep mode.Default value:
0 |
61
0x3D
|
62
0x3E
|
int16 RW |
Device reset command register.
This register always reads
0.Writing
1 resets the entire device. |
62
0x3E
|
63
0x3F
|
int16 RW |
Sensor reset command register.
This register always reads
0.Writing
1 resets only the SmartSense sensor module. |
63
0x3F
|
64
0x40
|
int16 RO |
Contains characters 0 and 1 of the sensor board firmware version string.
|
64
0x40
|
65
0x41
|
int16 RO |
Contains characters 2 and 3 of the sensor board firmware version string.
|
65
0x41
|
66
0x42
|
int16 RO |
Contains characters 4 and 5 of the sensor board firmware version string.
|
66
0x42
|
67
0x43
|
int16 RO |
Contains characters 6 and 7 of the sensor board firmware version string.
|
67
0x43
|
68
0x44
|
int16 RO |
Contains characters 0 and 1 of the sensor board hardware version string.
|
68
0x44
|
69
0x45
|
int16 RO |
Contains characters 2 and 3 of the sensor board hardware version string.
|
69
0x45
|
70
0x46
|
int16 RO |
Contains characters 4 and 5 of the sensor board hardware version string.
|
70
0x46
|
71
0x47
|
int16 RO |
Contains characters 6 and 7 of the sensor board hardware version string.
|
71
0x47
|
72
0x48
|
int16 RO |
Contains characters 0 and 1 of the sensor board bootloader version string.
|
72
0x48
|
73
0x49
|
int16 RO |
Contains characters 2 and 3 of the sensor board bootloader version string.
|
73
0x49
|
74
0x4A
|
int16 RO |
Contains characters 4 and 5 of the sensor board bootloader version string.
|
74
0x4A
|
75
0x4B
|
int16 RO |
Contains characters 6 and 7 of the sensor board bootloader version string.
|
79
0x4F
|
80
0x50
|
int16 RO |
Defines the gas sensor type installed in sensor slot 1. Possible values are:
0 = CO,1 = SO2,2 = NO,3 = NO2,4 = O3. |
80
0x50
|
81
0x51
|
int16 RO |
Defines the gas sensor type installed in sensor slot 2. Possible values are:
0 = CO,1 = SO2,2 = NO,3 = NO2,4 = O3. |
81
0x51
|
82
0x52
|
int16 RO |
Defines the gas sensor type installed in sensor slot 3. Possible values are:
0 = CO,1 = SO2,2 = NO,3 = NO2,4 = O3. |
82
0x52
|
83
0x53
|
int16 RO |
Defines the gas sensor type installed in sensor slot 4. Possible values are:
0 = CO,1 = SO2,2 = NO,3 = NO2,4 = O3. |
83
0x53
|
84
0x54
|
int16 RO |
Defines the gas sensor type installed in sensor slot 5. Possible values are:
0 = CO,1 = SO2,2 = NO,3 = NO2,4 = O3. |