From e0007a9bd8a84f820bb4f0b0c4266c587334d2a5 Mon Sep 17 00:00:00 2001 From: Eduard Iten Date: Tue, 1 Jul 2025 18:02:59 +0200 Subject: [PATCH] feat(valve): Implement virtual valve control - Add Modbus registers for valve control according to the documentation. - Implement a virtual valve logic that simulates the opening and closing process. - The state of the valve can be read and controlled via Modbus. - This serves as a software-only placeholder until the hardware is ready. --- software/apps/slave_node/src/main.c | 58 ++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/software/apps/slave_node/src/main.c b/software/apps/slave_node/src/main.c index b8045e6..645c812 100644 --- a/software/apps/slave_node/src/main.c +++ b/software/apps/slave_node/src/main.c @@ -22,6 +22,8 @@ LOG_MODULE_REGISTER(mbs_sample, LOG_LEVEL_INF); #define APP_VERSION_PATCH 0 enum { + REG_INPUT_VALVE_STATE_MOVEMENT = 0x0000, + REG_INPUT_MOTOR_CURRENT_MA = 0x0001, REG_INPUT_FIRMWARE_VERSION_MAJOR_MINOR = 0x00F0, REG_INPUT_FIRMWARE_VERSION_PATCH = 0x00F1, REG_INPUT_DEVICE_STATUS = 0x00F2, @@ -30,10 +32,28 @@ enum { }; enum { - REG_HOLDING_WATCHDOG_TIMEOUT_S = 0x00F0, + REG_HOLDING_VALVE_COMMAND = 0x0000, + REG_HOLDING_MAX_OPENING_TIME_S = 0x0001, + REG_HOLDING_MAX_CLOSING_TIME_S = 0x0002, + REG_HOLDING_WATCHDOG_TIMEOUT_S = 0x00F0, }; +enum valve_state { + VALVE_STATE_CLOSED, + VALVE_STATE_OPEN, +}; +enum valve_movement { + VALVE_MOVEMENT_IDLE, + VALVE_MOVEMENT_OPENING, + VALVE_MOVEMENT_CLOSING, + VALVE_MOVEMENT_ERROR, +}; + +static enum valve_state current_state = VALVE_STATE_CLOSED; +static enum valve_movement current_movement = VALVE_MOVEMENT_IDLE; +static uint16_t max_opening_time_s = 60; +static uint16_t max_closing_time_s = 60; static uint16_t watchdog_timeout_s; static int modbus_iface; @@ -66,6 +86,12 @@ static int coil_wr(uint16_t addr, bool state) static int holding_reg_rd(uint16_t addr, uint16_t *reg) { switch (addr) { + case REG_HOLDING_MAX_OPENING_TIME_S: + *reg = max_opening_time_s; + break; + case REG_HOLDING_MAX_CLOSING_TIME_S: + *reg = max_closing_time_s; + break; case REG_HOLDING_WATCHDOG_TIMEOUT_S: *reg = watchdog_timeout_s; break; @@ -81,6 +107,28 @@ static int holding_reg_rd(uint16_t addr, uint16_t *reg) static int holding_reg_wr(uint16_t addr, uint16_t reg) { switch (addr) { + case REG_HOLDING_VALVE_COMMAND: + if (reg == 1) { /* Open */ + current_movement = VALVE_MOVEMENT_OPENING; + LOG_INF("Virtual valve opening..."); + current_state = VALVE_STATE_OPEN; + current_movement = VALVE_MOVEMENT_IDLE; + } else if (reg == 2) { /* Close */ + current_movement = VALVE_MOVEMENT_CLOSING; + LOG_INF("Virtual valve closing..."); + current_state = VALVE_STATE_CLOSED; + current_movement = VALVE_MOVEMENT_IDLE; + } else if (reg == 0) { /* Stop */ + current_movement = VALVE_MOVEMENT_IDLE; + LOG_INF("Virtual valve movement stopped"); + } + break; + case REG_HOLDING_MAX_OPENING_TIME_S: + max_opening_time_s = reg; + break; + case REG_HOLDING_MAX_CLOSING_TIME_S: + max_closing_time_s = reg; + break; case REG_HOLDING_WATCHDOG_TIMEOUT_S: watchdog_timeout_s = reg; break; @@ -97,6 +145,12 @@ static int input_reg_rd(uint16_t addr, uint16_t *reg) uint32_t uptime_s = k_uptime_get_32() / 1000; switch (addr) { + case REG_INPUT_VALVE_STATE_MOVEMENT: + *reg = (current_movement << 8) | (current_state & 0xFF); + break; + case REG_INPUT_MOTOR_CURRENT_MA: + *reg = 50; /* Dummy value */ + break; case REG_INPUT_FIRMWARE_VERSION_MAJOR_MINOR: *reg = (APP_VERSION_MAJOR << 8) | (APP_VERSION_MINOR & 0xFF); break; @@ -233,4 +287,4 @@ int main(void) } return 0; -} \ No newline at end of file +}