Add run limit feature for relay channels with NVS support
- Introduced configuration options for enabling run limits in Kconfig. - Added APIs to get and set run limits for individual relay channels. - Implemented run limit timer functionality to automatically stop channels. - Updated NVS handling to store and retrieve run limit values. - Enhanced documentation in README and code comments to reflect new feature. Closes #1080
This commit is contained in:
32
Kconfig
32
Kconfig
@@ -17,6 +17,12 @@ menu "Relay Channel Driver Configuration"
|
||||
help
|
||||
Number of relay channels between 1 and 8.
|
||||
|
||||
config RELAY_CHN_ENABLE_RUN_LIMIT
|
||||
bool "Enable run limit for channels"
|
||||
default n
|
||||
help
|
||||
Enable run limit for channels as an extra layer of output protection.
|
||||
|
||||
config RELAY_CHN_ENABLE_TILTING
|
||||
bool "Enable tilting on relay channels"
|
||||
default n
|
||||
@@ -61,4 +67,30 @@ menu "Relay Channel NVS Storage Configuration"
|
||||
The name of the custom NVS partition used for storing relay channel
|
||||
configuration. Make sure the name is exactly the same as label defined
|
||||
in the relevant partition table.
|
||||
endmenu
|
||||
|
||||
menu "Relay Channel Run Limit Configuration"
|
||||
depends on RELAY_CHN_ENABLE_RUN_LIMIT
|
||||
|
||||
config RELAY_CHN_RUN_LIMIT_MIN_SEC
|
||||
int "Minimum run limit in seconds"
|
||||
range 1 60
|
||||
default 10
|
||||
help
|
||||
Minimum run limit in seconds for channels.
|
||||
|
||||
config RELAY_CHN_RUN_LIMIT_MAX_SEC
|
||||
int "Maximum run limit in seconds"
|
||||
range 60 3600
|
||||
default 600
|
||||
help
|
||||
Maximum run limit in seconds for channels.
|
||||
|
||||
config RELAY_CHN_RUN_LIMIT_DEFAULT_SEC
|
||||
int "Default run limit in seconds"
|
||||
range 10 3600
|
||||
default 60
|
||||
help
|
||||
Default run limit in seconds for channels.
|
||||
|
||||
endmenu
|
||||
43
README.md
43
README.md
@@ -13,17 +13,21 @@ An ESP-IDF component for controlling relay channels, specifically designed for d
|
||||
- State monitoring and reporting
|
||||
- Optional sensitivty adjustable tilting feature
|
||||
- Optional NVS storage for persistent configuration
|
||||
- Optional configurable run limit protection
|
||||
|
||||
## Description
|
||||
|
||||
Each relay channel consists of 2 output relays controlled by 2 GPIO pins. The component provides APIs to control these relay pairs while ensuring safe operation, particularly for driving bipolar motors. To prevent mechanical strain on the motor, the component automatically manages direction changes with a configurable inertia delay, protecting it from abrupt reversals. Hence, the component handles all the required timing between the movement transitions automatically to ensure reliable operation.
|
||||
|
||||
The run limit feature provides an additional layer of protection by automatically stopping channels after a configurable time period. This is particularly useful for motor-driven applications where continuous operation beyond a certain duration could cause damage or safety issues. Each channel can have its own run limit setting, and when enabled, the component will automatically stop the channel once it has been running for the specified duration.
|
||||
|
||||
It also provides an optional tilting interface per channel base. Tilting makes a channel move with a specific pattern moving with small steps at a time. Tilting is specifically designed for controlling some types of curtains that need to be adjusted to let enter specific amount of day light.
|
||||
Since it operates on relays, the switching frequency is limited to 10Hz which complies with the most of the general purpose relays' requirements. The minimum frequency is 2Hz and the duty cycle is about 10% in all ranges.
|
||||
|
||||
Another optional feature is NVS storage, which saves the configuration permanently across reboots of the device. These configurations are:
|
||||
|
||||
- Direction
|
||||
- Run limit duration
|
||||
- Tilt sensitivity
|
||||
- Last tilt position
|
||||
|
||||
@@ -33,9 +37,16 @@ Configure the component through menuconfig under "Relay Channel Driver Configura
|
||||
|
||||
- `CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS`: Time to wait before changing direction (200-1500ms, default: 800ms)
|
||||
- `CONFIG_RELAY_CHN_COUNT`: Number of relay channels (1-8, default: 1)
|
||||
- `CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT`: Enable run limit protection (default: n)
|
||||
- `CONFIG_RELAY_CHN_ENABLE_TILTING`: Enable tilting interface on all channels. (default: n)
|
||||
- `CONFIG_RELAY_CHN_ENABLE_NVS`: Enable persistent storage in NVS (default: n)
|
||||
|
||||
When run limit is enabled (`CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT`), the following configuration options become available:
|
||||
|
||||
- `CONFIG_RELAY_CHN_RUN_LIMIT_MIN_SEC`: Minimum allowed run limit duration (1-60s, default: 10s)
|
||||
- `CONFIG_RELAY_CHN_RUN_LIMIT_MAX_SEC`: Maximum allowed run limit duration (60-3600s, default: 600s)
|
||||
- `CONFIG_RELAY_CHN_RUN_LIMIT_DEFAULT_SEC`: Default run limit duration for channels (10-3600s, default: 60s)
|
||||
|
||||
When NVS storage is enabled (`CONFIG_RELAY_CHN_ENABLE_NVS`), additional configuration options become available:
|
||||
|
||||
- `CONFIG_RELAY_CHN_NVS_NAMESPACE`: NVS namespace for storing relay channel data (default: "relay_chn")
|
||||
@@ -225,7 +236,37 @@ relay_chn_direction_t direction = relay_chn_get_direction(0);
|
||||
/* The listener is same for multi mode */
|
||||
```
|
||||
|
||||
### 4. Tilting Interface (if enabled)
|
||||
### 4. Run Limit Control (if enabled)
|
||||
|
||||
For single mode:
|
||||
|
||||
```c
|
||||
// Assuming CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT is enabled
|
||||
|
||||
// Get current run limit (in seconds)
|
||||
uint16_t limit = relay_chn_get_run_limit();
|
||||
|
||||
// Set new run limit (in seconds)
|
||||
relay_chn_set_run_limit(120); // Set to 120 seconds
|
||||
```
|
||||
|
||||
For multi mode:
|
||||
|
||||
```c
|
||||
// Assuming CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT is enabled
|
||||
|
||||
// Get run limit for channel #0 (in seconds)
|
||||
uint16_t limit = relay_chn_get_run_limit(0);
|
||||
|
||||
// Set new run limit for specific channels (in seconds)
|
||||
relay_chn_set_run_limit(0, 120); // Set channel #0 to 120 seconds
|
||||
relay_chn_set_run_limit(1, 180); // Set channel #1 to 180 seconds
|
||||
relay_chn_set_run_limit(RELAY_CHN_ID_ALL, 90); // Set all channels to 90 seconds
|
||||
```
|
||||
> [!NOTE]
|
||||
> When a channel reaches its run limit, it will automatically stop. The run limit timer is reset whenever the channel starts running in either direction.
|
||||
|
||||
### 5. Tilting Interface (if enabled)
|
||||
|
||||
For single mode:
|
||||
|
||||
|
||||
@@ -146,6 +146,33 @@ void relay_chn_flip_direction(uint8_t chn_id);
|
||||
*/
|
||||
relay_chn_direction_t relay_chn_get_direction(uint8_t chn_id);
|
||||
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
/**
|
||||
* @brief Get the run limit for the specified channel
|
||||
*
|
||||
* @param chn_id The ID of the relay channel to query.
|
||||
*
|
||||
* @return The run limit value for the relevant channel if the channel ID is valid.
|
||||
* 0 if the channel ID is invalid.
|
||||
*/
|
||||
uint16_t relay_chn_get_run_limit(uint8_t chn_id);
|
||||
|
||||
/**
|
||||
* @brief Set the run limit for the specified channel
|
||||
*
|
||||
* Sets the time limit in seconds for the specified channel. It will not proceed
|
||||
* if the channel ID is invalid.
|
||||
* If the time_sec value is lesser than the CONFIG_RELAY_CHN_RUN_LIMIT_MIN_SEC,
|
||||
* the value will be set to CONFIG_RELAY_CHN_RUN_LIMIT_MIN_SEC.
|
||||
* If the time_sec value is greater than the CONFIG_RELAY_CHN_RUN_LIMIT_MAX_SEC,
|
||||
* the value will be set to CONFIG_RELAY_CHN_RUN_LIMIT_MAX_SEC.
|
||||
*
|
||||
* @param chn_id The ID of the relay channel to query.
|
||||
* @param time_sec The run limit time in seconds.
|
||||
*/
|
||||
void relay_chn_set_run_limit(uint8_t chn_id, uint16_t time_sec);
|
||||
#endif // RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
|
||||
|
||||
#if CONFIG_RELAY_CHN_ENABLE_TILTING == 1
|
||||
|
||||
@@ -275,6 +302,29 @@ void relay_chn_flip_direction(void);
|
||||
*/
|
||||
relay_chn_direction_t relay_chn_get_direction(void);
|
||||
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
/**
|
||||
* @brief Get the run limit for the channel
|
||||
*
|
||||
* @return The run limit value for the channel.
|
||||
*/
|
||||
uint16_t relay_chn_get_run_limit(void);
|
||||
|
||||
/**
|
||||
* @brief Set the run limit for the channel
|
||||
*
|
||||
* Sets the time limit in seconds for the channel. It will not proceed
|
||||
* if the channel ID is invalid.
|
||||
* If the time_sec value is lesser than the CONFIG_RELAY_CHN_RUN_LIMIT_MIN_SEC,
|
||||
* the value will be set to CONFIG_RELAY_CHN_RUN_LIMIT_MIN_SEC.
|
||||
* If the time_sec value is greater than the CONFIG_RELAY_CHN_RUN_LIMIT_MAX_SEC,
|
||||
* the value will be set to CONFIG_RELAY_CHN_RUN_LIMIT_MAX_SEC.
|
||||
*
|
||||
* @param time_sec The run limit time in seconds.
|
||||
*/
|
||||
void relay_chn_set_run_limit(uint16_t time_sec);
|
||||
#endif // RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
|
||||
|
||||
#if CONFIG_RELAY_CHN_ENABLE_TILTING == 1
|
||||
|
||||
|
||||
@@ -101,6 +101,36 @@ static inline relay_chn_direction_t relay_chn_get_direction(uint8_t chn_id)
|
||||
return relay_chn_ctl_get_direction(chn_id);
|
||||
}
|
||||
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
/**
|
||||
* @brief Get the run limit for the specified channel
|
||||
*
|
||||
* @param chn_id The ID of the relay channel to query.
|
||||
*
|
||||
* @return The run limit value for the relevant channel if the channel ID is valid.
|
||||
* 0 if the channel ID is invalid.
|
||||
*/
|
||||
extern uint16_t relay_chn_ctl_get_run_limit(uint8_t chn_id);
|
||||
|
||||
/**
|
||||
* @brief Set the run limit for the specified channel
|
||||
*
|
||||
* @param chn_id The ID of the relay channel to query.
|
||||
* @param time_sec The run limit time in seconds.
|
||||
*/
|
||||
extern void relay_chn_ctl_set_run_limit(uint8_t chn_id, uint16_t time_sec);
|
||||
|
||||
static inline uint16_t relay_chn_get_run_limit(uint8_t chn_id)
|
||||
{
|
||||
return relay_chn_ctl_get_run_limit(chn_id);
|
||||
}
|
||||
|
||||
static inline void relay_chn_set_run_limit(uint8_t chn_id, uint16_t time_sec)
|
||||
{
|
||||
relay_chn_ctl_set_run_limit(chn_id, time_sec);
|
||||
}
|
||||
#endif // RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
|
||||
#else
|
||||
|
||||
/**
|
||||
@@ -179,6 +209,32 @@ static inline relay_chn_direction_t relay_chn_get_direction(void)
|
||||
return relay_chn_ctl_get_direction();
|
||||
}
|
||||
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
/**
|
||||
* @brief Get the run limit for the channel
|
||||
*
|
||||
* @return The run limit value for the channel.
|
||||
*/
|
||||
extern uint16_t relay_chn_ctl_get_run_limit(void);
|
||||
|
||||
/**
|
||||
* @brief Set the run limit for the channel
|
||||
*
|
||||
* @param time_sec The run limit time in seconds.
|
||||
*/
|
||||
extern void relay_chn_ctl_set_run_limit(uint16_t time_sec);
|
||||
|
||||
static inline uint16_t relay_chn_get_run_limit(void)
|
||||
{
|
||||
return relay_chn_ctl_get_run_limit();
|
||||
}
|
||||
|
||||
static inline void relay_chn_set_run_limit(uint16_t time_sec)
|
||||
{
|
||||
relay_chn_ctl_set_run_limit(time_sec);
|
||||
}
|
||||
#endif // RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
|
||||
#endif // RELAY_CHN_COUNT > 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -15,6 +15,7 @@ extern "C" {
|
||||
#define RELAY_CHN_COUNT CONFIG_RELAY_CHN_COUNT
|
||||
#define RELAY_CHN_ENABLE_TILTING CONFIG_RELAY_CHN_ENABLE_TILTING
|
||||
#define RELAY_CHN_ENABLE_NVS CONFIG_RELAY_CHN_ENABLE_NVS
|
||||
#define RELAY_CHN_ENABLE_RUN_LIMIT CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT
|
||||
|
||||
#if RELAY_CHN_ENABLE_NVS == 1
|
||||
#define RELAY_CHN_NVS_NAMESPACE CONFIG_RELAY_CHN_NVS_NAMESPACE
|
||||
@@ -28,6 +29,12 @@ extern "C" {
|
||||
#define RELAY_CHN_ID_ALL RELAY_CHN_COUNT /*!< Special ID to address all channels */
|
||||
#endif
|
||||
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
#define RELAY_CHN_RUN_LIMIT_MIN_SEC CONFIG_RELAY_CHN_RUN_LIMIT_MIN_SEC
|
||||
#define RELAY_CHN_RUN_LIMIT_MAX_SEC CONFIG_RELAY_CHN_RUN_LIMIT_MAX_SEC
|
||||
#define RELAY_CHN_RUN_LIMIT_DEFAULT_SEC CONFIG_RELAY_CHN_RUN_LIMIT_DEFAULT_SEC
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -33,6 +33,20 @@ ESP_EVENT_DECLARE_BASE(RELAY_CHN_CMD_EVENT);
|
||||
*/
|
||||
esp_err_t relay_chn_init_timer(relay_chn_ctl_t *chn_ctl);
|
||||
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
/**
|
||||
* @brief Initializes the relay channel run limit timer.
|
||||
*
|
||||
* This function creates a timer for the relay channel to handle run time limit.
|
||||
* Required by *_ctl_* module.
|
||||
*
|
||||
* @param chn_ctl Pointer to the relay channel control structure.
|
||||
*
|
||||
* @return esp_err_t ESP_OK on success, or an error code on failure.
|
||||
*/
|
||||
esp_err_t relay_chn_init_run_limit_timer(relay_chn_ctl_t *chn_ctl);
|
||||
#endif // RELAY_CHN_ENABLE_RUN_LIMIT
|
||||
|
||||
/**
|
||||
* @brief Issues a command to the relay channel.
|
||||
*
|
||||
|
||||
@@ -45,6 +45,26 @@ esp_err_t relay_chn_nvs_set_direction(uint8_t ch, relay_chn_direction_t directio
|
||||
*/
|
||||
esp_err_t relay_chn_nvs_get_direction(uint8_t ch, relay_chn_direction_t *direction);
|
||||
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
/**
|
||||
* @brief Store relay channel run limit in NVS.
|
||||
*
|
||||
* @param[in] ch Channel number.
|
||||
* @param[in] direction Run limit value to store.
|
||||
* @return ESP_OK on success, error code otherwise.
|
||||
*/
|
||||
esp_err_t relay_chn_nvs_set_run_limit(uint8_t ch, uint16_t time_sec);
|
||||
|
||||
/**
|
||||
* @brief Retrieve relay channel run limit from NVS.
|
||||
*
|
||||
* @param[in] ch Channel number.
|
||||
* @param[out] direction Pointer to store retrieved run limit value.
|
||||
* @return ESP_OK on success, error code otherwise.
|
||||
*/
|
||||
esp_err_t relay_chn_nvs_get_run_limit(uint8_t ch, uint16_t *time_sec);
|
||||
#endif // RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
|
||||
#ifdef RELAY_CHN_ENABLE_TILTING
|
||||
/**
|
||||
* @brief Store tilt sensitivity in NVS.
|
||||
|
||||
@@ -68,6 +68,10 @@ typedef struct {
|
||||
relay_chn_output_t *output; /*!< Output configuration of the relay channel */
|
||||
relay_chn_cmd_t pending_cmd; /*!< The command that is pending to be issued */
|
||||
esp_timer_handle_t inertia_timer; /*!< Timer to handle the opposite direction inertia time */
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
esp_timer_handle_t run_limit_timer; /*!< Timer to handle the run limit */
|
||||
uint16_t run_limit_sec; /*!< Run limit in seconds */
|
||||
#endif
|
||||
#if RELAY_CHN_ENABLE_TILTING == 1
|
||||
relay_chn_tilt_ctl_t *tilt_ctl; /*!< Pointer to the tilt control structure if tilting is enabled */
|
||||
#endif
|
||||
|
||||
@@ -10,7 +10,7 @@ if [[ -z "$IDF_PATH" ]]; then
|
||||
fi
|
||||
|
||||
# ==== 2. Valid Modes and Defaults ====
|
||||
valid_test_tags=("core" "tilt" "listener" "all" "relay_chn" "nvs")
|
||||
valid_test_tags=("core" "tilt" "listener" "all" "relay_chn" "nvs" "run_limit")
|
||||
arg_tag="all" # Default to 'all' if no tag specified
|
||||
arg_clean=false
|
||||
arg_log=false
|
||||
@@ -24,7 +24,7 @@ print_help() {
|
||||
echo "This script builds and runs tests for the relay_chn component using QEMU."
|
||||
echo ""
|
||||
echo "Arguments:"
|
||||
echo " -t, --tag [relay_chn|core|tilt|listener|nvs|all] Specify which test tag to run."
|
||||
echo " -t, --tag [relay_chn|core|tilt|listener|nvs|run_limit|all] Specify which test tag to run."
|
||||
echo ""
|
||||
echo " If no tag is specified, it defaults to 'all'."
|
||||
echo ""
|
||||
|
||||
@@ -46,6 +46,30 @@ esp_event_loop_handle_t relay_chn_event_loop = NULL;
|
||||
static void relay_chn_event_handler(void* handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
|
||||
|
||||
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
/*
|
||||
* Run limit timer callback immediately dispatches a STOP command for the
|
||||
* relevant channel as soon as the run limit time times out
|
||||
*/
|
||||
static void relay_chn_run_limit_timer_cb(void* arg)
|
||||
{
|
||||
relay_chn_ctl_t* chn_ctl = (relay_chn_ctl_t*) arg;
|
||||
relay_chn_dispatch_cmd(chn_ctl, RELAY_CHN_CMD_STOP);
|
||||
}
|
||||
|
||||
esp_err_t relay_chn_init_run_limit_timer(relay_chn_ctl_t *chn_ctl)
|
||||
{
|
||||
char timer_name[32];
|
||||
snprintf(timer_name, sizeof(timer_name), "ch_%d_rlimit_timer", chn_ctl->id);
|
||||
esp_timer_create_args_t timer_args = {
|
||||
.callback = relay_chn_run_limit_timer_cb,
|
||||
.arg = chn_ctl,
|
||||
.name = timer_name
|
||||
};
|
||||
return esp_timer_create(&timer_args, &chn_ctl->run_limit_timer);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Timer callback function for relay channel direction change inertia.
|
||||
static void relay_chn_timer_cb(void* arg)
|
||||
{
|
||||
@@ -467,6 +491,10 @@ static void relay_chn_execute_stop(relay_chn_ctl_t *chn_ctl)
|
||||
// Invalidate the channel's timer if it is active
|
||||
esp_timer_stop(chn_ctl->inertia_timer);
|
||||
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
esp_timer_stop(chn_ctl->run_limit_timer);
|
||||
#endif
|
||||
|
||||
// Save the last run time only if the previous state was either STATE FORWARD
|
||||
// or STATE_REVERSE. Then schedule a free command.
|
||||
if (previous_state == RELAY_CHN_STATE_FORWARD || previous_state == RELAY_CHN_STATE_REVERSE) {
|
||||
@@ -489,6 +517,10 @@ static void relay_chn_execute_forward(relay_chn_ctl_t *chn_ctl)
|
||||
}
|
||||
relay_chn_run_info_set_last_run_cmd(chn_ctl->run_info, RELAY_CHN_CMD_FORWARD);
|
||||
relay_chn_update_state(chn_ctl, RELAY_CHN_STATE_FORWARD);
|
||||
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
relay_chn_start_esp_timer_once(chn_ctl->run_limit_timer, chn_ctl->run_limit_sec * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void relay_chn_execute_reverse(relay_chn_ctl_t *chn_ctl)
|
||||
@@ -499,6 +531,10 @@ static void relay_chn_execute_reverse(relay_chn_ctl_t *chn_ctl)
|
||||
}
|
||||
relay_chn_run_info_set_last_run_cmd(chn_ctl->run_info, RELAY_CHN_CMD_REVERSE);
|
||||
relay_chn_update_state(chn_ctl, RELAY_CHN_STATE_REVERSE);
|
||||
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
relay_chn_start_esp_timer_once(chn_ctl->run_limit_timer, chn_ctl->run_limit_sec * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void relay_chn_execute_flip(relay_chn_ctl_t *chn_ctl)
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
#include "relay_chn_ctl.h"
|
||||
#include "relay_chn_output.h"
|
||||
|
||||
#if RELAY_CHN_ENABLE_NVS == 1
|
||||
#include "relay_chn_nvs.h"
|
||||
#endif
|
||||
|
||||
static const char *TAG = "RELAY_CHN_CTL";
|
||||
|
||||
static relay_chn_ctl_t chn_ctls[RELAY_CHN_COUNT];
|
||||
@@ -30,6 +34,19 @@ esp_err_t relay_chn_ctl_init(relay_chn_output_t *outputs, relay_chn_run_info_t *
|
||||
|
||||
chn_ctl->output = output;
|
||||
chn_ctl->run_info = run_info;
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
uint16_t run_limit_sec = RELAY_CHN_RUN_LIMIT_DEFAULT_SEC;
|
||||
#if RELAY_CHN_ENABLE_NVS == 1
|
||||
// Load run limit value from NVS
|
||||
ret = relay_chn_nvs_get_run_limit(chn_ctl->id, &run_limit_sec);
|
||||
if (ret != ESP_OK && ret != ESP_ERR_NVS_NOT_FOUND) {
|
||||
ESP_LOGE(TAG, "Failed to load run limit from NVS for channel %d with error: %s", i, esp_err_to_name(ret));
|
||||
}
|
||||
#endif
|
||||
chn_ctl->run_limit_sec = run_limit_sec;
|
||||
ret = relay_chn_init_run_limit_timer(chn_ctl);
|
||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize run limit timer");
|
||||
#endif
|
||||
ret = relay_chn_init_timer(chn_ctl); // Create direction change inertia timer
|
||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to create relay channel timer for channel %d", i);
|
||||
}
|
||||
@@ -44,6 +61,12 @@ void relay_chn_ctl_deinit()
|
||||
esp_timer_delete(chn_ctl->inertia_timer);
|
||||
chn_ctl->inertia_timer = NULL;
|
||||
}
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
if (chn_ctl->run_limit_timer != NULL) {
|
||||
esp_timer_delete(chn_ctl->run_limit_timer);
|
||||
chn_ctl->run_limit_timer = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +146,37 @@ relay_chn_direction_t relay_chn_ctl_get_direction(uint8_t chn_id)
|
||||
return relay_chn_output_get_direction(chn_ctl->output);
|
||||
}
|
||||
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
uint16_t relay_chn_ctl_get_run_limit(uint8_t chn_id)
|
||||
{
|
||||
if (!relay_chn_is_channel_id_valid(chn_id) || chn_id == RELAY_CHN_ID_ALL) {
|
||||
ESP_LOGE(TAG, "get_run_limit: Invalid channel ID: %d", chn_id);
|
||||
return 0;
|
||||
}
|
||||
return chn_ctls[chn_id].run_limit_sec;
|
||||
}
|
||||
|
||||
void relay_chn_ctl_set_run_limit(uint8_t chn_id, uint16_t time_sec)
|
||||
{
|
||||
if (!relay_chn_is_channel_id_valid(chn_id) || chn_id == RELAY_CHN_ID_ALL) {
|
||||
ESP_LOGE(TAG, "set_run_limit: Invalid channel ID: %d", chn_id);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for boundaries
|
||||
if (time_sec > RELAY_CHN_RUN_LIMIT_MAX_SEC)
|
||||
time_sec = RELAY_CHN_RUN_LIMIT_MAX_SEC;
|
||||
else if (time_sec < RELAY_CHN_RUN_LIMIT_MIN_SEC)
|
||||
time_sec = RELAY_CHN_RUN_LIMIT_MIN_SEC;
|
||||
|
||||
chn_ctls[chn_id].run_limit_sec = time_sec;
|
||||
|
||||
#if RELAY_CHN_ENABLE_NVS == 1
|
||||
relay_chn_nvs_set_run_limit(chn_id, time_sec);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
relay_chn_ctl_t *relay_chn_ctl_get(uint8_t chn_id)
|
||||
{
|
||||
if (!relay_chn_is_channel_id_valid(chn_id)) {
|
||||
|
||||
@@ -4,11 +4,17 @@
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "esp_check.h"
|
||||
#include "relay_chn_priv_types.h"
|
||||
#include "relay_chn_core.h"
|
||||
#include "relay_chn_ctl.h"
|
||||
#include "relay_chn_output.h"
|
||||
|
||||
#if RELAY_CHN_ENABLE_NVS == 1
|
||||
#include "relay_chn_nvs.h"
|
||||
#endif
|
||||
|
||||
static const char *TAG = "RELAY_CHN_CTL";
|
||||
|
||||
static relay_chn_ctl_t chn_ctl;
|
||||
|
||||
@@ -21,6 +27,20 @@ esp_err_t relay_chn_ctl_init(relay_chn_output_t *output, relay_chn_run_info_t *r
|
||||
chn_ctl.pending_cmd = RELAY_CHN_CMD_NONE;
|
||||
chn_ctl.output = output;
|
||||
chn_ctl.run_info = run_info;
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
uint16_t run_limit_sec = RELAY_CHN_RUN_LIMIT_DEFAULT_SEC;
|
||||
esp_err_t ret;
|
||||
#if RELAY_CHN_ENABLE_NVS == 1
|
||||
// Load run limit value from NVS
|
||||
ret = relay_chn_nvs_get_run_limit(chn_ctl.id, &run_limit_sec);
|
||||
if (ret != ESP_OK && ret != ESP_ERR_NVS_NOT_FOUND) {
|
||||
ESP_LOGE(TAG, "Failed to load run limit from NVS with error: %s", esp_err_to_name(ret));
|
||||
}
|
||||
#endif
|
||||
chn_ctl.run_limit_sec = run_limit_sec;
|
||||
ret = relay_chn_init_run_limit_timer(&chn_ctl);
|
||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize run limit timer");
|
||||
#endif
|
||||
return relay_chn_init_timer(&chn_ctl); // Create direction change inertia timer
|
||||
}
|
||||
|
||||
@@ -31,6 +51,12 @@ void relay_chn_ctl_deinit()
|
||||
esp_timer_delete(chn_ctl.inertia_timer);
|
||||
chn_ctl.inertia_timer = NULL;
|
||||
}
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
if (chn_ctl.run_limit_timer != NULL) {
|
||||
esp_timer_delete(chn_ctl.run_limit_timer);
|
||||
chn_ctl.run_limit_timer = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* relay_chn APIs */
|
||||
@@ -68,6 +94,28 @@ relay_chn_direction_t relay_chn_ctl_get_direction()
|
||||
{
|
||||
return relay_chn_output_get_direction(chn_ctl.output);
|
||||
}
|
||||
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
uint16_t relay_chn_ctl_get_run_limit()
|
||||
{
|
||||
return chn_ctl.run_limit_sec;
|
||||
}
|
||||
|
||||
void relay_chn_ctl_set_run_limit(uint16_t time_sec)
|
||||
{
|
||||
// Check for boundaries
|
||||
if (time_sec > RELAY_CHN_RUN_LIMIT_MAX_SEC)
|
||||
time_sec = RELAY_CHN_RUN_LIMIT_MAX_SEC;
|
||||
else if (time_sec < RELAY_CHN_RUN_LIMIT_MIN_SEC)
|
||||
time_sec = RELAY_CHN_RUN_LIMIT_MIN_SEC;
|
||||
|
||||
chn_ctl.run_limit_sec = time_sec;
|
||||
|
||||
#if RELAY_CHN_ENABLE_NVS == 1
|
||||
relay_chn_nvs_set_run_limit(chn_ctl.id, time_sec);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
/* relay_chn APIs */
|
||||
|
||||
relay_chn_ctl_t *relay_chn_ctl_get()
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
#include "relay_chn_nvs.h"
|
||||
|
||||
#define RELAY_CHN_KEY_DIR "dir" /*!< Direction key */
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
#define RELAY_CHN_KEY_RLIM(ch) "rlim_%d" /*!< Run limit key */
|
||||
#endif
|
||||
#ifdef RELAY_CHN_ENABLE_TILTING
|
||||
#define RELAY_CHN_KEY_TSENS(ch) "tsens_%d" /*!< Tilt sensitivity key */
|
||||
#define RELAY_CHN_KEY_TCNT(ch) "tcnt_%d" /*!< Tilt count key */
|
||||
@@ -69,6 +72,22 @@ esp_err_t relay_chn_nvs_get_direction(uint8_t ch, relay_chn_direction_t *directi
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
esp_err_t relay_chn_nvs_set_run_limit(uint8_t ch, uint16_t time_sec)
|
||||
{
|
||||
esp_err_t ret = nvs_set_u16(relay_chn_nvs, RELAY_CHN_KEY_RLIM(ch), time_sec);
|
||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to set run limit for channel %d", ch);
|
||||
return nvs_commit(relay_chn_nvs);
|
||||
}
|
||||
|
||||
esp_err_t relay_chn_nvs_get_run_limit(uint8_t ch, uint16_t *time_sec)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(time_sec != NULL, ESP_ERR_INVALID_ARG, TAG, "Run limit value pointer is NULL");
|
||||
|
||||
return nvs_get_u16(relay_chn_nvs, RELAY_CHN_KEY_RLIM(ch), time_sec);
|
||||
}
|
||||
#endif // RELAY_CHN_ENABLE_RUN_LIMIT == 1
|
||||
|
||||
#ifdef RELAY_CHN_ENABLE_TILTING
|
||||
esp_err_t relay_chn_nvs_set_tilt_sensitivity(uint8_t ch, uint8_t sensitivity)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user