style: added docs
This commit is contained in:
1 parent
b8aa3a594d
commit
b9fc3a6f41
17 files changed
+824
-244
No files matched your search
+372
-118
@@ -1,46 +1,261 @@
|
||||
#include "ate0005.h"
|
||||
|
||||
static task_stats_t _task_stats = {A_INCLINOMETER_TASK_STACK_SIZE, B_INCLINOMETER_TASK_STACK_SIZE, A_TACHOMETER_TASK_STACK_SIZE, B_TACHOMETER_TASK_STACK_SIZE};
|
||||
/**
|
||||
* @brief Internal structure holding the tasks minimum free stack sizes.
|
||||
*
|
||||
* Each field stores the high water mark of the corresponding processing
|
||||
* task, reported by uxTaskGetStackHighWaterMark(). The statistics task reads
|
||||
* these values to log stack usage and to raise a warning when a value falls
|
||||
* below the threshold.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t a_inclinometer_task_min_stack_size; /*!< Minimum free stack size of the A inclinometer task */
|
||||
uint32_t b_inclinometer_task_min_stack_size; /*!< Minimum free stack size of the B inclinometer task */
|
||||
uint32_t a_tachometer_task_min_stack_size; /*!< Minimum free stack size of the A tachometer task */
|
||||
uint32_t b_tachometer_task_min_stack_size; /*!< Minimum free stack size of the B tachometer task */
|
||||
} _task_stats_t;
|
||||
|
||||
static httpd_handle_t _http_server_handle = NULL;
|
||||
|
||||
static zh_pcf8574_handle_t _lcd_handle = {0};
|
||||
static zh_encoder_handle_t _mode_encoder_handle = {0};
|
||||
static zh_inclinometer_handle_t _a_inclinometer_handle = {0};
|
||||
static zh_inclinometer_handle_t _b_inclinometer_handle = {0};
|
||||
static zh_tachometer_handle_t _a_tachometer_handle = {0};
|
||||
static zh_tachometer_handle_t _b_tachometer_handle = {0};
|
||||
static esp_timer_handle_t _inclinometer_reset_timer_handle = {0};
|
||||
|
||||
static SemaphoreHandle_t _lcd_mutex = NULL;
|
||||
static TaskHandle_t _a_inclinometer_task_handle = NULL;
|
||||
static TaskHandle_t _b_inclinometer_task_handle = NULL;
|
||||
static TaskHandle_t _a_tachometer_task_handle = NULL;
|
||||
static TaskHandle_t _b_tachometer_task_handle = NULL;
|
||||
static TaskHandle_t _zh_stats_task_handle = NULL;
|
||||
static httpd_handle_t _http_server_handle = NULL; /*!< HTTP server handle */
|
||||
static zh_pcf8574_handle_t *_lcd_handle = NULL; /*!< PCF8574 LCD expander handle */
|
||||
static zh_160x_i2c_handle_t *_lcd_160x_handle = NULL; /*!< 16x2 LCD display handle */
|
||||
static zh_encoder_handle_t *_mode_encoder_handle = NULL; /*!< Mode selector rotary encoder handle */
|
||||
static zh_inclinometer_handle_t *_a_inclinometer_handle = NULL; /*!< A channel inclinometer handle */
|
||||
static zh_inclinometer_handle_t *_b_inclinometer_handle = NULL; /*!< B channel inclinometer handle */
|
||||
static zh_tachometer_handle_t *_a_tachometer_handle = NULL; /*!< A channel tachometer handle */
|
||||
static zh_tachometer_handle_t *_b_tachometer_handle = NULL; /*!< B channel tachometer handle */
|
||||
static esp_timer_handle_t _inclinometer_reset_timer_handle = {0}; /*!< Inclinometer reset software timer handle */
|
||||
static SemaphoreHandle_t _lcd_mutex = NULL; /*!< Mutex to protect the LCD display access */
|
||||
static TaskHandle_t _a_inclinometer_task_handle = NULL; /*!< Handle of the A inclinometer processing task */
|
||||
static TaskHandle_t _b_inclinometer_task_handle = NULL; /*!< Handle of the B inclinometer processing task */
|
||||
static TaskHandle_t _a_tachometer_task_handle = NULL; /*!< Handle of the A tachometer processing task */
|
||||
static TaskHandle_t _b_tachometer_task_handle = NULL; /*!< Handle of the B tachometer processing task */
|
||||
static TaskHandle_t _zh_stats_task_handle = NULL; /*!< Handle of the statistics processing task */
|
||||
|
||||
/**
|
||||
* @brief Initialize WiFi in AP+STA mode.
|
||||
*
|
||||
* Creates default AP and STA netifs, configures the AP with the SSID,
|
||||
* password, channel and maximum number of connections and the STA with the
|
||||
* SSID and password. Registers the Wi-Fi event handler and starts Wi-Fi.
|
||||
*/
|
||||
static void _zh_wifi_init(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize the web server with OTA support.
|
||||
*
|
||||
* Starts the HTTP server with default configuration and registers the OTA
|
||||
* update page handler at the root URI.
|
||||
*/
|
||||
static void _zh_webserver_init(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize the ESP-NOW wireless protocol.
|
||||
*
|
||||
* Not implemented yet.
|
||||
*/
|
||||
static void _zh_espnow_init(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize the mode selector rotary encoder.
|
||||
*
|
||||
* Registers the encoder event handler and initializes the encoder with the
|
||||
* task configuration, GPIO numbers, queue size and position limits
|
||||
* corresponding to the number of main menu entries.
|
||||
*/
|
||||
static void _zh_encoder_init(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize the A channel inclinometer.
|
||||
*
|
||||
* Initializes the inclinometer with the A channel optical device GPIO numbers
|
||||
* and the encoder pulse count, then creates the A inclinometer processing
|
||||
* task.
|
||||
*/
|
||||
static void _zh_a_inclinometer_init(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize the B channel inclinometer.
|
||||
*
|
||||
* Initializes the inclinometer with the B channel optical device GPIO numbers
|
||||
* and the encoder pulse count, then creates the B inclinometer processing
|
||||
* task.
|
||||
*/
|
||||
static void _zh_b_inclinometer_init(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize the A channel tachometer.
|
||||
*
|
||||
* Initializes the tachometer with the A channel optical device GPIO numbers
|
||||
* and the encoder pulse count, then creates the A tachometer processing
|
||||
* task.
|
||||
*/
|
||||
static void _zh_a_tachometer_init(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize the B channel tachometer.
|
||||
*
|
||||
* Initializes the tachometer with the B channel optical device GPIO numbers
|
||||
* and the encoder pulse count, then creates the B tachometer processing
|
||||
* task.
|
||||
*/
|
||||
static void _zh_b_tachometer_init(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize the PCF8574 I2C expander of the LCD display.
|
||||
*
|
||||
* Creates the I2C master bus, initializes the PCF8574 expander with the task
|
||||
* configuration and I2C address, initializes the 16x2 LCD driver on top of
|
||||
* it and creates the LCD access mutex.
|
||||
*/
|
||||
static void _zh_pcf8574_init(void);
|
||||
|
||||
/**
|
||||
* @brief Show the system loading screen on the LCD display.
|
||||
*
|
||||
* Displays the manufacturer name, project name and firmware version, then an
|
||||
* animated progress bar. After loading, shows the current operating mode
|
||||
* label.
|
||||
*/
|
||||
static void _zh_system_load(void);
|
||||
|
||||
/**
|
||||
* @brief Create the inclinometer reset timer.
|
||||
*
|
||||
* Creates a one-shot software timer that resets the inclinometer angle on
|
||||
* long press of the mode encoder button.
|
||||
*/
|
||||
static void _zh_timer_init(void);
|
||||
|
||||
/**
|
||||
* @brief Handle the mode encoder events.
|
||||
*
|
||||
* On button press starts the inclinometer reset timer and enters reset mode.
|
||||
* On button release stops the timer and either ignores the event if the reset
|
||||
* already occurred, or toggles the menu mode.
|
||||
*
|
||||
* Entering the menu mode stops the tasks and deinitializes the active devices
|
||||
* of the current operating mode and enables the LCD cursor. Leaving the menu
|
||||
* mode initializes the devices of the selected mode.
|
||||
*
|
||||
* On encoder rotation in the menu mode updates and displays the selected menu
|
||||
* entry, otherwise restores the encoder position to the current menu value.
|
||||
*
|
||||
* @param arg User data registered with the event handler (unused)
|
||||
* @param event_base Event base of the registered event
|
||||
* @param event_id ID of the encoder or button event
|
||||
* @param event_data Pointer to the event payload structure
|
||||
*/
|
||||
static void _zh_encoder_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
|
||||
|
||||
/**
|
||||
* @brief Handle the ESP-NOW events.
|
||||
*
|
||||
* Not implemented yet.
|
||||
*
|
||||
* @param arg User data registered with the event handler (unused)
|
||||
* @param event_base Event base of the registered event
|
||||
* @param event_id ID of the ESP-NOW event (unused)
|
||||
* @param event_data Pointer to the event payload (unused)
|
||||
*/
|
||||
static void _zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
|
||||
|
||||
/**
|
||||
* @brief Handle the Wi-Fi station events.
|
||||
*
|
||||
* Initiates connection on station start, reconnects with a limited number of
|
||||
* retries on disconnection and stops the syslog statistics task. On IP
|
||||
* assignment resets the retry counter, initializes the syslog client and
|
||||
* creates the statistics processing task.
|
||||
*
|
||||
* @param arg User data registered with the event handler (unused)
|
||||
* @param event_base Event base of the registered event
|
||||
* @param event_id ID of the Wi-Fi or IP event
|
||||
* @param event_data Pointer to the event payload structure (unused)
|
||||
*/
|
||||
static void _zh_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
|
||||
|
||||
/**
|
||||
* @brief Inclinometer reset timer callback.
|
||||
*
|
||||
* Called on long press of the mode encoder button. Resets the angle of the
|
||||
* active inclinometers of the current operating mode when the device is not
|
||||
* in the menu mode.
|
||||
*
|
||||
* @param arg User data registered with the timer (unused)
|
||||
*/
|
||||
static void _zh_inclinometer_reset_timer_on_alarm_cb(void *arg);
|
||||
|
||||
/**
|
||||
* @brief A channel inclinometer processing task.
|
||||
*
|
||||
* Displays the A channel angle with 1 decimal place on the second LCD row.
|
||||
* The value is refreshed only when it changes. Updates the task minimum free
|
||||
* stack size for the statistics task.
|
||||
*
|
||||
* @param pvParameter Task parameter (unused)
|
||||
*/
|
||||
static void _zh_a_inclinometer_processing_task(void *pvParameter);
|
||||
|
||||
/**
|
||||
* @brief B channel inclinometer processing task.
|
||||
*
|
||||
* Displays the B channel angle with 1 decimal place on the second LCD row.
|
||||
* The value is refreshed only when it changes. Updates the task minimum free
|
||||
* stack size for the statistics task.
|
||||
*
|
||||
* @param pvParameter Task parameter (unused)
|
||||
*/
|
||||
static void _zh_b_inclinometer_processing_task(void *pvParameter);
|
||||
|
||||
/**
|
||||
* @brief A channel tachometer processing task.
|
||||
*
|
||||
* Displays the A channel RPM on the second LCD row. The value is refreshed
|
||||
* only when it changes. Updates the task minimum free stack size for the
|
||||
* statistics task.
|
||||
*
|
||||
* @param pvParameter Task parameter (unused)
|
||||
*/
|
||||
static void _zh_a_tachometer_processing_task(void *pvParameter);
|
||||
|
||||
/**
|
||||
* @brief B channel tachometer processing task.
|
||||
*
|
||||
* Displays the B channel RPM on the second LCD row. The value is refreshed
|
||||
* only when it changes. Updates the task minimum free stack size for the
|
||||
* statistics task.
|
||||
*
|
||||
* @param pvParameter Task parameter (unused)
|
||||
*/
|
||||
static void _zh_b_tachometer_processing_task(void *pvParameter);
|
||||
|
||||
/**
|
||||
* @brief Statistics processing task.
|
||||
*
|
||||
* Periodically sends the tasks minimum free stack sizes and the component
|
||||
* error counters to the remote syslog server. Messages are logged with the
|
||||
* warning severity when a stack size falls below the threshold or an error
|
||||
* counter is not zero.
|
||||
*
|
||||
* @param pvParameter Task parameter (unused)
|
||||
*/
|
||||
static void _zh_stats_processing_task(void *pvParameter);
|
||||
|
||||
/**
|
||||
* @brief Main application entry point.
|
||||
*
|
||||
* Initializes NVS flash with erase and re-init on empty or version mismatch,
|
||||
* the default event loop, the PCF8574 LCD expander, the system loading
|
||||
* screen, the mode encoder, the inclinometer reset timer, the A and B
|
||||
* inclinometers, WiFi in AP+STA mode, the web server and ESP-NOW.
|
||||
*
|
||||
* Then performs the OTA rollback self-check: if the running image is pending
|
||||
* verification, waits 60 seconds and marks it as valid.
|
||||
*/
|
||||
void app_main(void);
|
||||
|
||||
volatile static _task_stats_t _task_stats = {A_INCLINOMETER_TASK_STACK_SIZE, B_INCLINOMETER_TASK_STACK_SIZE, A_TACHOMETER_TASK_STACK_SIZE, B_TACHOMETER_TASK_STACK_SIZE};
|
||||
static const char *_main_menu[] = {MAIN_MENU_ANGLE_ANGLE_NAME, MAIN_MENU_TACHO_TACHO_NAME, MAIN_MENU_ANGLE_TACHO_NAME, MAIN_MENU_REMOTE_NAME};
|
||||
volatile static bool _is_menu_mode = false;
|
||||
volatile static bool _is_reset_mode = false;
|
||||
@@ -51,8 +266,12 @@ volatile static bool _is_wifi_connected = false;
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
_lcd_mutex = xSemaphoreCreateMutex();
|
||||
nvs_flash_init();
|
||||
esp_err_t err = nvs_flash_init();
|
||||
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND)
|
||||
{
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
}
|
||||
esp_event_loop_create_default();
|
||||
_zh_pcf8574_init();
|
||||
_zh_system_load();
|
||||
@@ -108,7 +327,6 @@ static void _zh_webserver_init(void)
|
||||
|
||||
static void _zh_espnow_init(void)
|
||||
{
|
||||
// To Do.
|
||||
}
|
||||
|
||||
static void _zh_encoder_init(void)
|
||||
@@ -121,7 +339,6 @@ static void _zh_encoder_init(void)
|
||||
config.a_gpio_number = MODE_ENCODER_A_GPIO;
|
||||
config.b_gpio_number = MODE_ENCODER_B_GPIO;
|
||||
config.s_gpio_number = MODE_ENCODER_S_GPIO;
|
||||
config.s_gpio_debounce_time = 1000;
|
||||
config.encoder_min_value = 0;
|
||||
config.encoder_max_value = (sizeof(_main_menu) / sizeof(_main_menu[0])) - 1;
|
||||
config.encoder_step = 1;
|
||||
@@ -137,8 +354,8 @@ static void _zh_a_inclinometer_init(void)
|
||||
config.b_gpio_number = A_OPTICAL_DEVICE_B_GPIO;
|
||||
config.encoder_pulses = 3600;
|
||||
zh_inclinometer_init(&config, &_a_inclinometer_handle);
|
||||
xTaskCreatePinnedToCore(&_zh_a_inclinometer_processing_task, "a_inclinometer_processing_task", A_INCLINOMETER_TASK_STACK_SIZE, NULL, A_INCLINOMETER_TASK_PRIORITY,
|
||||
&_a_inclinometer_task_handle, tskNO_AFFINITY);
|
||||
xTaskCreatePinnedToCore(&_zh_a_inclinometer_processing_task, "a_inclinometer_processing_task", A_INCLINOMETER_TASK_STACK_SIZE, NULL,
|
||||
A_INCLINOMETER_TASK_PRIORITY, &_a_inclinometer_task_handle, tskNO_AFFINITY);
|
||||
}
|
||||
|
||||
static void _zh_b_inclinometer_init(void)
|
||||
@@ -148,8 +365,8 @@ static void _zh_b_inclinometer_init(void)
|
||||
config.b_gpio_number = B_OPTICAL_DEVICE_B_GPIO;
|
||||
config.encoder_pulses = 3600;
|
||||
zh_inclinometer_init(&config, &_b_inclinometer_handle);
|
||||
xTaskCreatePinnedToCore(&_zh_b_inclinometer_processing_task, "b_inclinometer_processing_task", B_INCLINOMETER_TASK_STACK_SIZE, NULL, B_INCLINOMETER_TASK_PRIORITY,
|
||||
&_b_inclinometer_task_handle, tskNO_AFFINITY);
|
||||
xTaskCreatePinnedToCore(&_zh_b_inclinometer_processing_task, "b_inclinometer_processing_task", B_INCLINOMETER_TASK_STACK_SIZE, NULL,
|
||||
B_INCLINOMETER_TASK_PRIORITY, &_b_inclinometer_task_handle, tskNO_AFFINITY);
|
||||
}
|
||||
|
||||
static void _zh_a_tachometer_init(void)
|
||||
@@ -159,8 +376,8 @@ static void _zh_a_tachometer_init(void)
|
||||
config.b_gpio_number = A_OPTICAL_DEVICE_B_GPIO;
|
||||
config.encoder_pulses = 3600;
|
||||
zh_tachometer_init(&config, &_a_tachometer_handle);
|
||||
xTaskCreatePinnedToCore(&_zh_a_tachometer_processing_task, "a_tachometer_processing_task", A_TACHOMETER_TASK_STACK_SIZE, NULL, A_TACHOMETER_TASK_PRIORITY,
|
||||
&_a_tachometer_task_handle, tskNO_AFFINITY);
|
||||
xTaskCreatePinnedToCore(&_zh_a_tachometer_processing_task, "a_tachometer_processing_task", A_TACHOMETER_TASK_STACK_SIZE, NULL,
|
||||
A_TACHOMETER_TASK_PRIORITY, &_a_tachometer_task_handle, tskNO_AFFINITY);
|
||||
}
|
||||
|
||||
static void _zh_b_tachometer_init(void)
|
||||
@@ -170,8 +387,8 @@ static void _zh_b_tachometer_init(void)
|
||||
config.b_gpio_number = B_OPTICAL_DEVICE_B_GPIO;
|
||||
config.encoder_pulses = 3600;
|
||||
zh_tachometer_init(&config, &_b_tachometer_handle);
|
||||
xTaskCreatePinnedToCore(&_zh_b_tachometer_processing_task, "b_tachometer_processing_task", B_TACHOMETER_TASK_STACK_SIZE, NULL, B_TACHOMETER_TASK_PRIORITY,
|
||||
&_b_tachometer_task_handle, tskNO_AFFINITY);
|
||||
xTaskCreatePinnedToCore(&_zh_b_tachometer_processing_task, "b_tachometer_processing_task", B_TACHOMETER_TASK_STACK_SIZE, NULL,
|
||||
B_TACHOMETER_TASK_PRIORITY, &_b_tachometer_task_handle, tskNO_AFFINITY);
|
||||
}
|
||||
|
||||
static void _zh_pcf8574_init(void)
|
||||
@@ -191,34 +408,35 @@ static void _zh_pcf8574_init(void)
|
||||
config.i2c_handle = _i2c_bus_handle;
|
||||
config.i2c_address = LCD_I2C_ADDRESS;
|
||||
zh_pcf8574_init(&config, &_lcd_handle);
|
||||
zh_160x_init(&_lcd_handle, ZH_LCD_16X2);
|
||||
zh_160x_init(&_lcd_handle, &_lcd_160x_handle, ZH_LCD_16X2);
|
||||
_lcd_mutex = xSemaphoreCreateMutex();
|
||||
}
|
||||
|
||||
static void _zh_system_load(void)
|
||||
{
|
||||
zh_160x_set_cursor(&_lcd_handle, 0, 0);
|
||||
zh_160x_print_char(&_lcd_handle, "LLC AEROTECH");
|
||||
zh_160x_set_cursor(&_lcd_handle, 1, 0);
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 0, 0);
|
||||
zh_160x_print_char(&_lcd_160x_handle, "LLC AEROTECH");
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 1, 0);
|
||||
const esp_app_desc_t *esp_app_desc = esp_app_get_description();
|
||||
zh_160x_print_char(&_lcd_handle, esp_app_desc->project_name);
|
||||
zh_160x_set_cursor(&_lcd_handle, 1, 8);
|
||||
zh_160x_print_char(&_lcd_handle, "V");
|
||||
zh_160x_print_char(&_lcd_handle, esp_app_desc->version);
|
||||
zh_160x_print_char(&_lcd_160x_handle, esp_app_desc->project_name);
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 1, 8);
|
||||
zh_160x_print_char(&_lcd_160x_handle, "V");
|
||||
zh_160x_print_char(&_lcd_160x_handle, esp_app_desc->version);
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
zh_160x_lcd_clear(&_lcd_handle);
|
||||
zh_160x_set_cursor(&_lcd_handle, 0, 0);
|
||||
zh_160x_print_char(&_lcd_handle, "SYSTEM LOADING:");
|
||||
zh_160x_lcd_clear(&_lcd_160x_handle);
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 0, 0);
|
||||
zh_160x_print_char(&_lcd_160x_handle, "SYSTEM LOADING:");
|
||||
for (uint8_t i = 0; i <= 100; i += 10)
|
||||
{
|
||||
zh_160x_print_progress_bar(&_lcd_handle, 1, i);
|
||||
zh_160x_print_progress_bar(&_lcd_160x_handle, 1, i);
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
}
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
zh_160x_lcd_clear(&_lcd_handle);
|
||||
zh_160x_lcd_clear(&_lcd_160x_handle);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
zh_160x_set_cursor(&_lcd_handle, 0, 0);
|
||||
zh_160x_print_char(&_lcd_handle, "MODE:");
|
||||
zh_160x_print_char(&_lcd_handle, _main_menu[0]);
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 0, 0);
|
||||
zh_160x_print_char(&_lcd_160x_handle, "MODE:");
|
||||
zh_160x_print_char(&_lcd_160x_handle, _main_menu[0]);
|
||||
}
|
||||
|
||||
static void _zh_timer_init(void)
|
||||
@@ -231,11 +449,12 @@ static void _zh_timer_init(void)
|
||||
|
||||
static void _zh_encoder_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
|
||||
{
|
||||
(void)arg;
|
||||
switch (event_id)
|
||||
{
|
||||
case ZH_BUTTON_EVENT:
|
||||
zh_encoder_button_event_on_isr_t *button_event = event_data;
|
||||
if (button_event->button_status == ENCODER_BUTTON_PRESSED)
|
||||
zh_encoder_button_event_on_isr_t *button_event = (zh_encoder_button_event_on_isr_t *)event_data;
|
||||
if (button_event->button_status == ZH_ENCODER_BUTTON_STATUS_PRESSED)
|
||||
{
|
||||
esp_timer_start_once(_inclinometer_reset_timer_handle, 2000000);
|
||||
_is_reset_mode = true;
|
||||
@@ -258,36 +477,53 @@ static void _zh_encoder_event_handler(void *arg, esp_event_base_t event_base, in
|
||||
switch (_current_menu_value)
|
||||
{
|
||||
case MODE_ANGLE_ANGLE:
|
||||
vTaskDelete(_a_inclinometer_task_handle);
|
||||
vTaskDelete(_b_inclinometer_task_handle);
|
||||
if (_a_inclinometer_task_handle != NULL)
|
||||
{
|
||||
vTaskDelete(_a_inclinometer_task_handle);
|
||||
}
|
||||
if (_b_inclinometer_task_handle != NULL)
|
||||
{
|
||||
vTaskDelete(_b_inclinometer_task_handle);
|
||||
}
|
||||
zh_inclinometer_deinit(&_a_inclinometer_handle);
|
||||
zh_inclinometer_deinit(&_b_inclinometer_handle);
|
||||
break;
|
||||
case MODE_TACHO_TACHO:
|
||||
vTaskDelete(_a_tachometer_task_handle);
|
||||
vTaskDelete(_b_tachometer_task_handle);
|
||||
if (_a_tachometer_task_handle != NULL)
|
||||
{
|
||||
vTaskDelete(_a_tachometer_task_handle);
|
||||
}
|
||||
if (_b_tachometer_task_handle != NULL)
|
||||
{
|
||||
vTaskDelete(_b_tachometer_task_handle);
|
||||
}
|
||||
zh_tachometer_deinit(&_a_tachometer_handle);
|
||||
zh_tachometer_deinit(&_b_tachometer_handle);
|
||||
break;
|
||||
case MODE_ANGLE_TACHO:
|
||||
vTaskDelete(_a_inclinometer_task_handle);
|
||||
vTaskDelete(_b_tachometer_task_handle);
|
||||
if (_a_inclinometer_task_handle != NULL)
|
||||
{
|
||||
vTaskDelete(_a_inclinometer_task_handle);
|
||||
}
|
||||
if (_b_tachometer_task_handle != NULL)
|
||||
{
|
||||
vTaskDelete(_b_tachometer_task_handle);
|
||||
}
|
||||
zh_inclinometer_deinit(&_a_inclinometer_handle);
|
||||
zh_tachometer_deinit(&_b_tachometer_handle);
|
||||
break;
|
||||
case MODE_REMOTE:
|
||||
// To Do.
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
zh_160x_clear_row(&_lcd_handle, 1);
|
||||
zh_160x_set_cursor(&_lcd_handle, 0, 0);
|
||||
zh_160x_on_cursor(&_lcd_handle, true);
|
||||
zh_160x_clear_row(&_lcd_160x_handle, 1);
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 0, 0);
|
||||
zh_160x_on_cursor(&_lcd_160x_handle, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
zh_160x_off_cursor(&_lcd_handle);
|
||||
zh_160x_off_cursor(&_lcd_160x_handle);
|
||||
switch (_current_menu_value)
|
||||
{
|
||||
case MODE_ANGLE_ANGLE:
|
||||
@@ -303,8 +539,8 @@ static void _zh_encoder_event_handler(void *arg, esp_event_base_t event_base, in
|
||||
_zh_b_tachometer_init();
|
||||
break;
|
||||
case MODE_REMOTE:
|
||||
zh_160x_set_cursor(&_lcd_handle, 1, 0);
|
||||
zh_160x_print_char(&_lcd_handle, "NOT CONNECTED");
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 1, 0);
|
||||
zh_160x_print_char(&_lcd_160x_handle, "NOT CONNECTED");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -313,15 +549,15 @@ static void _zh_encoder_event_handler(void *arg, esp_event_base_t event_base, in
|
||||
}
|
||||
break;
|
||||
case ZH_ENCODER_EVENT:
|
||||
zh_encoder_event_on_isr_t *encoder_event = event_data;
|
||||
zh_encoder_event_on_isr_t *encoder_event = (zh_encoder_event_on_isr_t *)event_data;
|
||||
if (_is_menu_mode == true)
|
||||
{
|
||||
_current_menu_value = (uint8_t)encoder_event->encoder_position; // -V2004
|
||||
zh_160x_clear_row(&_lcd_handle, 0);
|
||||
zh_160x_set_cursor(&_lcd_handle, 0, 0);
|
||||
zh_160x_print_char(&_lcd_handle, "MODE:");
|
||||
zh_160x_print_char(&_lcd_handle, _main_menu[(uint8_t)encoder_event->encoder_position]); // -V2004
|
||||
zh_160x_set_cursor(&_lcd_handle, 0, 0);
|
||||
_current_menu_value = (uint8_t)encoder_event->encoder_position;
|
||||
zh_160x_clear_row(&_lcd_160x_handle, 0);
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 0, 0);
|
||||
zh_160x_print_char(&_lcd_160x_handle, "MODE:");
|
||||
zh_160x_print_char(&_lcd_160x_handle, _main_menu[(uint8_t)encoder_event->encoder_position]);
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -335,11 +571,12 @@ static void _zh_encoder_event_handler(void *arg, esp_event_base_t event_base, in
|
||||
|
||||
static void _zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
|
||||
{
|
||||
// To Do.
|
||||
}
|
||||
|
||||
static void _zh_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
|
||||
{
|
||||
(void)arg;
|
||||
(void)event_data;
|
||||
switch (event_id)
|
||||
{
|
||||
case WIFI_EVENT_STA_START:
|
||||
@@ -348,7 +585,10 @@ static void _zh_wifi_event_handler(void *arg, esp_event_base_t event_base, int32
|
||||
case WIFI_EVENT_STA_DISCONNECTED:
|
||||
if (_is_wifi_connected == true)
|
||||
{
|
||||
vTaskDelete(_zh_stats_task_handle);
|
||||
if (_zh_stats_task_handle != NULL)
|
||||
{
|
||||
vTaskDelete(_zh_stats_task_handle);
|
||||
}
|
||||
zh_syslog_deinit();
|
||||
_is_wifi_connected = false;
|
||||
}
|
||||
@@ -364,7 +604,11 @@ static void _zh_wifi_event_handler(void *arg, esp_event_base_t event_base, int32
|
||||
zh_syslog_init_config_t config = ZH_SYSLOG_INIT_CONFIG_DEFAULT();
|
||||
strcpy(config.syslog_ip, SYSLOG_IP);
|
||||
zh_syslog_init(&config);
|
||||
xTaskCreatePinnedToCore(&_zh_stats_processing_task, "stats_processing_task", STATS_TASK_STACK_SIZE, NULL, STATS_TASK_PRIORITY, &_zh_stats_task_handle, tskNO_AFFINITY);
|
||||
if (_zh_stats_task_handle == NULL)
|
||||
{
|
||||
xTaskCreatePinnedToCore(&_zh_stats_processing_task, "stats_processing_task", STATS_TASK_STACK_SIZE, NULL, STATS_TASK_PRIORITY,
|
||||
&_zh_stats_task_handle, tskNO_AFFINITY);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -373,6 +617,7 @@ static void _zh_wifi_event_handler(void *arg, esp_event_base_t event_base, int32
|
||||
|
||||
static void _zh_inclinometer_reset_timer_on_alarm_cb(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
_is_reset_mode = false;
|
||||
_is_reset_occurred = true;
|
||||
if (_is_menu_mode == false)
|
||||
@@ -394,11 +639,13 @@ static void _zh_inclinometer_reset_timer_on_alarm_cb(void *arg)
|
||||
|
||||
static void _zh_a_inclinometer_processing_task(void *pvParameter)
|
||||
{
|
||||
float prev_angle = 0, current_angle = 0;
|
||||
(void)pvParameter;
|
||||
float prev_angle = 0.0;
|
||||
float current_angle = 0.0;
|
||||
xSemaphoreTake(_lcd_mutex, portMAX_DELAY);
|
||||
zh_160x_set_cursor(&_lcd_handle, 1, 0);
|
||||
zh_160x_print_char(&_lcd_handle, "A:");
|
||||
zh_160x_print_float(&_lcd_handle, current_angle, 1);
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 1, 0);
|
||||
zh_160x_print_char(&_lcd_160x_handle, "A:");
|
||||
zh_160x_print_float(&_lcd_160x_handle, current_angle, 1);
|
||||
xSemaphoreGive(_lcd_mutex);
|
||||
for (;;)
|
||||
{
|
||||
@@ -407,10 +654,10 @@ static void _zh_a_inclinometer_processing_task(void *pvParameter)
|
||||
{
|
||||
prev_angle = current_angle;
|
||||
xSemaphoreTake(_lcd_mutex, portMAX_DELAY);
|
||||
zh_160x_set_cursor(&_lcd_handle, 1, 5);
|
||||
zh_160x_print_char(&_lcd_handle, " ");
|
||||
zh_160x_set_cursor(&_lcd_handle, 1, 2);
|
||||
zh_160x_print_float(&_lcd_handle, current_angle, 1);
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 1, 5);
|
||||
zh_160x_print_char(&_lcd_160x_handle, " ");
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 1, 2);
|
||||
zh_160x_print_float(&_lcd_160x_handle, current_angle, 1);
|
||||
xSemaphoreGive(_lcd_mutex);
|
||||
}
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
@@ -421,11 +668,13 @@ static void _zh_a_inclinometer_processing_task(void *pvParameter)
|
||||
|
||||
static void _zh_b_inclinometer_processing_task(void *pvParameter)
|
||||
{
|
||||
float prev_angle = 0, current_angle = 0;
|
||||
(void)pvParameter;
|
||||
float prev_angle = 0.0;
|
||||
float current_angle = 0.0;
|
||||
xSemaphoreTake(_lcd_mutex, portMAX_DELAY);
|
||||
zh_160x_set_cursor(&_lcd_handle, 1, 8);
|
||||
zh_160x_print_char(&_lcd_handle, "B:");
|
||||
zh_160x_print_float(&_lcd_handle, current_angle, 1);
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 1, 8);
|
||||
zh_160x_print_char(&_lcd_160x_handle, "B:");
|
||||
zh_160x_print_float(&_lcd_160x_handle, current_angle, 1);
|
||||
xSemaphoreGive(_lcd_mutex);
|
||||
for (;;)
|
||||
{
|
||||
@@ -434,10 +683,10 @@ static void _zh_b_inclinometer_processing_task(void *pvParameter)
|
||||
{
|
||||
prev_angle = current_angle;
|
||||
xSemaphoreTake(_lcd_mutex, portMAX_DELAY);
|
||||
zh_160x_set_cursor(&_lcd_handle, 1, 13);
|
||||
zh_160x_print_char(&_lcd_handle, " ");
|
||||
zh_160x_set_cursor(&_lcd_handle, 1, 10);
|
||||
zh_160x_print_float(&_lcd_handle, current_angle, 1);
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 1, 13);
|
||||
zh_160x_print_char(&_lcd_160x_handle, " ");
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 1, 10);
|
||||
zh_160x_print_float(&_lcd_160x_handle, current_angle, 1);
|
||||
xSemaphoreGive(_lcd_mutex);
|
||||
}
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
@@ -448,11 +697,13 @@ static void _zh_b_inclinometer_processing_task(void *pvParameter)
|
||||
|
||||
static void _zh_a_tachometer_processing_task(void *pvParameter)
|
||||
{
|
||||
uint16_t prev_rpm = 0, current_rpm = 0;
|
||||
(void)pvParameter;
|
||||
uint16_t prev_rpm = 0;
|
||||
uint16_t current_rpm = 0;
|
||||
xSemaphoreTake(_lcd_mutex, portMAX_DELAY);
|
||||
zh_160x_set_cursor(&_lcd_handle, 1, 0);
|
||||
zh_160x_print_char(&_lcd_handle, "A:");
|
||||
zh_160x_print_int(&_lcd_handle, current_rpm);
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 1, 0);
|
||||
zh_160x_print_char(&_lcd_160x_handle, "A:");
|
||||
zh_160x_print_int(&_lcd_160x_handle, current_rpm);
|
||||
xSemaphoreGive(_lcd_mutex);
|
||||
for (;;)
|
||||
{
|
||||
@@ -461,10 +712,10 @@ static void _zh_a_tachometer_processing_task(void *pvParameter)
|
||||
{
|
||||
prev_rpm = current_rpm;
|
||||
xSemaphoreTake(_lcd_mutex, portMAX_DELAY);
|
||||
zh_160x_set_cursor(&_lcd_handle, 1, 3);
|
||||
zh_160x_print_char(&_lcd_handle, " ");
|
||||
zh_160x_set_cursor(&_lcd_handle, 1, 2);
|
||||
zh_160x_print_int(&_lcd_handle, current_rpm);
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 1, 3);
|
||||
zh_160x_print_char(&_lcd_160x_handle, " ");
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 1, 2);
|
||||
zh_160x_print_int(&_lcd_160x_handle, current_rpm);
|
||||
xSemaphoreGive(_lcd_mutex);
|
||||
}
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
@@ -475,11 +726,13 @@ static void _zh_a_tachometer_processing_task(void *pvParameter)
|
||||
|
||||
static void _zh_b_tachometer_processing_task(void *pvParameter)
|
||||
{
|
||||
uint16_t prev_rpm = 0, current_rpm = 0;
|
||||
(void)pvParameter;
|
||||
uint16_t prev_rpm = 0;
|
||||
uint16_t current_rpm = 0;
|
||||
xSemaphoreTake(_lcd_mutex, portMAX_DELAY);
|
||||
zh_160x_set_cursor(&_lcd_handle, 1, 8);
|
||||
zh_160x_print_char(&_lcd_handle, "B:");
|
||||
zh_160x_print_int(&_lcd_handle, current_rpm);
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 1, 8);
|
||||
zh_160x_print_char(&_lcd_160x_handle, "B:");
|
||||
zh_160x_print_int(&_lcd_160x_handle, current_rpm);
|
||||
xSemaphoreGive(_lcd_mutex);
|
||||
for (;;)
|
||||
{
|
||||
@@ -488,10 +741,10 @@ static void _zh_b_tachometer_processing_task(void *pvParameter)
|
||||
{
|
||||
prev_rpm = current_rpm;
|
||||
xSemaphoreTake(_lcd_mutex, portMAX_DELAY);
|
||||
zh_160x_set_cursor(&_lcd_handle, 1, 11);
|
||||
zh_160x_print_char(&_lcd_handle, " ");
|
||||
zh_160x_set_cursor(&_lcd_handle, 1, 10);
|
||||
zh_160x_print_int(&_lcd_handle, current_rpm);
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 1, 11);
|
||||
zh_160x_print_char(&_lcd_160x_handle, " ");
|
||||
zh_160x_set_cursor(&_lcd_160x_handle, 1, 10);
|
||||
zh_160x_print_int(&_lcd_160x_handle, current_rpm);
|
||||
xSemaphoreGive(_lcd_mutex);
|
||||
}
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
@@ -502,51 +755,52 @@ static void _zh_b_tachometer_processing_task(void *pvParameter)
|
||||
|
||||
static void _zh_stats_processing_task(void *pvParameter)
|
||||
{
|
||||
(void)pvParameter;
|
||||
const esp_app_desc_t *esp_app_desc = esp_app_get_description();
|
||||
for (;;)
|
||||
{
|
||||
char buffer[1024] = {0};
|
||||
const zh_encoder_stats_t *encoder_stats = zh_encoder_get_stats();
|
||||
const zh_pcf8574_stats_t *pcf8574_stats = zh_pcf8574_get_stats();
|
||||
sprintf(buffer, "A inclinometer task minimum free stack size: %ld.\n", _task_stats.a_inclinometer_task_min_stack_size);
|
||||
snprintf(buffer, sizeof(buffer), "A inclinometer task minimum free stack size: %lu.\n", _task_stats.a_inclinometer_task_min_stack_size);
|
||||
zh_syslog_send(ZH_KERN, _task_stats.a_inclinometer_task_min_stack_size > 100 ? ZH_INFO : ZH_WARNING, esp_app_desc->project_name, "zh_inclinometer", buffer);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
sprintf(buffer, "B inclinometer task minimum free stack size: %ld.\n", _task_stats.b_inclinometer_task_min_stack_size);
|
||||
snprintf(buffer, sizeof(buffer), "B inclinometer task minimum free stack size: %lu.\n", _task_stats.b_inclinometer_task_min_stack_size);
|
||||
zh_syslog_send(ZH_KERN, _task_stats.b_inclinometer_task_min_stack_size > 100 ? ZH_INFO : ZH_WARNING, esp_app_desc->project_name, "zh_inclinometer", buffer);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
sprintf(buffer, "A tachometer task minimum free stack size: %ld.\n", _task_stats.b_tachometer_task_min_stack_size);
|
||||
snprintf(buffer, sizeof(buffer), "A tachometer task minimum free stack size: %lu.\n", _task_stats.a_tachometer_task_min_stack_size);
|
||||
zh_syslog_send(ZH_KERN, _task_stats.a_tachometer_task_min_stack_size > 100 ? ZH_INFO : ZH_WARNING, esp_app_desc->project_name, "zh_tachometer", buffer);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
snprintf(buffer, sizeof(buffer), "B tachometer task minimum free stack size: %lu.\n", _task_stats.b_tachometer_task_min_stack_size);
|
||||
zh_syslog_send(ZH_KERN, _task_stats.b_tachometer_task_min_stack_size > 100 ? ZH_INFO : ZH_WARNING, esp_app_desc->project_name, "zh_tachometer", buffer);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
sprintf(buffer, "B tachometer task minimum free stack size: %ld.\n", _task_stats.b_tachometer_task_min_stack_size);
|
||||
zh_syslog_send(ZH_KERN, _task_stats.b_tachometer_task_min_stack_size > 100 ? ZH_INFO : ZH_WARNING, esp_app_desc->project_name, "zh_tachometer", buffer);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
sprintf(buffer, "Stats task minimum free stack size: %ld.\n", (uint32_t)uxTaskGetStackHighWaterMark(NULL));
|
||||
snprintf(buffer, sizeof(buffer), "Stats task minimum free stack size: %lu.\n", (uint32_t)uxTaskGetStackHighWaterMark(NULL));
|
||||
zh_syslog_send(ZH_KERN, (uint32_t)uxTaskGetStackHighWaterMark(NULL) > 100 ? ZH_INFO : ZH_WARNING, esp_app_desc->project_name, "zh_syslog", buffer);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
sprintf(buffer, "Encoder task minimum free stack size: %ld.\n", encoder_stats->min_stack_size);
|
||||
snprintf(buffer, sizeof(buffer), "Encoder task minimum free stack size: %lu.\n", encoder_stats->min_stack_size);
|
||||
zh_syslog_send(ZH_KERN, encoder_stats->min_stack_size > 100 ? ZH_INFO : ZH_WARNING, esp_app_desc->project_name, "zh_encoder", buffer);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
sprintf(buffer, "Expander task minimum free stack size: %ld.\n", pcf8574_stats->min_stack_size);
|
||||
snprintf(buffer, sizeof(buffer), "Expander task minimum free stack size: %lu.\n", pcf8574_stats->min_stack_size);
|
||||
zh_syslog_send(ZH_KERN, pcf8574_stats->min_stack_size > 100 ? ZH_INFO : ZH_WARNING, esp_app_desc->project_name, "zh_pcf8574", buffer);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
sprintf(buffer, "Number of event post error: %ld.\n", encoder_stats->event_post_error);
|
||||
snprintf(buffer, sizeof(buffer), "Number of event post error: %lu.\n", encoder_stats->event_post_error);
|
||||
zh_syslog_send(ZH_KERN, encoder_stats->event_post_error == 0 ? ZH_INFO : ZH_WARNING, esp_app_desc->project_name, "zh_encoder", buffer);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
sprintf(buffer, "Number of queue overflow error: %ld.\n", encoder_stats->queue_overflow_error);
|
||||
snprintf(buffer, sizeof(buffer), "Number of queue overflow error: %lu.\n", encoder_stats->queue_overflow_error);
|
||||
zh_syslog_send(ZH_KERN, encoder_stats->queue_overflow_error == 0 ? ZH_INFO : ZH_WARNING, esp_app_desc->project_name, "zh_encoder", buffer);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
sprintf(buffer, "Number of i2c driver error: %ld.\n", pcf8574_stats->i2c_driver_error);
|
||||
snprintf(buffer, sizeof(buffer), "Number of i2c driver error: %lu.\n", pcf8574_stats->i2c_driver_error);
|
||||
zh_syslog_send(ZH_KERN, pcf8574_stats->i2c_driver_error == 0 ? ZH_INFO : ZH_WARNING, esp_app_desc->project_name, "zh_pcf8574", buffer);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
sprintf(buffer, "Number of event post error: %ld.\n", pcf8574_stats->event_post_error);
|
||||
snprintf(buffer, sizeof(buffer), "Number of event post error: %lu.\n", pcf8574_stats->event_post_error);
|
||||
zh_syslog_send(ZH_KERN, pcf8574_stats->event_post_error == 0 ? ZH_INFO : ZH_WARNING, esp_app_desc->project_name, "zh_pcf8574", buffer);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
sprintf(buffer, "Number of vector error: %ld.\n", pcf8574_stats->vector_error);
|
||||
snprintf(buffer, sizeof(buffer), "Number of vector error: %lu.\n", pcf8574_stats->vector_error);
|
||||
zh_syslog_send(ZH_KERN, pcf8574_stats->vector_error == 0 ? ZH_INFO : ZH_WARNING, esp_app_desc->project_name, "zh_pcf8574", buffer);
|
||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||
sprintf(buffer, "Number of queue overflow error: %ld.\n", pcf8574_stats->queue_overflow_error);
|
||||
snprintf(buffer, sizeof(buffer), "Number of queue overflow error: %lu.\n", pcf8574_stats->queue_overflow_error);
|
||||
zh_syslog_send(ZH_KERN, pcf8574_stats->queue_overflow_error == 0 ? ZH_INFO : ZH_WARNING, esp_app_desc->project_name, "zh_pcf8574", buffer);
|
||||
vTaskDelay(60000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user