Compare commits
No commits in common. "f9d4a3b97196da520ce7b2191a6b4872e35bfdff" and "c23d1f08c0fcb37327c3e17625cade616966dac3" have entirely different histories.
f9d4a3b971
...
c23d1f08c0
|
|
@ -1,5 +1,3 @@
|
|||
[🇩🇪 Deutsch](concept.de.md) | [🇬🇧 English](concept.en.md)
|
||||
|
||||
# Konzept: Modulares Bewässerungssystem
|
||||
|
||||
Dieses Dokument beschreibt das Konzept für ein modulares, smartes Bewässerungssystem, das zentral über Home Assistant gesteuert wird.
|
||||
16
README.de.md
16
README.de.md
|
|
@ -1,16 +0,0 @@
|
|||
# Modulares Bewässerungssystem
|
||||
|
||||
Dieses Projekt realisiert ein smartes, modulares Bewässerungssystem, das über Home Assistant gesteuert wird.
|
||||
|
||||
## Dokumentation
|
||||
|
||||
Die detaillierte Dokumentation befindet sich im Verzeichnis [`docs/`](./docs/):
|
||||
|
||||
* **[Konzept](./docs/concept.de.md)**: Beschreibt die Systemarchitektur, die verwendeten Komponenten und die grundlegenden Design-Entscheidungen.
|
||||
* **[MODBUS Register](./docs/modbus-registers.de.md)**: Definiert die Register-Map für die Kommunikation mit den Slave-Nodes.
|
||||
* **[Projektplan](./docs/planning.de.md)**: Enthält den Entwicklungs- und Implementierungsplan.
|
||||
|
||||
## Schnellstart
|
||||
|
||||
* **Hardware**: Die KiCad-Dateien für die Hardware befinden sich im Verzeichnis [`hardware/`](./hardware/).
|
||||
* **Software**: Die Zephyr-basierte Firmware für die Slave-Nodes befindet sich im Verzeichnis [`software/`](./software/).
|
||||
20
README.md
20
README.md
|
|
@ -1,18 +1,2 @@
|
|||
[🇩🇪 Deutsch](README.de.md) | [🇬🇧 English](README.md)
|
||||
|
||||
# Modular Irrigation System
|
||||
|
||||
This project implements a smart, modular irrigation system controlled via Home Assistant.
|
||||
|
||||
## Documentation
|
||||
|
||||
The detailed documentation can be found in the [`docs/`](./docs/) directory:
|
||||
|
||||
* **[Concept](./docs/concept.en.md)**: Describes the system architecture, the components used, and the basic design decisions.
|
||||
* **[MODBUS Registers](./docs/modbus-registers.en.md)**: Defines the register map for communication with the slave nodes.
|
||||
* **[Project Plan](./docs/planning.en.md)**: Contains the development and implementation plan.
|
||||
|
||||
## Quick Start
|
||||
|
||||
* **Hardware**: The KiCad files for the hardware are located in the [`hardware/`](./hardware/) directory.
|
||||
* **Software**: The Zephyr-based firmware for the slave nodes is located in the [`software/`](./software/) directory.
|
||||
# Home assistant irrigation system
|
||||
This is a home assistant irrigation system
|
||||
|
|
|
|||
|
|
@ -1,75 +0,0 @@
|
|||
[🇩🇪 Deutsch](concept.de.md) | [🇬🇧 English](concept.en.md)
|
||||
|
||||
# Concept: Modular Irrigation System
|
||||
|
||||
This document describes the concept for a modular, smart irrigation system that is centrally controlled via Home Assistant.
|
||||
|
||||
## 1. Architecture Overview
|
||||
|
||||
The system is divided into three logical layers to ensure high flexibility and maintainability:
|
||||
|
||||
1. **Control Layer (Home Assistant):** All logic, automations, and the user interface reside in Home Assistant. This is the "brain" of the system.
|
||||
2. **Gateway Layer (ESP32):** A pure protocol translator that acts as a bridge between the home network (WLAN/Thread) and the physical bus system of the plant. It contains no control logic of its own.
|
||||
3. **Actor/Sensor Layer (Slave Nodes):** Robust, specialized modules that are controlled via a bus and perform the actual tasks (switching valves, reading sensors).
|
||||
|
||||

|
||||
|
||||
## 2. System Components
|
||||
|
||||
* **Water Tank:** An IBC container serves as a water reservoir.
|
||||
* **Water Supply:** A "rain thief" on the downpipe directs rainwater into the tank.
|
||||
* **Pump:** A pump with an integrated pressure expansion tank provides the necessary water pressure.
|
||||
* **Actuators:** Motorized 12V ball valves to control the water outlets.
|
||||
* **Level Sensor (precise):** A `QDY30A` with 4-20mA output and RS485/MODBUS interface for continuous measurement of the water level.
|
||||
* **Level Sensors (Min/Max):** Optional capacitive sensors (`XKC-Y25-NPN` or similar) as redundant protection against running dry and overflowing.
|
||||
|
||||
## 3. Gateway
|
||||
|
||||
The central communication interface is implemented as a "dumb" gateway.
|
||||
|
||||
* **Hardware:** An `ESP32C6`-based board.
|
||||
* **Function:** The gateway acts as a transparent **MODBUS TCP/IP to MODBUS RTU converter**. It receives commands from the home network and forwards them to the RS485 bus and vice versa. It does not execute its own control logic.
|
||||
* **Connection to Home Assistant:** The connection is made via the home network, either via WLAN or in the future possibly via Thread/Matter. In Home Assistant, the official MODBUS integration is used to address the gateway and the slaves behind it directly.
|
||||
|
||||
## 4. Slave Nodes
|
||||
|
||||
The slave nodes are the working units in the field. To keep the effort low for small series production (e.g. at JLCPCB), a universal board design for all slave types is sought.
|
||||
|
||||
* **Microcontroller:** An `STM32G431PB`. Although powerful, it offers all the necessary peripherals (multiple UARTs, ADCs, CAN) and enables a uniform hardware and software design.
|
||||
* **Peripherals per Node:**
|
||||
* **Two High-Side Outputs (+12V):** Realized via a `VND7050AJ`. Perfect for controlling the 12V motor valves (`Open`/`Close`). The `Sense` line of the driver is read out via an AD converter to realize an end position detection without physical limit switches by measuring the motor current (motor current at standstill ≈ 0).
|
||||
* **Two Low-Side Outputs (0V):** Outputs switched via N-channel MOSFETs. Can be used to control 12V LEDs in buttons or to switch the solid-state relay for the pump.
|
||||
* **Two digital inputs:** Direct, protected inputs on the controller for connecting buttons or the capacitive NPN sensors.
|
||||
|
||||
## 5. Bus System: MODBUS-RTU via RS485
|
||||
|
||||
MODBUS-RTU is consistently used as the bus system.
|
||||
|
||||
* **Reasoning:** This choice is pragmatic, as the level sensor already requires MODBUS. This means that only a single, simple and widespread protocol is required for the entire system.
|
||||
* **Physical Layer:** The cabling is done via RS485. Commercially available Cat-7 Ethernet cable with RJ45 plugs is used:
|
||||
* 1 twisted pair for the bus signals `A` and `B`.
|
||||
* 3 pairs of wires in parallel for `+12V` and `GND` to supply power to the slaves.
|
||||
|
||||
## 6. Software
|
||||
|
||||
* **Operating System (Slaves):** `Zephyr OS`. It is a modern, powerful real-time operating system that enables a clean and maintainable firmware structure.
|
||||
* **Logic Implementation:** The entire control logic (e.g. "If level < 20% and day of the week = Monday, then switch on valve 3 for 10 minutes") is mapped exclusively in **Home Assistant** via its automation engine.
|
||||
|
||||
### 6.1. Firmware Update of the Slaves (OTA)
|
||||
|
||||
The firmware of the slaves can be updated during operation via the bus without the need for direct physical access.
|
||||
|
||||
* **Concept:** The `MCUBoot` bootloader is used. This is decoupled from the communication protocol.
|
||||
* **Procedure:**
|
||||
1. A script in Home Assistant reads the new firmware file (`firmware.bin`).
|
||||
2. The script breaks the file down into small data packets and sends them one after the other to the target slave via MODBUS command.
|
||||
3. The running application on the slave receives these packets and writes them directly to the secondary flash memory ("update slot").
|
||||
4. After successful transmission, the slave is restarted by command.
|
||||
5. `MCUBoot` checks the signature of the new image, copies it to the primary slot and starts it.
|
||||
* **Security:** The new firmware must mark itself as "functional" after starting. If it does not do this (e.g. due to a crash), the previous, stable firmware version is automatically restored by `MCUBoot` on the next restart by the watchdog.
|
||||
|
||||
## 7. Safety and Robustness Concepts
|
||||
|
||||
* **Fail-Safe Behavior:** Each slave node implements a watchdog. If no valid MODBUS query is received from the gateway over a defined period of time (e.g. 15 seconds), the slave goes into a safe state: all valves are closed and relays (e.g. for the pump) are switched off.
|
||||
* **Electrical Protection Circuits:** All external interfaces are protected. The RS485 bus lines (`A`/`B`) are protected against overvoltages with TVS diodes on each board. Inputs and outputs receive basic ESD protection.
|
||||
* **Power Supply:** The 12V bus voltage is regulated on each slave node with an efficient `TPS5430DDAR` step-down converter to the required 3.3V for the microcontroller and the bus drivers.
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="203.36" height="143.44" version="1.1" viewBox="0 0 203.36 143.44">
|
||||
<g transform="translate(-2.88 -78.28)">
|
||||
<g stroke-width=".26458">
|
||||
<g fill="#fff" stroke="#000">
|
||||
<rect x="3.14" y="78.54" width="88.9" height="21.16" rx="2" ry="2"/>
|
||||
<rect x="3.14" y="105.4" width="88.9" height="21.16" rx="2" ry="2"/>
|
||||
<rect x="3.14" y="132.26" width="88.9" height="21.16" rx="2" ry="2"/>
|
||||
</g>
|
||||
<text x="47.59" y="86.9" font-family="sans-serif" font-size="5.64" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
|
||||
<tspan x="47.59" y="86.9" text-anchor="middle">Control Layer</tspan>
|
||||
<tspan x="47.59" y="93.45" text-anchor="middle">(Home Assistant)</tspan>
|
||||
</text>
|
||||
<text x="47.59" y="113.76" font-family="sans-serif" font-size="5.64" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
|
||||
<tspan x="47.59" y="113.76" text-anchor="middle">Gateway Layer</tspan>
|
||||
<tspan x="47.59" y="120.31" text-anchor="middle">(ESP32)</tspan>
|
||||
</text>
|
||||
<text x="47.59" y="140.62" font-family="sans-serif" font-size="5.64" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
|
||||
<tspan x="47.59" y="140.62" text-anchor="middle">Actor/Sensor Layer</tspan>
|
||||
<tspan x="47.59" y="147.17" text-anchor="middle">(Slaves)</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<path d="m47.59 99.7v5.7m-2.82-2.88h5.64" fill="none" stroke="#000" stroke-linecap="round" stroke-width="1.0583"/>
|
||||
<path d="m47.59 126.56v5.7m-2.82-2.88h5.64" fill="none" stroke="#000" stroke-linecap="round" stroke-width="1.0583"/>
|
||||
<g stroke-width=".26458">
|
||||
<g transform="translate(100.58 -2.64)">
|
||||
<g fill="#fff" stroke="#000">
|
||||
<rect x="3.14" y="108.04" width="88.9" height="21.16" rx="2" ry="2"/>
|
||||
<rect x="3.14" y="134.9" width="88.9" height="21.16" rx="2" ry="2"/>
|
||||
<rect x="3.14" y="161.76" width="88.9" height="21.16" rx="2" ry="2"/>
|
||||
<rect x="3.14" y="188.62" width="88.9" height="21.16" rx="2" ry="2"/>
|
||||
</g>
|
||||
<text x="47.59" y="118.94" font-family="sans-serif" font-size="5.64" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
|
||||
<tspan x="47.59" y="118.94" text-anchor="middle">Level Sensor</tspan>
|
||||
<tspan x="47.59" y="125.49" font-size="4.23" text-anchor="middle">(MODBUS Slave)</tspan>
|
||||
</text>
|
||||
<text x="47.59" y="145.8" font-family="sans-serif" font-size="5.64" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
|
||||
<tspan x="47.59" y="145.8" text-anchor="middle">Valve Control 1</tspan>
|
||||
<tspan x="47.59" y="152.35" font-size="4.23" text-anchor="middle">(MODBUS Slave)</tspan>
|
||||
</text>
|
||||
<text x="47.59" y="172.66" font-family="sans-serif" font-size="5.64" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
|
||||
<tspan x="47.59" y="172.66" text-anchor="middle">Valve Control n</tspan>
|
||||
<tspan x="47.59" y="179.21" font-size="4.23" text-anchor="middle">(MODBUS Slave)</tspan>
|
||||
</text>
|
||||
<text x="47.59" y="199.52" font-family="sans-serif" font-size="5.64" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
|
||||
<tspan x="47.59" y="199.52" text-anchor="middle">Pump</tspan>
|
||||
<tspan x="47.59" y="206.07" font-size="4.23" text-anchor="middle">(switched via Slave)</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<path d="m148.17 132.26v-18.52m-2.82 2.82 2.82-2.82 2.82 2.82" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width=".529"/>
|
||||
<path d="m148.17 159.12v-18.52m-2.82 2.82 2.82-2.82 2.82 2.82" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width=".529"/>
|
||||
<path d="m148.17 185.98v-18.52m-2.82 2.82 2.82-2.82 2.82 2.82" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width=".529"/>
|
||||
<path d="m148.17 212.84v-18.52m-2.82 2.82 2.82-2.82 2.82 2.82" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width=".529"/>
|
||||
</g>
|
||||
<g fill="none" stroke="#000" stroke-width=".52917">
|
||||
<path d="m92.04 89.12h10.58"/>
|
||||
<path d="m92.04 116h10.58"/>
|
||||
</g>
|
||||
<path d="m102.62 89.12v-5.29h45.55v26.45" fill="none" stroke="#000" stroke-width=".52917"/>
|
||||
<path d="m102.62 116h45.55v-23.8h-45.55z" fill="#fff" stroke="#000" stroke-width=".26458"/>
|
||||
<text x="125.4" y="100.3" font-family="sans-serif" font-size="4.23" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
|
||||
<tspan x="125.4" y="100.3" text-anchor="middle">Home Network</tspan>
|
||||
<tspan x="125.4" y="105.11" text-anchor="middle">(WLAN / Thread)</tspan>
|
||||
</text>
|
||||
<text x="125.4" y="114.09" font-family="sans-serif" font-size="4.23" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
|
||||
<tspan x="125.4" y="114.09" text-anchor="middle">MODBUS TCP/IP</tspan>
|
||||
</text>
|
||||
<path d="m102.62 142.84h45.55v-23.8h-45.55z" fill="#fff" stroke="#000" stroke-width=".26458"/>
|
||||
<text x="125.4" y="127.15" font-family="sans-serif" font-size="4.23" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
|
||||
<tspan x="125.4" y="127.15" text-anchor="middle">Gateway</tspan>
|
||||
<tspan x="125.4" y="131.96" text-anchor="middle">(Protocol Translator)</tspan>
|
||||
</text>
|
||||
<text x="125.4" y="140.94" font-family="sans-serif" font-size="4.23" letter-spacing="0" stroke-width=".26458" text-align="center" word-spacing="0">
|
||||
<tspan x="125.4" y="140.94" text-anchor="middle">MODBUS RTU</tspan>
|
||||
<tspan x="125.4" y="145.75" text-anchor="middle">(RS485 Bus)</tspan>
|
||||
</text>
|
||||
<path d="m92.04 142.84h10.58"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.5 KiB |
|
|
@ -1,85 +0,0 @@
|
|||
[🇩🇪 Deutsch](modbus-registers.de.md) | [🇬🇧 English](modbus-registers.en.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. |
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
[🇩🇪 Deutsch](planning.de.md) | [🇬🇧 English](planning.en.md)
|
||||
|
||||
# Projektplan: Modulares Bewässerungssystem
|
||||
|
||||
| Abgehakt | Aufgabe | Datum | Bemerkungen |
|
||||
| :---: | :--- | :--- | :--- |
|
||||
| ✅ | **Phase 0: Planung & Definition** | | |
|
||||
| ✅ | Konzept erstellen und finalisieren | 30.06.2025 | Architektur, Komponenten und grundlegende Architektur sind festgelegt. |
|
||||
| ✅ | MODBUS Register Map definieren | 30.06.2025 | Die "API" der Slaves ist definiert und bildet die Grundlage für die Software-Entwicklung. |
|
||||
| ☐ | **Phase 1: Slave-Node Prototyp (STM32 Eval-Board)** | | **Ziel:** Ein einzelner Slave wird auf dem Eval-Board zum Leben erweckt. |
|
||||
| ☐ | 1.1 Entwicklungsumgebung für STM32/Zephyr einrichten | | Toolchain, VS Code, Zephyr-SDK, MCUBoot etc. installieren und ein "Hello World" zum Laufen bringen. |
|
||||
| ☐ | 1.2 Basis-Firmware für Slave-Node erstellen | | Hardware-Abstraktion (GPIOs, ADC, UART für RS485) implementieren. |
|
||||
| ☐ | 1.3 MODBUS-RTU Stack auf dem Slave implementieren | | Basierend auf der definierten Register-Map. Zuerst nur lesende Funktionen (Status, Version). |
|
||||
| ☐ | 1.4 Kernlogik implementieren (z.B. Ventilsteuerung) | | Umsetzung der `VENTIL_ZUSTAND_BEWEGUNG` Logik, Strommessung für Endlagen etc. |
|
||||
| ☐ | **Phase 2: Verifikation der Slave-Firmware** | | **Ziel:** Nachweisen, dass der Slave sich exakt an die MODBUS-Spezifikation hält. |
|
||||
| ☐ | 2.1 Slave-Node mit PC via USB-MODBUS-Adapter testen | | **Kritischer Meilenstein.** Mit Tools wie "QModMaster" oder einem Python-Skript die Register lesen & schreiben. Die Slave-Firmware wird so unabhängig vom Gateway validiert. |
|
||||
| ☐ | 2.2 Firmware-Update Mechanismus testen | | Den kompletten Update-Prozess (Chunking, CRC-Check) mit einem Skript vom PC aus testen. Der Slave schreibt die Firmware dabei vorerst nur in einen ungenutzten RAM-Bereich. |
|
||||
| ☐ | **Phase 3: Hardware-Design und Prototypenbau** | | **Ziel:** Von der Entwicklung auf dem Eval-Board zum massgeschneiderten PCB. |
|
||||
| ☐ | 3.1 Schaltplan und PCB-Layout für Slave-Node entwerfen | | Basierend auf den Erfahrungen mit dem Eval-Board. |
|
||||
| ☐ | 3.2 Prototypen-Platinen bestellen und bestücken | | Z.B. bei JLCPCB. THT-Komponenten (Stecker etc.) selbst löten. |
|
||||
| ☐ | 3.3 Hardware-Inbetriebnahme des ersten Prototyps | | Spannungen prüfen, Firmware aufspielen und die Tests aus Phase 2 wiederholen, um die Hardware zu validieren. |
|
||||
| ☐ | 3.4 Flash-Schreibroutine für Firmware-Update implementieren | | Den in Schritt 2.2 im RAM validierten Prozess nun auf den echten Flash-Speicher anwenden. |
|
||||
| ☐ | **Phase 4: Gateway Entwicklung (ESP32 Eval-Board)** | | **Ziel:** Die Brücke von der RS485-Welt ins Heimnetzwerk bauen. |
|
||||
| ☐ | 4.1 Gateway-Firmware (ESPHome) erstellen | | Einfaches MODBUS TCP zu RTU Gateway auf dem ESP32C6 Eval-Board aufsetzen. |
|
||||
| ☐ | 4.2 Gateway mit Slave-Node Prototyp verbinden und testen | | Test der Kette: PC (als MODBUS TCP Client) -> WLAN -> Gateway -> RS485 -> Slave. |
|
||||
| ☐ | **Phase 5: System-Integration in Home Assistant** | | **Ziel:** Das System "smart" machen. |
|
||||
| ☐ | 5.1 MODBUS-Integration in Home Assistant konfigurieren | | Anlegen der Sensoren und Entitäten für den Slave-Node in der `configuration.yaml` oder über die UI. |
|
||||
| ☐ | 5.2 Dashboards und Automationen in HA erstellen | | Visualisierung der Zustände (Ventil, Pumpe etc.) und Erstellen der eigentlichen Bewässerungs-Logik. |
|
||||
| ☐ | 5.3 Python-Skript für Firmware-Update in HA entwickeln | | Implementierung des Chunk-basierten Uploads als Skript, das aus HA heraus aufgerufen werden kann. |
|
||||
| ☐ | **Phase 6: Aufbau und Inbetriebnahme** | | **Ziel:** Das fertige System installieren. |
|
||||
| ☐ | 6.1 Alle benötigten Slave-Nodes aufbauen und testen | | Jeden Slave einzeln mit dem PC via USB-Adapter testen und die MODBUS-Adresse konfigurieren. |
|
||||
| ☐ | 6.2 System final installieren und verkabeln | | Einbau der Komponenten in den Schuppen, Verkabelung des RS485-Busses. |
|
||||
| ☐ | 6.3 Gesamtsystemtest und Kalibrierung | | Füllstandsensor kalibrieren, Laufzeiten der Ventile prüfen, Fail-Safe-Verhalten testen. |
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
[🇩🇪 Deutsch](planning.de.md) | [🇬🇧 English](planning.en.md)
|
||||
|
||||
# Project Plan: Modular Irrigation System
|
||||
|
||||
| Done | Task | Date | Remarks |
|
||||
| :---: | :--- | :--- | :--- |
|
||||
| ✅ | **Phase 0: Planning & Definition** | | |
|
||||
| ✅ | Create and finalize concept | 2025-06-30 | Architecture, components and basic architecture are defined. |
|
||||
| ✅ | Define MODBUS Register Map | 2025-06-30 | The "API" of the slaves is defined and forms the basis for software development. |
|
||||
| ☐ | **Phase 1: Slave Node Prototype (STM32 Eval-Board)** | | **Goal:** A single slave is brought to life on the eval board. |
|
||||
| ☐ | 1.1 Set up development environment for STM32/Zephyr | | Install toolchain, VS Code, Zephyr-SDK, MCUBoot etc. and get a "Hello World" running. |
|
||||
| ☐ | 1.2 Create basic firmware for slave node | | Implement hardware abstraction (GPIOs, ADC, UART for RS485). |
|
||||
| ☐ | 1.3 Implement MODBUS-RTU stack on the slave | | Based on the defined register map. Initially only read functions (status, version). |
|
||||
| ☐ | 1.4 Implement core logic (e.g. valve control) | | Implementation of the `VALVE_STATE_MOVEMENT` logic, current measurement for end positions etc. |
|
||||
| ☐ | **Phase 2: Verification of the Slave Firmware** | | **Goal:** Prove that the slave adheres exactly to the MODBUS specification. |
|
||||
| ☐ | 2.1 Test slave node with PC via USB-MODBUS adapter | | **Critical milestone.** Read & write the registers with tools like "QModMaster" or a Python script. The slave firmware is thus validated independently of the gateway. |
|
||||
| ☐ | 2.2 Test firmware update mechanism | | Test the complete update process (chunking, CRC check) with a script from the PC. The slave initially only writes the firmware to an unused RAM area. |
|
||||
| ☐ | **Phase 3: Hardware Design and Prototype Construction** | | **Goal:** From development on the eval board to a customized PCB. |
|
||||
| ☐ | 3.1 Design schematic and PCB layout for slave node | | Based on the experience with the eval board. |
|
||||
| ☐ | 3.2 Order and assemble prototype boards | | E.g. at JLCPCB. Solder THT components (connectors etc.) yourself. |
|
||||
| ☐ | 3.3 Hardware commissioning of the first prototype | | Check voltages, upload firmware and repeat the tests from phase 2 to validate the hardware. |
|
||||
| ☐ | 3.4 Implement flash write routine for firmware update | | Apply the process validated in RAM in step 2.2 to the real flash memory. |
|
||||
| ☐ | **Phase 4: Gateway Development (ESP32 Eval-Board)** | | **Goal:** Build the bridge from the RS485 world to the home network. |
|
||||
| ☐ | 4.1 Create gateway firmware (ESPHome) | | Set up a simple MODBUS TCP to RTU gateway on the ESP32C6 eval board. |
|
||||
| ☐ | 4.2 Connect and test gateway with slave node prototype | | Test the chain: PC (as MODBUS TCP client) -> WLAN -> Gateway -> RS485 -> Slave. |
|
||||
| ☐ | **Phase 5: System Integration in Home Assistant** | | **Goal:** Make the system "smart". |
|
||||
| ☐ | 5.1 Configure MODBUS integration in Home Assistant | | Create the sensors and entities for the slave node in `configuration.yaml` or via the UI. |
|
||||
| ☐ | 5.2 Create dashboards and automations in HA | | Visualization of the states (valve, pump etc.) and creation of the actual irrigation logic. |
|
||||
| ☐ | 5.3 Develop Python script for firmware update in HA | | Implementation of the chunk-based upload as a script that can be called from HA. |
|
||||
| ☐ | **Phase 6: Setup and Commissioning** | | **Goal:** Install the finished system. |
|
||||
| ☐ | 6.1 Build and test all required slave nodes | | Test each slave individually with the PC via USB adapter and configure the MODBUS address. |
|
||||
| ☐ | 6.2 Final installation and cabling of the system | | Installation of the components in the shed, cabling of the RS485 bus. |
|
||||
| ☐ | 6.3 Overall system test and calibration | | Calibrate level sensor, check valve running times, test fail-safe behavior. |
|
||||
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
|
@ -1,6 +1,8 @@
|
|||
[🇩🇪 Deutsch](modbus-registers.de.md) | [🇬🇧 English](modbus-registers.en.md)
|
||||
Gerne, hier ist die finale Version der MODBUS-Register-Definition, die alle unsere Diskussionen und Verfeinerungen berücksichtigt, als kompletter Markdown-Block.
|
||||
|
||||
# MODBUS Register Map Definition v1.0
|
||||
Markdown
|
||||
|
||||
# MODBUS Register Map Definition v2.0
|
||||
|
||||
## 1. Einleitung
|
||||
|
||||
Loading…
Reference in New Issue