88 lines
6.1 KiB
Markdown
88 lines
6.1 KiB
Markdown
<img src="./img/logo.svg" alt="Logo" width="100"/>
|
|
|
|
[🇩🇪 Deutsch](modbus-registers.de.md) | 🇬🇧 English | [🇫🇷 Français](modbus-registers.fr.md) | [🇪🇸 Español](modbus-registers.es.md)
|
|
|
|
# MODBUS Register Map Definition v1.0
|
|
|
|
## 1. Introduction
|
|
|
|
This document defines the MODBUS registers for the universal slave nodes of the irrigation system.
|
|
|
|
### 1.1. Addressing Philosophy
|
|
|
|
All registers are defined in a single, continuous list per register type (`Input` or `Holding`). A "Category" column logically assigns the function. The addresses are grouped in blocks to leave room for future extensions and to increase readability.
|
|
|
|
* **`0x0000 - 0x000F`**: Valve control & status
|
|
* **`0x0010 - 0x001F`**: Digital outputs (LEDs / relays)
|
|
* **`0x0020 - 0x002F`**: Digital inputs (buttons / sensors)
|
|
* **`0x00F0 - 0x00FF`**: General device configuration & status
|
|
* **`0x0100 - 0x01FF`**: Firmware update mechanism
|
|
|
|
### 1.2. Used Function Codes
|
|
|
|
* **`0x03` (Read Holding Registers):** For reading `4xxxx` registers.
|
|
* **`0x04` (Read Input Registers):** For reading `3xxxx` registers.
|
|
* **`0x06` (Write Single Register):** For writing a single `4xxxx` register.
|
|
* **`0x10` (Write Multiple Registers):** For writing multiple `4xxxx` registers at once.
|
|
|
|
## 2. Input Registers (3xxxx, Read-Only)
|
|
|
|
| Address (hex) | Name | Category | Description |
|
|
| :--- | :--- | :--- | :--- |
|
|
| **0x0000** | `VALVE_STATE_MOVEMENT` | Valve | Combined status register. **High-Byte**: Movement (`0`=Idle, `1`=Opening, `2`=Closing, `3`=Error). **Low-Byte**: State (`0`=Closed, `1`=Open). |
|
|
| **0x0001** | `MOTOR_CURRENT_MA` | Valve | Current motor current in milliamperes (mA). |
|
|
| **0x0020** | `DIGITAL_INPUTS_STATE` | Inputs | Bitmask of the digital inputs. Bit 0: Input 1, Bit 1: Input 2. `1`=Active. |
|
|
| **0x0021** | `BUTTON_EVENTS` | Inputs | Event flags for buttons (Clear-on-Read). Bit 0: Button 1 pressed. Bit 1: Button 2 pressed. |
|
|
| **0x00F0** | `FIRMWARE_VERSION_MAJOR_MINOR` | System | e.g. `0x0102` for v1.2. |
|
|
| **0x00F1** | `FIRMWARE_VERSION_PATCH` | System | e.g. `3` for v1.2.3. |
|
|
| **0x00F2** | `DEVICE_STATUS` | System | `0`=OK, `1`=General error. |
|
|
| **0x00F3** | `UPTIME_SECONDS_LOW` | System | Lower 16 bits of the uptime in seconds. |
|
|
| **0x00F4** | `UPTIME_SECONDS_HIGH` | System | Upper 16 bits of the uptime. |
|
|
| **0x0100** | `FWU_LAST_CHUNK_CRC` | Firmware-Update | Contains the CRC16 of the last data chunk received in the buffer. |
|
|
|
|
## 3. Holding Registers (4xxxx, Read/Write)
|
|
|
|
| Address (hex) | Name | Category | Description |
|
|
| :--- | :--- | :--- | :--- |
|
|
| **0x0000** | `VALVE_COMMAND` | Valve | `1`=Open, `2`=Close, `0`=Stop movement. |
|
|
| **0x0001** | `MAX_OPENING_TIME_S` | Valve | Safety timeout in seconds for the opening process. |
|
|
| **0x0002** | `MAX_CLOSING_TIME_S` | Valve | Safety timeout in seconds for the closing process. |
|
|
| **0x0010** | `DIGITAL_OUTPUTS_STATE` | Outputs | Bitmask for reading and writing the outputs. Bit 0: Output 1, Bit 1: Output 2. `1`=ON, `0`=OFF. |
|
|
| **0x00F0** | `WATCHDOG_TIMEOUT_S` | System | Timeout of the fail-safe watchdog in seconds. `0`=Disabled. |
|
|
| **0x0100** | `FWU_COMMAND` | Firmware-Update | `1`: **Verify Chunk**: The last transmitted chunk was found to be valid by the client. The slave should now write it to flash. `2`: **Finalize Update**: All chunks have been transmitted. Finalize installation and restart. |
|
|
| **0x0101** | `FWU_CHUNK_OFFSET_LOW` | Firmware-Update | Lower 16 bits of the 32-bit offset to which the next chunk is to be written. |
|
|
| **0x0102** | `FWU_CHUNK_OFFSET_HIGH` | Firmware-Update | Upper 16 bits of the 32-bit offset. |
|
|
| **0x0103** | `FWU_CHUNK_SIZE` | Firmware-Update | Size of the next chunk in bytes (max. 256). |
|
|
| **0x0180** | `FWU_DATA_BUFFER` | Firmware-Update | **Start address** of a 128x16-bit buffer (256 bytes). Corresponds to registers `40384` to `40511`. |
|
|
|
|
## 4. Detailed Firmware Update Process
|
|
|
|
This process is stateless and robust against transmission errors.
|
|
|
|
1. **Client:** Selects a chunk (max. 256 bytes) from the firmware file and calculates its CRC16.
|
|
2. **Client:** Writes the target offset (e.g. `0`) to `FWU_CHUNK_OFFSET_...` and the size to `FWU_CHUNK_SIZE`.
|
|
3. **Client:** Writes the chunk data to the `FWU_DATA_BUFFER` (from address `0x0180`).
|
|
4. **Slave:** Receives the data, places it in the RAM buffer and calculates the CRC. The result is provided in `FWU_LAST_CHUNK_CRC` (`30256`).
|
|
5. **Client:** Reads `FWU_LAST_CHUNK_CRC` and compares the value with the self-calculated CRC.
|
|
* **Error:** Go back to step 3 to send the same chunk again.
|
|
* **Success:** Continues with the next step.
|
|
6. **Client:** Writes the command `1` ("Verify Chunk") to `FWU_COMMAND` (`40256`).
|
|
7. **Slave:** Receives the command, takes the verified chunk from the RAM buffer and writes it to the correct location in the flash memory.
|
|
8. **Client:** Continues with the next chunk (back to step 1 with new offset and data).
|
|
9. **Last Chunk:** After the last chunk has been transferred and written to flash with command `1`, the client writes the command `2` ("Finalize Update") to `FWU_COMMAND`.
|
|
10. **Slave:** Performs final checks and restarts so that MCUBoot can perform the installation.
|
|
|
|
## Appendix: QDY30A Level Sensor Registers
|
|
|
|
These registers belong to the external level sensor and can also be addressed on the bus. According to the manufacturer, these are Holding Registers (`4xxxx`) that are read with function code `0x03`.
|
|
|
|
| Address (hex) | Name | R/W | Description |
|
|
| :--- | :--- | :-- | :--- |
|
|
| **0x0000** | `NODE_ADDRESS` | R/W | Device address of the sensor (1-255). |
|
|
| **0x0001** | `BAUDRATE` | R/W | `0`=1200, `1`=2400, `2`=4800, `3`=9600, `4`=19200, `5`=38400, `6`=57600, `7`=115200. |
|
|
| **0x0002** | `UNIT` | R/W | `0`=None, `1`=cm, `2`=mm, `3`=MPa, `4`=Pa, `5`=kPa. |
|
|
| **0x0003** | `DECIMAL_PLACES` | R/W | Number of decimal places for the measured value (0-3). |
|
|
| **0x0004** | `CURRENT_MEASUREMENT` | R | The scaled measured value as a signed 16-bit integer. |
|
|
| **0x0005** | `MEASURING_RANGE_ZERO_POINT` | R/W | Raw value for the zero point of the scale. |
|
|
| **0x0006** | `MEASURING_RANGE_END_POINT` | R/W | Raw value for the end point of the scale. |
|