feat(valve): Make end-position current thresholds configurable

Introduces separate Modbus holding registers for configurable end-position
current thresholds for both opening and closing valve movements.

- Added REG_HOLDING_VALVE_END_CURRENT_THRESHOLD_OPEN_MA and
  REG_HOLDING_VALVE_END_CURRENT_THRESHOLD_CLOSE_MA to modbus_server.h.
- Modified valve.c to use these new thresholds and save/load them via settings.
- Added new setter functions to valve.h.
- Created new shell_valve library with commands to set/get these thresholds.
- Updated modbus_tool.py to include new menu options for setting thresholds.
- Updated docs/modbus-registers.de.md to document the new registers.

This enhances the flexibility and calibration of the valve control system.
This commit is contained in:
2025-07-10 23:42:41 +02:00
parent bd8a7a766c
commit 92bb171e85
10 changed files with 198 additions and 12 deletions

View File

@@ -2,4 +2,5 @@ add_subdirectory_ifdef(CONFIG_LIB_FWU fwu)
add_subdirectory_ifdef(CONFIG_LIB_MODBUS_SERVER modbus_server)
add_subdirectory_ifdef(CONFIG_LIB_VALVE valve)
add_subdirectory_ifdef(CONFIG_SHELL_SYSTEM shell_system)
add_subdirectory_ifdef(CONFIG_SHELL_MODBUS shell_modbus)
add_subdirectory_ifdef(CONFIG_SHELL_MODBUS shell_modbus)
add_subdirectory_ifdef(CONFIG_SHELL_VALVE shell_valve)

View File

@@ -0,0 +1 @@
zephyr_library()

View File

@@ -0,0 +1,6 @@
config SHELL_VALVE
bool "Shell Valve commands"
default y
depends on SHELL
help
Enable the shell commands for valve control.

View File

@@ -0,0 +1,115 @@
#include <zephyr/kernel.h>
#include <zephyr/shell/shell.h>
#include <lib/valve.h>
#include <stdlib.h>
static int cmd_valve_set_max_open_time(const struct shell *sh, size_t argc, char **argv)
{
if (argc != 2) {
shell_print(sh, "Usage: valve set_max_open_time <seconds>");
return -EINVAL;
}
uint16_t seconds = (uint16_t)atoi(argv[1]);
valve_set_max_open_time(seconds);
shell_print(sh, "Max open time set to %u seconds.", seconds);
return 0;
}
static int cmd_valve_get_max_open_time(const struct shell *sh, size_t argc, char **argv)
{
uint16_t seconds = valve_get_max_open_time();
shell_print(sh, "Max open time: %u seconds.", seconds);
return 0;
}
static int cmd_valve_set_max_close_time(const struct shell *sh, size_t argc, char **argv)
{
if (argc != 2) {
shell_print(sh, "Usage: valve set_max_close_time <seconds>");
return -EINVAL;
}
uint16_t seconds = (uint16_t)atoi(argv[1]);
valve_set_max_close_time(seconds);
shell_print(sh, "Max close time set to %u seconds.", seconds);
return 0;
}
static int cmd_valve_get_max_close_time(const struct shell *sh, size_t argc, char **argv)
{
uint16_t seconds = valve_get_max_close_time();
shell_print(sh, "Max close time: %u seconds.", seconds);
return 0;
}
static int cmd_valve_set_end_current_threshold_open(
const struct shell *sh, size_t argc, char **argv)
{
if (argc != 2) {
shell_print(sh, "Usage: valve set_end_current_threshold_open <milliamps>");
return -EINVAL;
}
uint16_t current_ma = (uint16_t)atoi(argv[1]);
valve_set_end_current_threshold_open(current_ma);
shell_print(sh, "End current threshold (open) set to %u mA.", current_ma);
return 0;
}
static int cmd_valve_get_end_current_threshold_open(
const struct shell *sh, size_t argc, char **argv)
{
uint16_t current_ma = valve_get_end_current_threshold_open();
shell_print(sh, "End current threshold (open): %u mA.", current_ma);
return 0;
}
static int cmd_valve_set_end_current_threshold_close(
const struct shell *sh, size_t argc, char **argv)
{
if (argc != 2) {
shell_print(sh, "Usage: valve set_end_current_threshold_close <milliamps>");
return -EINVAL;
}
uint16_t current_ma = (uint16_t)atoi(argv[1]);
valve_set_end_current_threshold_close(current_ma);
shell_print(sh, "End current threshold (close) set to %u mA.", current_ma);
return 0;
}
static int cmd_valve_get_end_current_threshold_close(
const struct shell *sh, size_t argc, char **argv)
{
uint16_t current_ma = valve_get_end_current_threshold_close();
shell_print(sh, "End current threshold (close): %u mA.", current_ma);
return 0;
}
SHELL_STATIC_SUBCMD_SET_CREATE(sub_valve_settings,
SHELL_CMD(set_max_open_time, NULL, "Set max open time (seconds)", cmd_valve_set_max_open_time),
SHELL_CMD(get_max_open_time, NULL, "Get max open time (seconds)", cmd_valve_get_max_open_time),
SHELL_CMD(
set_max_close_time, NULL, "Set max close time (seconds)", cmd_valve_set_max_close_time),
SHELL_CMD(
get_max_close_time, NULL, "Get max close time (seconds)", cmd_valve_get_max_close_time),
SHELL_CMD(set_end_current_threshold_open,
NULL,
"Set end current threshold for opening (mA)",
cmd_valve_set_end_current_threshold_open),
SHELL_CMD(get_end_current_threshold_open,
NULL,
"Get end current threshold for opening (mA)",
cmd_valve_get_end_current_threshold_open),
SHELL_CMD(set_end_current_threshold_close,
NULL,
"Set end current threshold for closing (mA)",
cmd_valve_set_end_current_threshold_close),
SHELL_CMD(get_end_current_threshold_close,
NULL,
"Get end current threshold for closing (mA)",
cmd_valve_get_end_current_threshold_close),
SHELL_SUBCMD_SET_END);
SHELL_CMD_REGISTER(valve, &sub_valve_settings, "Valve commands", NULL);

View File

@@ -27,6 +27,8 @@ static enum valve_state current_state = VALVE_STATE_OPEN;
static enum valve_movement current_movement = VALVE_MOVEMENT_IDLE;
static uint16_t max_opening_time_s = 10;
static uint16_t max_closing_time_s = 10;
static uint16_t end_current_threshold_open_ma = 10; // Default value for open
static uint16_t end_current_threshold_close_ma = 10; // Default value for close
static struct k_work_delayable valve_work; // Work item for scheduling valve movement timeouts
static struct k_timer movement_timer;
@@ -45,14 +47,14 @@ static void valve_work_handler(struct k_work *work)
if (current_movement == VALVE_MOVEMENT_OPENING) {
vnd7050aj_read_load_current(vnd7050aj_dev, VALVE_CHANNEL_OPEN, &current_ma);
if (current_ma > 10) {
if (current_ma > end_current_threshold_open_ma) {
k_work_schedule(&valve_work, VALVE_ENDPOSITION_CHECK_INTERVAL);
return;
}
LOG_INF("Valve finished opening");
} else if (current_movement == VALVE_MOVEMENT_CLOSING) {
vnd7050aj_read_load_current(vnd7050aj_dev, VALVE_CHANNEL_CLOSE, &current_ma);
if (current_ma > 10) {
if (current_ma > end_current_threshold_close_ma) {
k_work_schedule(&valve_work, VALVE_ENDPOSITION_CHECK_INTERVAL);
return;
}
@@ -96,10 +98,19 @@ int valve_init(void)
settings_load_one("valve/max_open_time", &max_opening_time_s, sizeof(max_opening_time_s));
settings_load_one("valve/max_close_time", &max_closing_time_s, sizeof(max_closing_time_s));
settings_load_one("valve/end_current_threshold_open",
&end_current_threshold_open_ma,
sizeof(end_current_threshold_open_ma));
settings_load_one("valve/end_current_threshold_close",
&end_current_threshold_close_ma,
sizeof(end_current_threshold_close_ma));
LOG_INF("Valve initialized: max_open=%us, max_close=%us",
LOG_INF("Valve initialized: max_open=%us, max_close=%us, end_curr_open=%umA, "
"end_curr_close=%umA",
max_opening_time_s,
max_closing_time_s);
max_closing_time_s,
end_current_threshold_open_ma,
end_current_threshold_close_ma);
valve_close();
return 0;
}
@@ -158,6 +169,23 @@ void valve_set_max_close_time(uint16_t seconds)
max_closing_time_s = seconds;
settings_save_one("valve/max_close_time", &max_closing_time_s, sizeof(max_closing_time_s));
}
void valve_set_end_current_threshold_open(uint16_t current_ma)
{
end_current_threshold_open_ma = current_ma;
settings_save_one("valve/end_current_threshold_open",
&end_current_threshold_open_ma,
sizeof(end_current_threshold_open_ma));
}
void valve_set_end_current_threshold_close(uint16_t current_ma)
{
end_current_threshold_close_ma = current_ma;
settings_save_one("valve/end_current_threshold_close",
&end_current_threshold_close_ma,
sizeof(end_current_threshold_close_ma));
}
uint16_t valve_get_max_open_time(void)
{
return max_opening_time_s;