Modbus Register Definitions
Modbus Register Definitions
| Register Type | Register Address | Register Name | R/W Attribute | Value Range | Default Value | Description |
|---|---|---|---|---|---|---|
| Input Register | 0x0000 | PIDR | R | 0x0296 | 0x0296 | Product ID. Identifies the DFRobot BMV080 Gravity module; this value is verified during begin() of the Gravity library. |
| Input Register | 0x0001 | VIDR | R | 0x3343 | 0x3343 | Vendor ID. 0x3343 represents DFRobot. |
| Input Register | 0x0002 | Firmware Version | R | 0x0000 ~ 0xFFFF | 0x1000 | Firmware version number. 0x1000 = V1.0.0. |
| Input Register | 0x0003 | Register Map Version | R | 0x0000 ~ 0xFFFF | 0x0004 | Register mapping version. Library version must match the firmware version. |
| Input Register | 0x0004 | Operating Status | R | 0x0000 ~ 0x0005 | 0x0000 | Current firmware operating status:0 = Booting,1 = Sensor ready, waiting for measurement,2 = Continuous measurement in progress,3 = Duty-cycle measurement in progress,4 = Stopped,5 = Error state |
| Input Register | 0x0005 | Last Status Code | R | 0x0000 ~ 0xFFFF | 0x0000 | Status code from the last BMV080 SDK operation. 0 = Success; non-zero value indicates error / warning. |
| Input Register | 0x0006 | PM1.0 (float32 High Word) | R | 0x0000 ~ 0xFFFF | 0x0000 | High 16 bits of the float32 PM1.0 mass concentration value. |
| Input Register | 0x0007 | PM1.0 (float32 Low Word) | R | 0x0000 ~ 0xFFFF | 0x0000 | Low 16 bits of the float32 PM1.0 mass concentration value. |
| Input Register | 0x0008 | PM2.5 (float32 High Word) | R | 0x0000 ~ 0xFFFF | 0x0000 | High 16 bits of the float32 PM2.5 mass concentration value. |
| Input Register | 0x0009 | PM2.5 (float32 Low Word) | R | 0x0000 ~ 0xFFFF | 0x0000 | Low 16 bits of the float32 PM2.5 mass concentration value. |
| Input Register | 0x000A | PM10 (float32 High Word) | R | 0x0000 ~ 0xFFFF | 0x0000 | High 16 bits of the float32 PM10 mass concentration value. |
| Input Register | 0x000B | PM10 (float32 Low Word) | R | 0x0000 ~ 0xFFFF | 0x0000 | Low 16 bits of the float32 PM10 mass concentration value. |
| Input Register | 0x000C | Operating Duration (float32 High Word) | R | 0x0000 ~ 0xFFFF | 0x0000 | High 16 bits of the float32 operating duration (unit: second). |
| Input Register | 0x000D | Operating Duration (float32 Low Word) | R | 0x0000 ~ 0xFFFF | 0x0000 | Low 16 bits of the float32 operating duration (unit: second). |
| Input Register | 0x000E | Status Flags | R | 0x0000 ~ 0xFFFF | 0x0000 | Sensor status bitfield:bit0: Sensor blockage;bit1: PM2.5 out-of-range;bit2: New PM data ready (cleared when PM data, flags and sample counter are read);bit3: Sensor initialization complete;bit4: Measurement in progress;bit5: Pending dirty parameters (auto-cleared after successful application);bit6: Parameter validation passed;bit7: Parameter applying (asserted during internal parameter download on START/RESET);bit8: Compatibility reserved bit (always 0 under float register mapping);bit9: A floating-point input is non-finite (NaN/Inf), written as 0;bit10–15: Reserved |
| Input Register | 0x000F | Sample Counter | R | 0x0000 ~ 0xFFFF | 0x0000 | Monotonically incrementing sample counter. Increments upon receiving sensor data; wraps around after exceeding 65535. |
| Input Register | 0x0010 | SDK Major Version | R | 0x0000 ~ 0xFFFF | 0x0000 | Bosch BMV080 SDK major version number. |
| Input Register | 0x0011 | SDK Minor Version | R | 0x0000 ~ 0xFFFF | 0x0000 | Bosch BMV080 SDK minor version number. |
| Input Register | 0x0012 | SDK Patch Version | R | 0x0000 ~ 0xFFFF | 0x0000 | Bosch BMV080 SDK patch version number. |
| Input Register | 0x0013 | Sensor Unique ID 0 | R | 0x0000 ~ 0xFFFF | 0x0000 | Bytes 0‑1 of sensor unique ID, stores 2 ASCII characters in big-endian format.Decoding: id[i*2] = (reg >> 8), id[i*2+1] = (reg & 0xFF) |
| Input Register | 0x0014 | Sensor Unique ID 1 | R | 0x0000 ~ 0xFFFF | 0x0000 | Bytes 2‑3 of sensor unique ID, stores 2 ASCII characters in big-endian format.Decoding: id[i*2] = (reg >> 8), id[i*2+1] = (reg & 0xFF) |
| Input Register | 0x0015 | Sensor Unique ID 2 | R | 0x0000 ~ 0xFFFF | 0x0000 | Bytes 4‑5 of sensor unique ID, stores 2 ASCII characters in big-endian format.Decoding: id[i*2] = (reg >> 8), id[i*2+1] = (reg & 0xFF) |
| Input Register | 0x0016 | Sensor Unique ID 3 | R | 0x0000 ~ 0xFFFF | 0x0000 | Bytes 6‑7 of sensor unique ID, stores 2 ASCII characters in big-endian format.Decoding: id[i*2] = (reg >> 8), id[i*2+1] = (reg & 0xFF) |
| Input Register | 0x0017 | Sensor Unique ID 4 | R | 0x0000 ~ 0xFFFF | 0x0000 | Bytes 8‑9 of sensor unique ID, stores 2 ASCII characters in big-endian format.Decoding: id[i*2] = (reg >> 8), id[i*2+1] = (reg & 0xFF) |
| Input Register | 0x0018 | Sensor Unique ID 5 | R | 0x0000 ~ 0xFFFF | 0x0000 | Bytes 10‑11 of sensor unique ID, stores 2 ASCII characters in big-endian format.Decoding: id[i*2] = (reg >> 8), id[i*2+1] = (reg & 0xFF) |
| Holding Register | 0x0000 | RTU Slave Address | R/W | 0x0001 ~ 0x00F7 | 0x0057 | UART Modbus RTU slave address. Persistent in NVS after power-off. A0/A1 only controls external I2C address and does not affect RTU address. |
| Holding Register | 0x0001 | Baud Rate | R/W | 0x0001 ~ 0x0008 | 0x0003 | Serial baud rate:0x0001=2400, 0x0002=4800, 0x0003=9600, 0x0004=14400, 0x0005=19200, 0x0006=38400, 0x0007=57600, 0x0008=115200Persistent in NVS; takes effect after reboot. |
| Holding Register | 0x0002 | Parity & Stop Bit Configuration | R/W | 0x0000 ~ 0x0203 | 0x0001 | High byte: parity bit 0x00 = No parity, 0x01 = Even parity, 0x02 = Odd parityLow byte: stop bit 0x01 = 1 bit, 0x02 = 1.5 bits, 0x03 = 2 bits, Persistent in NVS; takes effect after reboot. |
| Holding Register | 0x0003 | Operation Command | W | 0x0001 ~ 0x0003 | 0x0000 | Transient command; read operation always returns 0.0x0001: Start measurement (continuous / duty-cycle selected by MEASURE_MODE),0x0002: Stop measurement,0x0003: Restore sensor default configurationNon-persistent. |
| Holding Register | 0x0004 | Measurement Mode | R/W | 0x0000 ~ 0x0001 | 0x0000 | 0x0000: Continuous measurement mode,0x0001: Duty-cycle measurement modePersistent in NVS. Write operation command after writing this register to start measurement. |
| Holding Register | 0x0005 | Measurement Algorithm | R/W | 0x0001 ~ 0x0003 | 0x0002 | 0x0001: Fast Response,0x0002: Balanced,0x0003: High PrecisionPersistent in NVS. Measurement restarts upon parameter modification. Fast Response algorithm is forced under duty-cycle mode. |
| Holding Register | 0x0006 | Blockage Detection Switch | R/W | 0x0000 ~ 0x0001 | 0x0001 | 0x0000: Disable blockage detection,0x0001: Enable blockage detectionPersistent in NVS. Parameters will be re-applied upon modification. |
| Holding Register | 0x0007 | Vibration Filter Switch | R/W | 0x0000 ~ 0x0001 | 0x0001 | 0x0000: Disable vibration filtering,0x0001: Enable vibration filteringPersistent in NVS. Parameters will be re-applied upon modification. |
| Holding Register | 0x0008 | Integration Time (float32 High Word) | R/W | 0x0000 ~ 0xFFFF | 0x4120 | High 16 bits of float32 integration time, default 10.0f. Persistent in NVS. |
| Holding Register | 0x0009 | Integration Time (float32 Low Word) | R/W | 0x0000 ~ 0xFFFF | 0x0000 | Low 16 bits of float32 integration time, default 10.0f. Persistent in NVS. |
| Holding Register | 0x000A | Duty-Cycle Period | R/W | 0x0000 ~ 0xFFFF | 0x001E | Total duration of duty-cycle period = integration time + sleep time. Unit: second. Persistent in NVS. |
Common Modbus Function Codes
| Function Code | Name | Description |
|---|---|---|
| 0x03 | Read Holding Registers | Read integers, characters, status words and floating-point values (read N words).Used for byte-oriented access to holding registers. |
| 0x04 | Read Input Registers | Read integers, status words and floating-point values (read N words).Used for byte-oriented access to input registers. |
| 0x06 | Write Single Holding Register | Write integers, characters, status words and floating-point values (write one word).Used for byte-oriented write to a holding register. |
| 0x10 | Write Multiple Holding Registers | Write multiple holding registers. Load binary values into a contiguous sequence of holding registers. |
Input registers and holding registers can be read and written using the above commands.
Modbus Exception Codes
| Code | Name | Meaning |
|---|---|---|
| 0x01 | Illegal Function Code | The requested function code is not supported. |
| 0x02 | Illegal Data Address | The register address is out of bounds. |
| 0x03 | Illegal Data Value | The value is outside the permitted range. |
| 0x04 | Slave Device Failure | An internal error occurred on the slave device. |
| 0x08 | CRC Check Error | CRC check failed. |
Sensor Data Reading Example
Function: Read the current PM1.0, PM2.5 and PM10 particulate concentration values detected by the BMV080 sensor via the Modbus RTU protocol.
Hardware Preparation
SEN0662 Gravity: BMV080 PM2.5 Sensor ×1
Wiring Diagram

Connection Description:
| Sensor Pin: VCC | Connect to | Main Controller Pin: 3.3V |
|---|---|---|
| Sensor Pin: GND | Connect to | Main Controller Pin: GND |
| Sensor Pin: R | Connect to | Main Controller Pin: 26/TX |
| Sensor Pin: T | Connect to | Main Controller Pin: 25/RX |
- Sensor DIP switch configuration: Set the communication mode to UART side (the factory default UART address is 0x57).
General Operation Procedure
Parameter configuration: Configure settings in the serial debugging tool to match the sensor:
- Baud rate: 9600 (default)
- Data bits: 8
- Stop bit: 1
- Parity: None
Important Precondition: The sensor does not automatically start measurement after power-up. The start-measurement command must be sent first for the PM concentration registers to refresh with valid data.
Enter the hexadecimal command below in the transmit pane of the debugging tool, enable hex transmit, then send.
Start Measurement Command & Parsing
| Field Name | Hex Value | Description |
|---|---|---|
| Slave Address | 57 | Modbus slave address, default 0x57 (modifiable via holding register and saved to NVS) |
| Function Code | 06 | Write Single Holding Register (fixed command) |
| Starting Register Address | 00 03 | Action command holding register address (0x0003) |
| Register Value to Write | 00 01 | Write value 1 to start sensor measurement |
| CRC Checksum | B4 3C | CRC16 checksum of the command |
Full transmit frame: 57 06 00 03 00 01 B4 3C
Response Data & Parsing
The sensor replies with the following frame upon receiving the command:
| Field Name | Hex Value | Description |
|---|---|---|
| Slave Address | 57 | Matches the slave address in the request frame |
| Function Code | 06 | Acknowledges Write Single Holding Register operation |
| Starting Register Address | 00 03 | Target holding register address written |
| Register Value Written | 00 01 | Acknowledges the written value |
| CRC Checksum | B4 3C | CRC16 checksum of response frame |
Full response frame: 57 06 00 03 00 01 B4 3C
A response identical to the transmit frame indicates successful measurement start. After waiting several milliseconds, PM concentration data can be read.
PM Concentration Read Command & Parsing
Send the PM concentration read command:
| Field Name | Hex Value | Description |
|---|---|---|
| Slave Address | 57 | Modbus slave address, default 0x57 |
| Function Code | 04 | Read Input Registers (fixed command) |
| Starting Register Address | 00 06 | PM1.0 high-word register address (0x0006) |
| Quantity of Registers | 00 06 | Read 6 input registers: PM1.0_HI, PM1.0_LO, PM2.5_HI, PM2.5_LO, PM10_HI, PM10_LO |
| CRC Checksum | 9C 3F | CRC16 checksum of the command |
Full transmit frame: 57 04 00 06 00 06 9C 3F
Response Data & Parsing
Sample response frame returned by the sensor:
| Field Name | Hex Value | Description |
|---|---|---|
| Slave Address | 57 | Matches the slave address in the request frame |
| Function Code | 04 | Acknowledges Read Input Registers operation |
| Byte Count | 0C | Total byte count of payload data (12 bytes) |
| Read Payload | 40 E0 00 00 41 80 00 00 41 B8 00 00 | Sequentially: PM1.0 (HI/LO), PM2.5 (HI/LO), PM10 (HI/LO). Each pair of 16-bit registers forms a 32-bit IEEE‑754 single-precision floating-point value |
| CRC Checksum | C5 58 | CRC16 checksum of response frame |
Full response frame: 57 04 0C 40 E0 00 00 41 80 00 00 41 B8 00 00 C5 58

Data Parsing Steps
The raw response payload is 12 bytes, divided into 3 groups of 4 bytes each (2 × 16-bit registers, big-endian).
Physical quantity conversion is already completed inside the sensor firmware. The two 16-bit Modbus registers returned hold the high/low fragments of a 32-bit IEEE‑754 single-precision float. No additional multiplication or scaling factors are required.
Concatenate the high word and low word in big-endian order to form the 32-bit raw bit value:
floatRaw = ((uint32_t)high_word << 16) | low_word;
Interpret the bit pattern of floatRaw directly as an IEEE‑754 single-precision float. The resulting value is particulate concentration in μg/m³.
Example
- PM1.0: high word = 0x40E0, low word = 0x0000
floatRaw = (0x40E0 << 16) | 0x0000 = 0x40E00000Interpreted per IEEE‑754 → 7.0 μg/m³ - PM2.5: high word = 0x4180, low word = 0x0000
floatRaw = (0x4180 << 16) | 0x0000 = 0x41800000Interpreted per IEEE‑754 → 16.0 μg/m³ - PM10: high word = 0x41B8, low word = 0x0000
floatRaw = (0x41B8 << 16) | 0x0000 = 0x41B80000Interpreted per IEEE‑754 → 23.0 μg/m³
Result Interpretation
The sample readings represent low particulate concentration in ambient air, typical output for a clean environment.
If NaN / Inf is returned, read the status flag input register
0x000E. When BIT9 (VALUE_INVALID) is set, the floating-point data is invalid.
Rationale
Digital output: The firmware encodes concentration values from the Bosch BMV080 chip into 32-bit IEEE‑754 single-precision floats, then splits each float across two 16-bit Modbus registers for output.
Big-endian ordering: Modbus register transmission uses big-endian format; the high 16-bit register precedes the low 16-bit register. The order must not be swapped during reconstruction. Unit: Parsing yields values directly in μg/m³ with no further scaling required.
Notes
- No automatic measurement after power-up: The start-measurement command
06 00 03 00 01must be sent after every power cycle. PM-related input registers will continuously refresh only after this command; PM registers hold stale values or zero before measurement starts. - Configuration changes (algorithm, blockage detection, integration time, duty-cycle period) can be written directly to holding registers and saved into NVS. However, updated parameters are only downloaded to the sensor chip and take effect upon the next start-measurement command.
- PID / VID, version and operating status registers are readable immediately after power-up; measurement start command is not required.
- CRC checksum in response frames can be used to verify transmission integrity.
- For continuous reading: after measurement starts, repeatedly issue Read Input Register commands to retrieve the latest samples.
- Full-scale PM range: up to 1000 μg/m³. When BIT1 of register
0x000Eis asserted, PM2.5 exceeds the measurement range.
Modbus RTU Scan for Unknown Slave Address
Function: When the Modbus RTU slave address of the sensor is forgotten, scan devices on the bus via a serial debugging tool to retrieve the actual slave address of the BMV080 sensor.
Hardware Required
SEN0662 Gravity: BMV080 PM2.5 Sensor ×1
Wiring Diagram

Connection Description:
| Sensor Pin: VCC | Connect to | Main Controller Pin: 3.3V |
|---|---|---|
| Sensor Pin: GND | Connect to | Main Controller Pin: GND |
| Sensor Pin: R | Connect to | Main Controller Pin: 26/TX |
| Sensor Pin: T | Connect to | Main Controller Pin: 25/RX |
- Sensor DIP switch configuration: Set the communication mode to UART side (the factory default UART address is 0x57).
General Operation Procedure
Parameter configuration: Configure settings in the serial debugging tool to match the sensor:
- Baud rate: 9600 (default)
- Data bits: 8
- Stop bit: 1
- Parity: None
Note: This function is a custom firmware extension. It works only when exactly one BMV080 sensor is connected to the bus. Do not use this command if two or more Modbus devices reside on the bus, as it will cause bus message collision.
Command Transmission & Parsing (Single Sensor on Bus Only)
| Field Name | Hex Value | Description |
|---|---|---|
| Slave Address | 00 | Modbus broadcast address (private extension supports read response) |
| Function Code | 03 | Read Holding Registers (fixed command) |
| Starting Register Address | 00 00 | Holding register 0x0000, which stores the device Modbus slave address |
| Quantity of Registers | 00 01 | Read 1 register |
| CRC Checksum | 85 DB | CRC16 checksum of the command |
Full transmit frame: 00 03 00 00 00 01 85 DB
Response Data & Parsing (Example, actual device address = 0x57)
| Field Name | Hex Value | Description |
|---|---|---|
| Slave Address | 57 | The first byte of the response frame is the actual slave address of the sensor |
| Function Code | 03 | Acknowledges Read Holding Registers operation |
| Byte Count | 02 | 2 bytes of register data returned |
| Read Payload | 00 57 | Content of holding register 0x0000; device slave address = 0x57 |
| CRC Checksum | B1 B6 | CRC16 checksum of the response frame |
Full response frame: 57 03 02 00 57 B1 B6

Result Interpretation
The returned register value 0x0057 indicates the current Modbus slave address of the sensor is 0x57.
Rationale
The standard Modbus‑RTU specification permits only write commands for broadcast addresses; read commands shall not generate a response. This sensor firmware implements a private extension: when only one device exists on the bus, a broadcast read of holding register 0x0000 returns the local address to simplify user debugging.
Notes
-
The bus must contain only one BMV080 sensor. In multi-device scenarios, this command triggers simultaneous responses from multiple devices, causing bus collision, garbled data, and unidentifiable addresses. For multi-device buses, use the standard scanning method: iterate addresses from
0x01to0xF7and read the PID input register. -
This command reads holding register
0x0000(device address configuration register), not the PID. The PID is located in input register0x0000and is read with function code04. -
If the baud rate has been modified, this broadcast command will return no response. Switch to the correct baud rate before use.
-
This private extension is firmware-specific to this sensor. Other vendors’ Modbus sensors do not support this method; do not port this command to other hardware.
Was this article helpful?
