diff --git a/examples/relay_chn_single/.gitignore b/examples/relay_chn_single/.gitignore new file mode 100644 index 0000000..51c9513 --- /dev/null +++ b/examples/relay_chn_single/.gitignore @@ -0,0 +1,3 @@ +build/ +sdkconfig +sdkconfig.old \ No newline at end of file diff --git a/examples/relay_chn_single/.vscode/c_cpp_properties.json b/examples/relay_chn_single/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..badb83d --- /dev/null +++ b/examples/relay_chn_single/.vscode/c_cpp_properties.json @@ -0,0 +1,23 @@ +{ + "configurations": [ + { + "name": "ESP-IDF", + "compilerPath": "${config:idf.toolsPath}/tools/riscv32-esp-elf/esp-14.2.0_20241119/riscv32-esp-elf/bin/riscv32-esp-elf-gcc", + "compileCommands": "/disk/Projeler/ESP-Components/relay_chn/examples/relay_chn_single/build/compile_commands.json", + "includePath": [ + "${config:idf.espIdfPath}/components/**", + "${config:idf.espIdfPathWin}/components/**", + "${workspaceFolder}/**" + ], + "browse": { + "path": [ + "${config:idf.espIdfPath}/components", + "${config:idf.espIdfPathWin}/components", + "${workspaceFolder}" + ], + "limitSymbolsToIncludedHeaders": true + } + } + ], + "version": 4 +} diff --git a/examples/relay_chn_single/.vscode/launch.json b/examples/relay_chn_single/.vscode/launch.json new file mode 100644 index 0000000..2511a38 --- /dev/null +++ b/examples/relay_chn_single/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "gdbtarget", + "request": "attach", + "name": "Eclipse CDT GDB Adapter" + }, + { + "type": "espidf", + "name": "Launch", + "request": "launch" + } + ] +} \ No newline at end of file diff --git a/examples/relay_chn_single/.vscode/settings.json b/examples/relay_chn_single/.vscode/settings.json new file mode 100644 index 0000000..81b74eb --- /dev/null +++ b/examples/relay_chn_single/.vscode/settings.json @@ -0,0 +1,17 @@ +{ + "C_Cpp.intelliSenseEngine": "default", + "idf.espIdfPath": "/disk/Depo/Developer/SDK/esp-idf/v5.4/esp-idf", + "idf.pythonInstallPath": "/usr/bin/python3", + "idf.openOcdConfigs": [ + "board/esp32c3-builtin.cfg" + ], + "idf.port": "/dev/ttyUSB0", + "idf.toolsPath": "/home/ismail/.espressif", + "idf.customExtraVars": { + "IDF_TARGET": "esp32c3" + }, + "idf.flashType": "UART", + "files.associations": { + "led_indicator_blink_default.h": "c" + } +} diff --git a/examples/relay_chn_single/CMakeLists.txt b/examples/relay_chn_single/CMakeLists.txt new file mode 100644 index 0000000..c64f60a --- /dev/null +++ b/examples/relay_chn_single/CMakeLists.txt @@ -0,0 +1,10 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +set(COMPONENTS main) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(relay_chn_single) \ No newline at end of file diff --git a/examples/relay_chn_single/README.md b/examples/relay_chn_single/README.md new file mode 100644 index 0000000..c39c97b --- /dev/null +++ b/examples/relay_chn_single/README.md @@ -0,0 +1,126 @@ +# Relay Channel Single Example + +## Introduction + +This example demonstrates how to use the relay channel component to control a 2-relay setup with button inputs and LED status indication. It showcases: + +- Basic relay channel operations (forward/reverse running, stopping) +- Secondary operations (tilting, direction flipping) +- State change event handling with multiple listeners +- Relay channel run limit +- Button event handling using esp-iot-solution's button component +- Visual feedback using esp-iot-solution's LED indicator component + +## How to Use Example + +This example has been tested on an `ESP32-C3-DevKitM-1U` board. However, it can be adapted to any ESP32-based board with at least six available GPIO pins by adjusting the configuration options. + +### Hardware Required + +* An ESP32-based development board +* 2 relays connected to GPIO pins (default: GPIO4, GPIO5) +* 3 buttons connected to GPIO pins: + - UP button (default: GPIO0) + - DOWN button (default: GPIO1) + - STOP button (default: GPIO2) +* 1 LED for status indication (default: GPIO3) + +#### Hardware Schematic + +![Hardware Schematic](example_schematic.png) + +### Configuration + +The example can be configured through `menuconfig` under "Relay Channel Single Example Configuration": + +1. Button active level (`EXAMPLE_RLCHN_BTN_ACTIVE_LEVEL`) + - Select between active LOW or HIGH logic level for buttons + +2. GPIO assignments: + - UP button pin (`EXAMPLE_RLCHN_BTN_UP_IO_NUM`, default: 0) + - DOWN button pin (`EXAMPLE_RLCHN_BTN_DOWN_IO_NUM`, default: 1) + - STOP button pin (`EXAMPLE_RLCHN_BTN_STOP_IO_NUM`, default: 2) + - LED indicator pin (`EXAMPLE_RLCHN_LED_INDICATOR_IO_NUM`, default: 3) + +3. Long press timing: + - `EXAMPLE_RLCHN_BTN_LONG_PRESS_TIME_MS`: Duration for long press actions (1500-3000ms, default: 2000ms) + +### Button Operations + +The example uses esp-iot-solution's `button` component to handle the following operations: + +- **UP button**: + * Short press: Start forward movement + * Long press: Start forward tilt (stops on release) + +- **DOWN button**: + * Short press: Start reverse movement + * Long press: Start reverse tilt (stops on release) + +- **STOP button**: + * Short press: Stop movement + * Long press: Flip movement direction + +### LED Indicator States + +The example uses esp-iot-solution's `led_indicator` component to show different states: + +- **Running**: LED blinks at 300ms on, 100ms off +- **Tilting**: Fast blink at 100ms on, 50ms off +- **Operation Success**: Two quick blinks +- **Operation Fail**: One long blink + +### Dependencies + +This example requires: +- ESP-IDF v4.1 or later +- esp-iot-solution components: + * button v4.1.1 or later + * led_indicator v1.1.1 or later +- relay_chn component + +## Example Output +When the application boots, it will wait for a button event. Then the two state listeners will print state changes. + +```log +I (273) main_task: Calling app_main() +I (273) RELAY_CHN_SINGLE_EXAMPLE: Initializing default NVS storage +I (283) RELAY_CHN_SINGLE_EXAMPLE: nvs_flash_init: NVS flash init return: ESP_OK +I (283) RELAY_CHN_SINGLE_EXAMPLE: Initializing relay channel +I (293) gpio: GPIO[4]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +I (303) gpio: GPIO[5]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +I (313) RELAY_CHN_SINGLE_EXAMPLE: Initializing buttons +I (313) RELAY_CHN_SINGLE_EXAMPLE: Initializing buttons with active level: 0 +I (323) gpio: GPIO[0]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +I (323) button: IoT Button Version: 4.1.3 +I (333) gpio: GPIO[1]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +I (343) gpio: GPIO[2]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +I (343) RELAY_CHN_SINGLE_EXAMPLE: Setting up button callbacks. Configured long press time: 2000 ms +I (353) RELAY_CHN_SINGLE_EXAMPLE: Initializing LED indicator +I (363) gpio: GPIO[3]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +I (373) led_indicator: LED Indicator Version: 1.1.1 +I (373) gpio: GPIO[3]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 +I (383) led_indicator: Indicator create successfully. type:GPIO mode, hardware_data:0x3fc97be4, blink_lists:custom +I (393) RELAY_CHN_SINGLE_EXAMPLE: Relay Channel Single Example is ready to operate +I (403) main_task: Returned from app_main() +I (3683) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_1: Defining new indicator mode for #0 and state change from 1 to 3 +I (3683) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_2: State change for #0, from IDLE to FORWARD +I (9513) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_1: Defining new indicator mode for #0 and state change from 3 to 2 +I (9513) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_2: State change for #0, from FORWARD to STOPPED +I (9523) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_1: Defining new indicator mode for #0 and state change from 2 to 6 +I (9533) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_2: State change for #0, from STOPPED to REVERSE_PENDING +I (10313) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_1: Defining new indicator mode for #0 and state change from 6 to 4 +I (10313) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_2: State change for #0, from REVERSE_PENDING to REVERSE +I (32173) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_1: Defining new indicator mode for #0 and state change from 4 to 2 +I (32173) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_2: State change for #0, from REVERSE to STOPPED +I (32973) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_1: Defining new indicator mode for #0 and state change from 2 to 1 +I (32973) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_2: State change for #0, from STOPPED to IDLE +I (36423) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_1: Defining new indicator mode for #0 and state change from 1 to 8 +I (36423) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_2: State change for #0, from IDLE to TILT_REVERSE +I (41153) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_1: Defining new indicator mode for #0 and state change from 8 to 1 +I (41153) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_2: State change for #0, from TILT_REVERSE to IDLE +I (47113) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_1: Defining new indicator mode for #0 and state change from 1 to 7 +I (47113) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_2: State change for #0, from IDLE to TILT_FORWARD +I (51913) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_1: Defining new indicator mode for #0 and state change from 7 to 1 +I (51913) RELAY_CHN_SINGLE_EXAMPLE: example_event_listener_2: State change for #0, from TILT_FORWARD to IDLE +``` \ No newline at end of file diff --git a/examples/relay_chn_single/example_schematic.png b/examples/relay_chn_single/example_schematic.png new file mode 100644 index 0000000..2c05916 Binary files /dev/null and b/examples/relay_chn_single/example_schematic.png differ diff --git a/examples/relay_chn_single/main/CMakeLists.txt b/examples/relay_chn_single/main/CMakeLists.txt new file mode 100644 index 0000000..3dcf1b0 --- /dev/null +++ b/examples/relay_chn_single/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "relay_chn_single_main.c" + PRIV_REQUIRES button led_indicator relay_chn) \ No newline at end of file diff --git a/examples/relay_chn_single/main/Kconfig.projbuild b/examples/relay_chn_single/main/Kconfig.projbuild new file mode 100644 index 0000000..e3a6992 --- /dev/null +++ b/examples/relay_chn_single/main/Kconfig.projbuild @@ -0,0 +1,40 @@ +menu "Relay Channel Single Example Configuration" + + choice EXAMPLE_RLCHN_BTN_ACTIVE_LEVEL + prompt "Choose an active level for buttons" + default EXAMPLE_RLCHN_BTN_ACTIVE_LEVEL_LOW + help + Specify the active level for buttons. + + config EXAMPLE_RLCHN_BTN_ACTIVE_LEVEL_LOW + bool "Active level LOW" + + config EXAMPLE_RLCHN_BTN_ACTIVE_LEVEL_HIGH + bool "Active level HIGH" + endchoice + + config EXAMPLE_RLCHN_BTN_UP_IO_NUM + int "GPIO number for UP button" + default 0 + + config EXAMPLE_RLCHN_BTN_DOWN_IO_NUM + int "GPIO number for DOWN button" + default 1 + + config EXAMPLE_RLCHN_BTN_STOP_IO_NUM + int "GPIO number for STOP button" + default 2 + + config EXAMPLE_RLCHN_LED_INDICATOR_IO_NUM + int "GPIO number for LED indicator output" + default 3 + + config EXAMPLE_RLCHN_BTN_LONG_PRESS_TIME_MS + int "Long press time in ms to start secondary actions" + range 1500 3000 + default 2000 + help + Long press time in milliseconds is required to start secondary actions + like tilting and flipping. + +endmenu \ No newline at end of file diff --git a/examples/relay_chn_single/main/idf_component.yml b/examples/relay_chn_single/main/idf_component.yml new file mode 100644 index 0000000..60c7cac --- /dev/null +++ b/examples/relay_chn_single/main/idf_component.yml @@ -0,0 +1,8 @@ +dependencies: + idf: + version: '>=4.1.0' + espressif/button: ^4.1.1 + espressif/led_indicator: ^1.1.1 + relay_chn: + version: '*' + override_path: ../../../ diff --git a/examples/relay_chn_single/main/relay_chn_single_main.c b/examples/relay_chn_single/main/relay_chn_single_main.c new file mode 100644 index 0000000..4e9db7d --- /dev/null +++ b/examples/relay_chn_single/main/relay_chn_single_main.c @@ -0,0 +1,290 @@ +/* + * SPDX-FileCopyrightText: 2025 Kozmotronik Tech + * + * SPDX-License-Identifier: MIT + */ + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_check.h" +#include "driver/gpio.h" +#include "nvs.h" +#include "nvs_flash.h" +#include "button_gpio.h" +#include "iot_button.h" +#include "led_indicator.h" +#include "relay_chn.h" + +static const char *TAG = "RELAY_CHN_SINGLE_EXAMPLE"; + +/** + * @brief LED indicator modes for different states. + */ +typedef enum { + INDICATOR_MODE_OK, /*!< OK/Success indication */ + INDICATOR_MODE_FAIL, /*!< Fail/Error indication */ + INDICATOR_MODE_TILTING, /*!< Tilting operation in progress */ + INDICATOR_MODE_RUNNING, /*!< Full run operation in progress */ + INDICATOR_MODE_MAX /*!< Maximum number of indicator modes */ +} indicator_mode_t; + +/** @brief Blink pattern for OK/Success indication. */ +static const blink_step_t indc_mode_ok[] = { + {LED_BLINK_HOLD, LED_STATE_ON, 100}, // step1: turn on LED 100 ms + {LED_BLINK_HOLD, LED_STATE_OFF, 50}, // step2: turn off LED 50 ms + {LED_BLINK_HOLD, LED_STATE_ON, 100}, // step3: turn on LED 100 ms + {LED_BLINK_HOLD, LED_STATE_OFF, 50}, // step4: turn off LED 50 ms + {LED_BLINK_STOP, 0, 0}, // step5: stop blink (off) +}; + +/** @brief Blink pattern for Fail/Error indication. */ +static const blink_step_t indc_mode_fail[] = { + {LED_BLINK_HOLD, LED_STATE_ON, 1000}, // step1: turn on LED 1000 ms + {LED_BLINK_HOLD, LED_STATE_OFF, 500}, // step2: turn off LED 500 ms + {LED_BLINK_STOP, 0, 0}, // step4: stop blink (off) +}; + +/** @brief Blink pattern for full run operation. */ +static const blink_step_t indc_mode_running[] = { + {LED_BLINK_HOLD, LED_STATE_ON, 300}, // step1: turn on LED 300 ms + {LED_BLINK_HOLD, LED_STATE_OFF, 100}, // step2: turn off LED 100 ms + {LED_BLINK_LOOP, 0, 0}, // step3: loop from step1 +}; + +/** @brief Blink pattern for tilting operation. */ +static const blink_step_t indc_mode_tilting[] = { + {LED_BLINK_HOLD, LED_STATE_ON, 100}, // step1: turn on LED 100 ms + {LED_BLINK_HOLD, LED_STATE_OFF, 50}, // step2: turn off LED 50 ms + {LED_BLINK_LOOP, 0, 0}, // step3: loop from step1 +}; + +/** @brief Array of LED indicator blink patterns. */ +blink_step_t const *led_indicator_modes[] = { + [INDICATOR_MODE_OK] = indc_mode_ok, + [INDICATOR_MODE_FAIL] = indc_mode_fail, + [INDICATOR_MODE_RUNNING] = indc_mode_running, + [INDICATOR_MODE_TILTING] = indc_mode_tilting, + [INDICATOR_MODE_MAX] = NULL, +}; + +/** @brief Handle for the LED indicator. */ +static led_indicator_handle_t indicator = NULL; + +/** + * @brief Initializes the buttons for user interaction. + * + * This function configures and creates GPIO buttons for UP, DOWN, and STOP + * operations. It also registers callbacks for single-click and long-press + * events to control the relay channel. + * + * @return esp_err_t + * - ESP_OK: Success + * - Others: Fail + */ +static esp_err_t init_buttons(void); + +/** + * @brief Initializes the LED indicator. + * + * This function configures and creates the LED indicator used to provide + * visual feedback on the relay channel's status. + * + * @return esp_err_t + * - ESP_OK: Success + * - ESP_FAIL: Fail + */ +static esp_err_t init_led_indicator(void); + +/** + * @brief Event listener for relay channel state changes to control the LED indicator. + */ +static void example_event_listener_1(uint8_t ch, relay_chn_state_t old_state, relay_chn_state_t new_state); + +/** + * @brief Event listener for relay channel state changes to log the state transition. + */ +static void example_event_listener_2(uint8_t ch, relay_chn_state_t old_state, relay_chn_state_t new_state); + +void app_main(void) +{ + const uint8_t gpio_map[] = { 4, 5 }; + const uint8_t gpio_count = sizeof(gpio_map) / sizeof(gpio_map[0]); + + ESP_LOGI(TAG, "Initializing relay channel"); + ESP_ERROR_CHECK(relay_chn_create(gpio_map, gpio_count)); + ESP_ERROR_CHECK(relay_chn_register_listener(example_event_listener_1)); + ESP_ERROR_CHECK(relay_chn_register_listener(example_event_listener_2)); + + ESP_LOGI(TAG, "Initializing buttons"); + ESP_ERROR_CHECK(init_buttons()); + ESP_LOGI(TAG, "Initializing LED indicator"); + ESP_ERROR_CHECK(init_led_indicator()); + + ESP_LOGI(TAG, "Relay Channel Single Example is ready to operate"); + + // Indicate init was successful + led_indicator_start(indicator, INDICATOR_MODE_OK); +} + +static void on_click_up(void *arg, void *data) +{ + relay_chn_run_forward(); +} + +static void on_click_down(void *arg, void *data) +{ + relay_chn_run_reverse(); +} + +static void on_click_stop(void *arg, void *data) +{ + relay_chn_stop(); +} + +static void on_click_flip(void *arg, void *data) +{ + relay_chn_flip_direction(); + led_indicator_start(indicator, INDICATOR_MODE_OK); +} + +static void on_click_tilt_up(void *arg, void *data) +{ + relay_chn_tilt_forward(); +} + +static void on_click_tilt_down(void *arg, void *data) +{ + relay_chn_tilt_reverse(); +} + +static void on_release_tilt(void *arg, void *data) +{ + relay_chn_tilt_stop(); +} + +static void example_event_listener_1(uint8_t ch, relay_chn_state_t old_state, relay_chn_state_t new_state) +{ + ESP_LOGI(TAG, "example_event_listener_1: Defining new indicator mode for #%d and state change from %d to %d", ch, old_state, new_state); + switch (new_state) { + case RELAY_CHN_STATE_FORWARD: + case RELAY_CHN_STATE_REVERSE: + led_indicator_start(indicator, INDICATOR_MODE_RUNNING); + break; + + case RELAY_CHN_STATE_STOPPED: + case RELAY_CHN_STATE_IDLE: + if (old_state == RELAY_CHN_STATE_FORWARD || old_state == RELAY_CHN_STATE_REVERSE) { + led_indicator_stop(indicator, INDICATOR_MODE_RUNNING); + // Make sure the indicator turned off + led_indicator_set_on_off(indicator, false); + } + else if (old_state == RELAY_CHN_STATE_TILT_FORWARD || old_state == RELAY_CHN_STATE_TILT_REVERSE) { + led_indicator_stop(indicator, INDICATOR_MODE_TILTING); + // Make sure the indicator turned off + led_indicator_set_on_off(indicator, false); + } + break; + + case RELAY_CHN_STATE_TILT_FORWARD: + case RELAY_CHN_STATE_TILT_REVERSE: + led_indicator_start(indicator, INDICATOR_MODE_TILTING); + break; + + default: // No-op + } +} + +static void example_event_listener_2(uint8_t ch, relay_chn_state_t old_state, relay_chn_state_t new_state) +{ + ESP_LOGI(TAG, "example_event_listener_2: State change for #%d, from %s to %s", + ch, relay_chn_state_to_str(old_state), relay_chn_state_to_str(new_state)); +} + +static esp_err_t init_buttons() +{ + esp_err_t ret; + button_config_t btn_cfg = {0}; + + uint8_t active_level = CONFIG_EXAMPLE_RLCHN_BTN_ACTIVE_LEVEL_LOW ? 0 : 1; + + button_gpio_config_t btn_gpio_ccfg = { + .gpio_num = (gpio_num_t) CONFIG_EXAMPLE_RLCHN_BTN_UP_IO_NUM, + .active_level = active_level + }; + + ESP_LOGI(TAG, "Initializing buttons with active level: %u", active_level); + button_handle_t btn_up = NULL, btn_down = NULL, btn_stop = NULL; + // --- Create buttons --- + ret = iot_button_new_gpio_device(&btn_cfg, &btn_gpio_ccfg, &btn_up); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to create UP button"); + ESP_RETURN_ON_FALSE(btn_up != NULL, ret, TAG, "Failed to create UP button"); + + btn_gpio_ccfg.gpio_num = (gpio_num_t) CONFIG_EXAMPLE_RLCHN_BTN_DOWN_IO_NUM; + ret = iot_button_new_gpio_device(&btn_cfg, &btn_gpio_ccfg, &btn_down); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to create DOWN button"); + ESP_RETURN_ON_FALSE(btn_down != NULL, ret, TAG, "Failed to create DOWN button"); + + btn_gpio_ccfg.gpio_num = (gpio_num_t) CONFIG_EXAMPLE_RLCHN_BTN_STOP_IO_NUM; + ret = iot_button_new_gpio_device(&btn_cfg, &btn_gpio_ccfg, &btn_stop); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to create STOP button"); + ESP_RETURN_ON_FALSE(btn_stop != NULL, ret, TAG, "Failed to create STOP button"); + // --- Create buttons --- + + // --- Register button callbacks --- + ESP_LOGI(TAG, "Setting up button callbacks. Configured long press time: %d ms", CONFIG_EXAMPLE_RLCHN_BTN_LONG_PRESS_TIME_MS); + button_event_args_t btn_event_args = { + .long_press.press_time = CONFIG_EXAMPLE_RLCHN_BTN_LONG_PRESS_TIME_MS + }; + // --- Register UP and TILT_UP operations on UP button --- + ret = iot_button_register_cb(btn_up, BUTTON_SINGLE_CLICK, NULL, on_click_up, NULL); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to register UP button click callback"); + ret = iot_button_register_cb(btn_up, BUTTON_LONG_PRESS_START, &btn_event_args, on_click_tilt_up, NULL); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to register TILT_UP button press callback"); + ret = iot_button_register_cb(btn_up, BUTTON_LONG_PRESS_UP, NULL, on_release_tilt, NULL); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to register TILT_UP button release callback"); + + // --- Register DOWN and TILT_DOWN operations on DOWN button --- + ret = iot_button_register_cb(btn_down, BUTTON_SINGLE_CLICK, NULL, on_click_down, NULL); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to register DOWN button click callback"); + ret = iot_button_register_cb(btn_down, BUTTON_LONG_PRESS_START, &btn_event_args, on_click_tilt_down, NULL); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to register TILT_DOWN button press callback"); + ret = iot_button_register_cb(btn_down, BUTTON_LONG_PRESS_UP, NULL, on_release_tilt, NULL); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to register TILT_DOWN button release callback"); + + // --- Register STOP and FLIP operations on STOP --- + ret = iot_button_register_cb(btn_stop, BUTTON_SINGLE_CLICK, NULL, on_click_stop, NULL); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to register STOP button click callback"); + ret = iot_button_register_cb(btn_stop, BUTTON_LONG_PRESS_START, &btn_event_args, on_click_flip, NULL); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to register FLIP button press callback"); + + return ESP_OK; +} + +static esp_err_t init_led_indicator() +{ + const gpio_num_t indicator_io_num = (gpio_num_t) CONFIG_EXAMPLE_RLCHN_LED_INDICATOR_IO_NUM; + gpio_reset_pin(indicator_io_num); // Clear the output buffers + + led_indicator_gpio_config_t led_indicator_gpio_cfg = { + .gpio_num = indicator_io_num, + .is_active_level_high = true + }; + + led_indicator_config_t led_indicator_cfg = { + .mode = LED_GPIO_MODE, + .led_indicator_gpio_config = &led_indicator_gpio_cfg, + .blink_lists = led_indicator_modes, + .blink_list_num = INDICATOR_MODE_MAX + }; + + indicator = led_indicator_create(&led_indicator_cfg); + if (!indicator) { + ESP_LOGE(TAG, "Failed to create LED indicator"); + return ESP_FAIL; + } + + return ESP_OK; +} \ No newline at end of file diff --git a/examples/relay_chn_single/sdkconfig.defaults b/examples/relay_chn_single/sdkconfig.defaults new file mode 100644 index 0000000..faefa95 --- /dev/null +++ b/examples/relay_chn_single/sdkconfig.defaults @@ -0,0 +1,9 @@ +# Halt on panic +CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y + +# Relay Channel Configs +CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT=y +# Keep this as short as possible for example purposes +CONFIG_RELAY_CHN_RUN_LIMIT_MIN_SEC=5 +CONFIG_RELAY_CHN_RUN_LIMIT_DEFAULT_SEC=20 +CONFIG_RELAY_CHN_ENABLE_TILTING=y