Compare commits

..
4 Commits
Author SHA1 Message Date
aZholtikov 4593f44b39 wip: 2026-11-03 11:12:33 +03:00
aZholtikov e9fb27ca88 wip: 2026-11-03 09:32:19 +03:00
aZholtikov 1ad6a80fce wip: 2026-09-10 19:01:04 +03:00
aZholtikov e987d4cafb wip: 2026-09-10 18:40:56 +03:00
16 changed files with 247 additions and 209 deletions

No files matched your search

+3
View File
@@ -5,3 +5,6 @@ sdkconfig.old
desktop.ini desktop.ini
.PVS-Studio .PVS-Studio
sdkconfig sdkconfig
dependencies.lock
managed_components
rules.md
-27
View File
@@ -1,27 +0,0 @@
[submodule "components/zh_inclinometer"]
path = components/zh_inclinometer
url = https://github.com/aZholtikov/zh_inclinometer
[submodule "components/zh_encoder"]
path = components/zh_encoder
url = https://github.com/aZholtikov/zh_encoder
[submodule "components/zh_160x_i2c"]
path = components/zh_160x_i2c
url = https://github.com/aZholtikov/zh_160x_i2c
[submodule "components/zh_pcf8574"]
path = components/zh_pcf8574
url = https://github.com/aZholtikov/zh_pcf8574
[submodule "components/zh_vector"]
path = components/zh_vector
url = https://github.com/aZholtikov/zh_vector
[submodule "components/zh_ota_server"]
path = components/zh_ota_server
url = https://github.com/aZholtikov/zh_ota_server
[submodule "components/zh_espnow"]
path = components/zh_espnow
url = https://github.com/aZholtikov/zh_espnow
[submodule "components/zh_tachometer"]
path = components/zh_tachometer
url = https://github.com/aZholtikov/zh_tachometer
[submodule "components/zh_syslog"]
path = components/zh_syslog
url = https://github.com/aZholtikov/zh_syslog
+10 -7
View File
@@ -1,18 +1,21 @@
# Universal Optical 2-Channel Angle Gauge / Tachometer # Universal Optical 2-Channel Angle Gauge / Tachometer
## Tested on ## Features
1. [ESP32 ESP-IDF v5.5.3](https://docs.espressif.com/projects/esp-idf/en/v5.5.3/esp32/index.html) 1. Two independent channels supporting optical encoders with 3600 pulses per revolution.
2. Four operating modes: both inclinometers, both tachometers, mixed angle/tachometer, and remote via ESP-NOW.
## SAST Tools 3. 16x2 LCD display (PCF8574 I2C expander) with boot animation, progress bar, and real-time value updates.
4. Rotary encoder menu with push-button for mode switching and angle reset (long press, 2 seconds).
[PVS-Studio](https://pvs-studio.com/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source) - static analyzer for C, C++, C#, and Java code. 5. WiFi AP+STA mode with local access and STA connection for remote logging.
6. Over-the-Air (OTA) firmware updates via built-in HTTP server.
7. Remote syslog with periodic logging of task stack usage and driver error counters.
8. FreeRTOS-based multitasking with separate tasks for each channel, encoder, LCD expander, and statistics monitoring.
## Build and flash ## Build and flash
Run the following command to firmware build and flash module: Run the following command to firmware build and flash module:
```text ```bash
cd your_projects_folder cd your_projects_folder
git clone --recurse-submodules https://github.com/aZholtikov/ate0005 git clone --recurse-submodules https://github.com/aZholtikov/ate0005
cd ate0005 cd ate0005
+138 -100
View File
@@ -1,17 +1,14 @@
#include "ate0005.h" #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};
static httpd_handle_t _http_server_handle = NULL; static httpd_handle_t _http_server_handle = NULL;
static zh_pcf8574_handle_t *_lcd_handle = NULL;
static zh_pcf8574_handle_t _lcd_handle = {0}; static zh_160x_i2c_handle_t *_lcd_160x_handle = NULL;
static zh_encoder_handle_t _mode_encoder_handle = {0}; static zh_encoder_handle_t *_mode_encoder_handle = NULL;
static zh_inclinometer_handle_t _a_inclinometer_handle = {0}; static zh_inclinometer_handle_t *_a_inclinometer_handle = NULL;
static zh_inclinometer_handle_t _b_inclinometer_handle = {0}; static zh_inclinometer_handle_t *_b_inclinometer_handle = NULL;
static zh_tachometer_handle_t _a_tachometer_handle = {0}; static zh_tachometer_handle_t *_a_tachometer_handle = NULL;
static zh_tachometer_handle_t _b_tachometer_handle = {0}; static zh_tachometer_handle_t *_b_tachometer_handle = NULL;
static esp_timer_handle_t _inclinometer_reset_timer_handle = {0}; static esp_timer_handle_t _inclinometer_reset_timer_handle = {0};
static SemaphoreHandle_t _lcd_mutex = NULL; static SemaphoreHandle_t _lcd_mutex = NULL;
static TaskHandle_t _a_inclinometer_task_handle = NULL; static TaskHandle_t _a_inclinometer_task_handle = NULL;
static TaskHandle_t _b_inclinometer_task_handle = NULL; static TaskHandle_t _b_inclinometer_task_handle = NULL;
@@ -34,13 +31,13 @@ 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); static void _zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
static void _zh_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); static void _zh_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
static void _zh_inclinometer_reset_timer_on_alarm_cb(void *arg); static void _zh_inclinometer_reset_timer_on_alarm_cb(void *arg);
static void _zh_a_inclinometer_processing_task(void *pvParameter); static void _zh_a_inclinometer_processing_task(void *pvParameter);
static void _zh_b_inclinometer_processing_task(void *pvParameter); static void _zh_b_inclinometer_processing_task(void *pvParameter);
static void _zh_a_tachometer_processing_task(void *pvParameter); static void _zh_a_tachometer_processing_task(void *pvParameter);
static void _zh_b_tachometer_processing_task(void *pvParameter); static void _zh_b_tachometer_processing_task(void *pvParameter);
static void _zh_stats_processing_task(void *pvParameter); static void _zh_stats_processing_task(void *pvParameter);
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}; 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_menu_mode = false;
volatile static bool _is_reset_mode = false; volatile static bool _is_reset_mode = false;
@@ -51,8 +48,12 @@ volatile static bool _is_wifi_connected = false;
void app_main(void) void app_main(void)
{ {
_lcd_mutex = xSemaphoreCreateMutex(); esp_err_t err = nvs_flash_init();
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(); esp_event_loop_create_default();
_zh_pcf8574_init(); _zh_pcf8574_init();
_zh_system_load(); _zh_system_load();
@@ -121,7 +122,6 @@ static void _zh_encoder_init(void)
config.a_gpio_number = MODE_ENCODER_A_GPIO; config.a_gpio_number = MODE_ENCODER_A_GPIO;
config.b_gpio_number = MODE_ENCODER_B_GPIO; config.b_gpio_number = MODE_ENCODER_B_GPIO;
config.s_gpio_number = MODE_ENCODER_S_GPIO; config.s_gpio_number = MODE_ENCODER_S_GPIO;
config.s_gpio_debounce_time = 1000;
config.encoder_min_value = 0; config.encoder_min_value = 0;
config.encoder_max_value = (sizeof(_main_menu) / sizeof(_main_menu[0])) - 1; config.encoder_max_value = (sizeof(_main_menu) / sizeof(_main_menu[0])) - 1;
config.encoder_step = 1; config.encoder_step = 1;
@@ -191,34 +191,35 @@ static void _zh_pcf8574_init(void)
config.i2c_handle = _i2c_bus_handle; config.i2c_handle = _i2c_bus_handle;
config.i2c_address = LCD_I2C_ADDRESS; config.i2c_address = LCD_I2C_ADDRESS;
zh_pcf8574_init(&config, &_lcd_handle); 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) static void _zh_system_load(void)
{ {
zh_160x_set_cursor(&_lcd_handle, 0, 0); zh_160x_set_cursor(&_lcd_160x_handle, 0, 0);
zh_160x_print_char(&_lcd_handle, "LLC AEROTECH"); zh_160x_print_char(&_lcd_160x_handle, "LLC AEROTECH");
zh_160x_set_cursor(&_lcd_handle, 1, 0); zh_160x_set_cursor(&_lcd_160x_handle, 1, 0);
const esp_app_desc_t *esp_app_desc = esp_app_get_description(); 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_print_char(&_lcd_160x_handle, esp_app_desc->project_name);
zh_160x_set_cursor(&_lcd_handle, 1, 8); zh_160x_set_cursor(&_lcd_160x_handle, 1, 8);
zh_160x_print_char(&_lcd_handle, "V"); zh_160x_print_char(&_lcd_160x_handle, "V");
zh_160x_print_char(&_lcd_handle, esp_app_desc->version); zh_160x_print_char(&_lcd_160x_handle, esp_app_desc->version);
vTaskDelay(1000 / portTICK_PERIOD_MS); vTaskDelay(1000 / portTICK_PERIOD_MS);
zh_160x_lcd_clear(&_lcd_handle); zh_160x_lcd_clear(&_lcd_160x_handle);
zh_160x_set_cursor(&_lcd_handle, 0, 0); zh_160x_set_cursor(&_lcd_160x_handle, 0, 0);
zh_160x_print_char(&_lcd_handle, "SYSTEM LOADING:"); zh_160x_print_char(&_lcd_160x_handle, "SYSTEM LOADING:");
for (uint8_t i = 0; i <= 100; i += 10) 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(100 / portTICK_PERIOD_MS);
} }
vTaskDelay(500 / 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); vTaskDelay(500 / portTICK_PERIOD_MS);
zh_160x_set_cursor(&_lcd_handle, 0, 0); zh_160x_set_cursor(&_lcd_160x_handle, 0, 0);
zh_160x_print_char(&_lcd_handle, "MODE:"); zh_160x_print_char(&_lcd_160x_handle, "MODE:");
zh_160x_print_char(&_lcd_handle, _main_menu[0]); zh_160x_print_char(&_lcd_160x_handle, _main_menu[0]);
} }
static void _zh_timer_init(void) static void _zh_timer_init(void)
@@ -231,11 +232,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) 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) switch (event_id)
{ {
case ZH_BUTTON_EVENT: case ZH_BUTTON_EVENT:
zh_encoder_button_event_on_isr_t *button_event = event_data; zh_encoder_button_event_on_isr_t *button_event = (zh_encoder_button_event_on_isr_t *)event_data;
if (button_event->button_status == ENCODER_BUTTON_PRESSED) if (button_event->button_status == ZH_ENCODER_BUTTON_STATUS_PRESSED)
{ {
esp_timer_start_once(_inclinometer_reset_timer_handle, 2000000); esp_timer_start_once(_inclinometer_reset_timer_handle, 2000000);
_is_reset_mode = true; _is_reset_mode = true;
@@ -258,20 +260,38 @@ static void _zh_encoder_event_handler(void *arg, esp_event_base_t event_base, in
switch (_current_menu_value) switch (_current_menu_value)
{ {
case MODE_ANGLE_ANGLE: case MODE_ANGLE_ANGLE:
vTaskDelete(_a_inclinometer_task_handle); if (_a_inclinometer_task_handle != NULL)
vTaskDelete(_b_inclinometer_task_handle); {
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(&_a_inclinometer_handle);
zh_inclinometer_deinit(&_b_inclinometer_handle); zh_inclinometer_deinit(&_b_inclinometer_handle);
break; break;
case MODE_TACHO_TACHO: case MODE_TACHO_TACHO:
vTaskDelete(_a_tachometer_task_handle); if (_a_tachometer_task_handle != NULL)
vTaskDelete(_b_tachometer_task_handle); {
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(&_a_tachometer_handle);
zh_tachometer_deinit(&_b_tachometer_handle); zh_tachometer_deinit(&_b_tachometer_handle);
break; break;
case MODE_ANGLE_TACHO: case MODE_ANGLE_TACHO:
vTaskDelete(_a_inclinometer_task_handle); if (_a_inclinometer_task_handle != NULL)
vTaskDelete(_b_tachometer_task_handle); {
vTaskDelete(_a_inclinometer_task_handle);
}
if (_b_tachometer_task_handle != NULL)
{
vTaskDelete(_b_tachometer_task_handle);
}
zh_inclinometer_deinit(&_a_inclinometer_handle); zh_inclinometer_deinit(&_a_inclinometer_handle);
zh_tachometer_deinit(&_b_tachometer_handle); zh_tachometer_deinit(&_b_tachometer_handle);
break; break;
@@ -281,13 +301,13 @@ static void _zh_encoder_event_handler(void *arg, esp_event_base_t event_base, in
default: default:
break; break;
} }
zh_160x_clear_row(&_lcd_handle, 1); zh_160x_clear_row(&_lcd_160x_handle, 1);
zh_160x_set_cursor(&_lcd_handle, 0, 0); zh_160x_set_cursor(&_lcd_160x_handle, 0, 0);
zh_160x_on_cursor(&_lcd_handle, true); zh_160x_on_cursor(&_lcd_160x_handle, true);
} }
else else
{ {
zh_160x_off_cursor(&_lcd_handle); zh_160x_off_cursor(&_lcd_160x_handle);
switch (_current_menu_value) switch (_current_menu_value)
{ {
case MODE_ANGLE_ANGLE: case MODE_ANGLE_ANGLE:
@@ -303,8 +323,8 @@ static void _zh_encoder_event_handler(void *arg, esp_event_base_t event_base, in
_zh_b_tachometer_init(); _zh_b_tachometer_init();
break; break;
case MODE_REMOTE: case MODE_REMOTE:
zh_160x_set_cursor(&_lcd_handle, 1, 0); zh_160x_set_cursor(&_lcd_160x_handle, 1, 0);
zh_160x_print_char(&_lcd_handle, "NOT CONNECTED"); zh_160x_print_char(&_lcd_160x_handle, "NOT CONNECTED");
break; break;
default: default:
break; break;
@@ -313,15 +333,15 @@ static void _zh_encoder_event_handler(void *arg, esp_event_base_t event_base, in
} }
break; break;
case ZH_ENCODER_EVENT: 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) if (_is_menu_mode == true)
{ {
_current_menu_value = (uint8_t)encoder_event->encoder_position; // -V2004 _current_menu_value = (uint8_t)encoder_event->encoder_position;
zh_160x_clear_row(&_lcd_handle, 0); zh_160x_clear_row(&_lcd_160x_handle, 0);
zh_160x_set_cursor(&_lcd_handle, 0, 0); zh_160x_set_cursor(&_lcd_160x_handle, 0, 0);
zh_160x_print_char(&_lcd_handle, "MODE:"); zh_160x_print_char(&_lcd_160x_handle, "MODE:");
zh_160x_print_char(&_lcd_handle, _main_menu[(uint8_t)encoder_event->encoder_position]); // -V2004 zh_160x_print_char(&_lcd_160x_handle, _main_menu[(uint8_t)encoder_event->encoder_position]);
zh_160x_set_cursor(&_lcd_handle, 0, 0); zh_160x_set_cursor(&_lcd_160x_handle, 0, 0);
} }
else else
{ {
@@ -340,6 +360,8 @@ static void _zh_espnow_event_handler(void *arg, esp_event_base_t event_base, int
static void _zh_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) 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) switch (event_id)
{ {
case WIFI_EVENT_STA_START: case WIFI_EVENT_STA_START:
@@ -348,7 +370,10 @@ static void _zh_wifi_event_handler(void *arg, esp_event_base_t event_base, int32
case WIFI_EVENT_STA_DISCONNECTED: case WIFI_EVENT_STA_DISCONNECTED:
if (_is_wifi_connected == true) if (_is_wifi_connected == true)
{ {
vTaskDelete(_zh_stats_task_handle); if (_zh_stats_task_handle != NULL)
{
vTaskDelete(_zh_stats_task_handle);
}
zh_syslog_deinit(); zh_syslog_deinit();
_is_wifi_connected = false; _is_wifi_connected = false;
} }
@@ -364,7 +389,10 @@ 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(); zh_syslog_init_config_t config = ZH_SYSLOG_INIT_CONFIG_DEFAULT();
strcpy(config.syslog_ip, SYSLOG_IP); strcpy(config.syslog_ip, SYSLOG_IP);
zh_syslog_init(&config); 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; break;
default: default:
break; break;
@@ -373,6 +401,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) static void _zh_inclinometer_reset_timer_on_alarm_cb(void *arg)
{ {
(void)arg;
_is_reset_mode = false; _is_reset_mode = false;
_is_reset_occurred = true; _is_reset_occurred = true;
if (_is_menu_mode == false) if (_is_menu_mode == false)
@@ -394,11 +423,13 @@ static void _zh_inclinometer_reset_timer_on_alarm_cb(void *arg)
static void _zh_a_inclinometer_processing_task(void *pvParameter) 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); xSemaphoreTake(_lcd_mutex, portMAX_DELAY);
zh_160x_set_cursor(&_lcd_handle, 1, 0); zh_160x_set_cursor(&_lcd_160x_handle, 1, 0);
zh_160x_print_char(&_lcd_handle, "A:"); zh_160x_print_char(&_lcd_160x_handle, "A:");
zh_160x_print_float(&_lcd_handle, current_angle, 1); zh_160x_print_float(&_lcd_160x_handle, current_angle, 1);
xSemaphoreGive(_lcd_mutex); xSemaphoreGive(_lcd_mutex);
for (;;) for (;;)
{ {
@@ -407,10 +438,10 @@ static void _zh_a_inclinometer_processing_task(void *pvParameter)
{ {
prev_angle = current_angle; prev_angle = current_angle;
xSemaphoreTake(_lcd_mutex, portMAX_DELAY); xSemaphoreTake(_lcd_mutex, portMAX_DELAY);
zh_160x_set_cursor(&_lcd_handle, 1, 5); zh_160x_set_cursor(&_lcd_160x_handle, 1, 5);
zh_160x_print_char(&_lcd_handle, " "); zh_160x_print_char(&_lcd_160x_handle, " ");
zh_160x_set_cursor(&_lcd_handle, 1, 2); zh_160x_set_cursor(&_lcd_160x_handle, 1, 2);
zh_160x_print_float(&_lcd_handle, current_angle, 1); zh_160x_print_float(&_lcd_160x_handle, current_angle, 1);
xSemaphoreGive(_lcd_mutex); xSemaphoreGive(_lcd_mutex);
} }
vTaskDelay(100 / portTICK_PERIOD_MS); vTaskDelay(100 / portTICK_PERIOD_MS);
@@ -421,11 +452,13 @@ static void _zh_a_inclinometer_processing_task(void *pvParameter)
static void _zh_b_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); xSemaphoreTake(_lcd_mutex, portMAX_DELAY);
zh_160x_set_cursor(&_lcd_handle, 1, 8); zh_160x_set_cursor(&_lcd_160x_handle, 1, 8);
zh_160x_print_char(&_lcd_handle, "B:"); zh_160x_print_char(&_lcd_160x_handle, "B:");
zh_160x_print_float(&_lcd_handle, current_angle, 1); zh_160x_print_float(&_lcd_160x_handle, current_angle, 1);
xSemaphoreGive(_lcd_mutex); xSemaphoreGive(_lcd_mutex);
for (;;) for (;;)
{ {
@@ -434,10 +467,10 @@ static void _zh_b_inclinometer_processing_task(void *pvParameter)
{ {
prev_angle = current_angle; prev_angle = current_angle;
xSemaphoreTake(_lcd_mutex, portMAX_DELAY); xSemaphoreTake(_lcd_mutex, portMAX_DELAY);
zh_160x_set_cursor(&_lcd_handle, 1, 13); zh_160x_set_cursor(&_lcd_160x_handle, 1, 13);
zh_160x_print_char(&_lcd_handle, " "); zh_160x_print_char(&_lcd_160x_handle, " ");
zh_160x_set_cursor(&_lcd_handle, 1, 10); zh_160x_set_cursor(&_lcd_160x_handle, 1, 10);
zh_160x_print_float(&_lcd_handle, current_angle, 1); zh_160x_print_float(&_lcd_160x_handle, current_angle, 1);
xSemaphoreGive(_lcd_mutex); xSemaphoreGive(_lcd_mutex);
} }
vTaskDelay(100 / portTICK_PERIOD_MS); vTaskDelay(100 / portTICK_PERIOD_MS);
@@ -448,11 +481,13 @@ static void _zh_b_inclinometer_processing_task(void *pvParameter)
static void _zh_a_tachometer_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); xSemaphoreTake(_lcd_mutex, portMAX_DELAY);
zh_160x_set_cursor(&_lcd_handle, 1, 0); zh_160x_set_cursor(&_lcd_160x_handle, 1, 0);
zh_160x_print_char(&_lcd_handle, "A:"); zh_160x_print_char(&_lcd_160x_handle, "A:");
zh_160x_print_int(&_lcd_handle, current_rpm); zh_160x_print_int(&_lcd_160x_handle, current_rpm);
xSemaphoreGive(_lcd_mutex); xSemaphoreGive(_lcd_mutex);
for (;;) for (;;)
{ {
@@ -461,10 +496,10 @@ static void _zh_a_tachometer_processing_task(void *pvParameter)
{ {
prev_rpm = current_rpm; prev_rpm = current_rpm;
xSemaphoreTake(_lcd_mutex, portMAX_DELAY); xSemaphoreTake(_lcd_mutex, portMAX_DELAY);
zh_160x_set_cursor(&_lcd_handle, 1, 3); zh_160x_set_cursor(&_lcd_160x_handle, 1, 3);
zh_160x_print_char(&_lcd_handle, " "); zh_160x_print_char(&_lcd_160x_handle, " ");
zh_160x_set_cursor(&_lcd_handle, 1, 2); zh_160x_set_cursor(&_lcd_160x_handle, 1, 2);
zh_160x_print_int(&_lcd_handle, current_rpm); zh_160x_print_int(&_lcd_160x_handle, current_rpm);
xSemaphoreGive(_lcd_mutex); xSemaphoreGive(_lcd_mutex);
} }
vTaskDelay(100 / portTICK_PERIOD_MS); vTaskDelay(100 / portTICK_PERIOD_MS);
@@ -475,11 +510,13 @@ static void _zh_a_tachometer_processing_task(void *pvParameter)
static void _zh_b_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); xSemaphoreTake(_lcd_mutex, portMAX_DELAY);
zh_160x_set_cursor(&_lcd_handle, 1, 8); zh_160x_set_cursor(&_lcd_160x_handle, 1, 8);
zh_160x_print_char(&_lcd_handle, "B:"); zh_160x_print_char(&_lcd_160x_handle, "B:");
zh_160x_print_int(&_lcd_handle, current_rpm); zh_160x_print_int(&_lcd_160x_handle, current_rpm);
xSemaphoreGive(_lcd_mutex); xSemaphoreGive(_lcd_mutex);
for (;;) for (;;)
{ {
@@ -488,10 +525,10 @@ static void _zh_b_tachometer_processing_task(void *pvParameter)
{ {
prev_rpm = current_rpm; prev_rpm = current_rpm;
xSemaphoreTake(_lcd_mutex, portMAX_DELAY); xSemaphoreTake(_lcd_mutex, portMAX_DELAY);
zh_160x_set_cursor(&_lcd_handle, 1, 11); zh_160x_set_cursor(&_lcd_160x_handle, 1, 11);
zh_160x_print_char(&_lcd_handle, " "); zh_160x_print_char(&_lcd_160x_handle, " ");
zh_160x_set_cursor(&_lcd_handle, 1, 10); zh_160x_set_cursor(&_lcd_160x_handle, 1, 10);
zh_160x_print_int(&_lcd_handle, current_rpm); zh_160x_print_int(&_lcd_160x_handle, current_rpm);
xSemaphoreGive(_lcd_mutex); xSemaphoreGive(_lcd_mutex);
} }
vTaskDelay(100 / portTICK_PERIOD_MS); vTaskDelay(100 / portTICK_PERIOD_MS);
@@ -502,49 +539,50 @@ static void _zh_b_tachometer_processing_task(void *pvParameter)
static void _zh_stats_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(); const esp_app_desc_t *esp_app_desc = esp_app_get_description();
for (;;) for (;;)
{ {
char buffer[1024] = {0}; char buffer[1024] = {0};
const zh_encoder_stats_t *encoder_stats = zh_encoder_get_stats(); const zh_encoder_stats_t *encoder_stats = zh_encoder_get_stats();
const zh_pcf8574_stats_t *pcf8574_stats = zh_pcf8574_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); 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); 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); 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); 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); 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); vTaskDelay(500 / portTICK_PERIOD_MS);
sprintf(buffer, "B tachometer task minimum free stack size: %ld.\n", _task_stats.b_tachometer_task_min_stack_size); snprintf(buffer, sizeof(buffer), "Stats task minimum free stack size: %lu.\n", (uint32_t)uxTaskGetStackHighWaterMark(NULL));
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));
zh_syslog_send(ZH_KERN, (uint32_t)uxTaskGetStackHighWaterMark(NULL) > 100 ? ZH_INFO : ZH_WARNING, esp_app_desc->project_name, "zh_syslog", buffer); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); vTaskDelay(60000 / portTICK_PERIOD_MS);
} }
+72 -53
View File
@@ -1,5 +1,18 @@
/** /**
* @file ate0005.h * @file ate0005.h
*
* @brief Header file for ATE0005 — Universal Optical 2-Channel Angle Gauge / Tachometer
*
* This header defines task priorities, stack sizes, mode constants,
* WiFi configuration, GPIO pin mappings, and data structures for the
* ATE0005 device running on ESP32 platform with FreeRTOS.
*
* Key features:
* - Task configuration for inclinometer, tachometer, encoder, and stats
* - WiFi AP/STA mode configuration
* - I2C and GPIO pin definitions for peripherals
* - Mode selection constants for different operating modes
* - LCD display and PCF8574 expander macros
*/ */
#pragma once #pragma once
@@ -15,80 +28,86 @@
#include "zh_espnow.h" #include "zh_espnow.h"
#include "zh_syslog.h" #include "zh_syslog.h"
#define STATS_TASK_PRIORITY tskIDLE_PRIORITY #define STATS_TASK_PRIORITY tskIDLE_PRIORITY /*!< Priority of the statistics logging task. */
#define STATS_TASK_STACK_SIZE configMINIMAL_STACK_SIZE + 1280 #define STATS_TASK_STACK_SIZE configMINIMAL_STACK_SIZE + 1280 /*!< Stack size for the statistics logging task. */
#define A_INCLINOMETER_TASK_PRIORITY tskIDLE_PRIORITY + 5 #define A_INCLINOMETER_TASK_PRIORITY tskIDLE_PRIORITY + 5 /*!< Priority of the A inclinometer processing task. */
#define A_INCLINOMETER_TASK_STACK_SIZE configMINIMAL_STACK_SIZE + 512 #define A_INCLINOMETER_TASK_STACK_SIZE configMINIMAL_STACK_SIZE + 512 /*!< Stack size for the A inclinometer processing task. */
#define B_INCLINOMETER_TASK_PRIORITY tskIDLE_PRIORITY + 5 #define B_INCLINOMETER_TASK_PRIORITY tskIDLE_PRIORITY + 5 /*!< Priority of the B inclinometer processing task. */
#define B_INCLINOMETER_TASK_STACK_SIZE configMINIMAL_STACK_SIZE + 512 #define B_INCLINOMETER_TASK_STACK_SIZE configMINIMAL_STACK_SIZE + 512 /*!< Stack size for the B inclinometer processing task. */
#define A_TACHOMETER_TASK_PRIORITY tskIDLE_PRIORITY + 5 #define A_TACHOMETER_TASK_PRIORITY tskIDLE_PRIORITY + 5 /*!< Priority of the A tachometer processing task. */
#define A_TACHOMETER_TASK_STACK_SIZE configMINIMAL_STACK_SIZE + 512 #define A_TACHOMETER_TASK_STACK_SIZE configMINIMAL_STACK_SIZE + 512 /*!< Stack size for the A tachometer processing task. */
#define B_TACHOMETER_TASK_PRIORITY tskIDLE_PRIORITY + 5 #define B_TACHOMETER_TASK_PRIORITY tskIDLE_PRIORITY + 5 /*!< Priority of the B tachometer processing task. */
#define B_TACHOMETER_TASK_STACK_SIZE configMINIMAL_STACK_SIZE + 512 #define B_TACHOMETER_TASK_STACK_SIZE configMINIMAL_STACK_SIZE + 512 /*!< Stack size for the B tachometer processing task. */
#define ENCODER_TASK_PRIORITY tskIDLE_PRIORITY + 4 #define ENCODER_TASK_PRIORITY tskIDLE_PRIORITY + 4 /*!< Priority of the mode encoder task. */
#define ENCODER_TASK_STACK_SIZE configMINIMAL_STACK_SIZE #define ENCODER_TASK_STACK_SIZE configMINIMAL_STACK_SIZE /*!< Stack size for the mode encoder task. */
#define EXPANDER_TASK_PRIORITY tskIDLE_PRIORITY + 4 #define EXPANDER_TASK_PRIORITY tskIDLE_PRIORITY + 4 /*!< Priority of the PCF8574 expander task. */
#define EXPANDER_TASK_STACK_SIZE configMINIMAL_STACK_SIZE #define EXPANDER_TASK_STACK_SIZE configMINIMAL_STACK_SIZE /*!< Stack size for the PCF8574 expander task. */
#define TRIAC_ON true // #define TRIAC_ON true /*!< Triac enabled state. */
#define TRIAC_OFF false // #define TRIAC_OFF false /*!< Triac disabled state. */
#define ENCODER_BUTTON_RELEASED true // #define ENCODER_BUTTON_RELEASED true /*!< Encoder button released state. */
#define ENCODER_BUTTON_PRESSED false // #define ENCODER_BUTTON_PRESSED false /*!< Encoder button pressed state. */
#define LED_OFF ZH_PCF8574_GPIO_LOW // #define LED_OFF ZH_PCF8574_GPIO_LOW /*!< LED turned off (low level). */
#define LED_ON ZH_PCF8574_GPIO_HIGH // #define LED_ON ZH_PCF8574_GPIO_HIGH /*!< LED turned on (high level). */
#define RELAY_OFF ZH_PCF8574_GPIO_LOW // #define RELAY_OFF ZH_PCF8574_GPIO_LOW /*!< Relay disconnected (low level). */
#define RELAY_ON ZH_PCF8574_GPIO_HIGH // #define RELAY_ON ZH_PCF8574_GPIO_HIGH /*!< Relay connected (high level). */
#define MODE_ANGLE_ANGLE 0 #define MODE_ANGLE_ANGLE 0 /*!< Operating mode: both inclinometers active. */
#define MAIN_MENU_ANGLE_ANGLE_NAME "ANGLE/ANGLE" #define MAIN_MENU_ANGLE_ANGLE_NAME "ANGLE/ANGLE" /*!< Menu label for angle/angle mode. */
#define MODE_TACHO_TACHO 1 #define MODE_TACHO_TACHO 1 /*!< Operating mode: both tachometers active. */
#define MAIN_MENU_TACHO_TACHO_NAME "TACHO/TACHO" #define MAIN_MENU_TACHO_TACHO_NAME "TACHO/TACHO" /*!< Menu label for tachometer/tachometer mode. */
#define MODE_ANGLE_TACHO 2 #define MODE_ANGLE_TACHO 2 /*!< Operating mode: A inclinometer and B tachometer active. */
#define MAIN_MENU_ANGLE_TACHO_NAME "ANGLE/TACHO" #define MAIN_MENU_ANGLE_TACHO_NAME "ANGLE/TACHO" /*!< Menu label for angle/tachometer mode. */
#define MODE_REMOTE 3 #define MODE_REMOTE 3 /*!< Operating mode: remote control via ESP-NOW. */
#define MAIN_MENU_REMOTE_NAME "REMOTE" #define MAIN_MENU_REMOTE_NAME "REMOTE" /*!< Menu label for remote mode. */
#define WIFI_AP_SSID "ATE0005" #define WIFI_AP_SSID "ATE0005" /*!< WiFi AP SSID. */
#define WIFI_AP_PASS "repairlab" #define WIFI_AP_PASS "repairlab" /*!< WiFi AP password. */
#define WIFI_AP_CHANNEL 1 #define WIFI_AP_CHANNEL 1 /*!< WiFi AP channel. */
#define MAX_AP_CONNECTION 4 #define MAX_AP_CONNECTION 4 /*!< Maximum number of stations connected to AP. */
#define WIFI_STA_SSID "rick_professor" #define WIFI_STA_SSID "rick_professor" /*!< WiFi STA SSID. */
#define WIFI_STA_PASS "repairlab" #define WIFI_STA_PASS "repairlab" /*!< WiFi STA password. */
#define WIFI_STA_MAXIMUM_RETRY 10 #define WIFI_STA_MAXIMUM_RETRY 10 /*!< Maximum number of reconnection attempts for STA mode. */
#define SYSLOG_IP "77.51.201.8" #define SYSLOG_IP "77.51.201.8" /*!< IP address of the remote syslog server. */
#define I2C_SCL_GPIO GPIO_NUM_22 #define I2C_SCL_GPIO GPIO_NUM_22 /*!< I2C clock line GPIO. */
#define I2C_SDA_GPIO GPIO_NUM_21 #define I2C_SDA_GPIO GPIO_NUM_21 /*!< I2C data line GPIO. */
#define LCD_I2C_ADDRESS 0x20 /*!< U2. */ #define LCD_I2C_ADDRESS 0x20 /*!< I2C address of the LCD PCF8574 expander (U2). */
#define MODE_ENCODER_NUMBER 0x01 /*!< Connector EN1. */ #define MODE_ENCODER_NUMBER 0x01 /*!< Encoder instance number (Connector EN1). */
#define MODE_ENCODER_A_GPIO GPIO_NUM_27 #define MODE_ENCODER_A_GPIO GPIO_NUM_27 /*!< Mode encoder A-phase GPIO. */
#define MODE_ENCODER_B_GPIO GPIO_NUM_26 #define MODE_ENCODER_B_GPIO GPIO_NUM_26 /*!< Mode encoder B-phase GPIO. */
#define MODE_ENCODER_S_GPIO GPIO_NUM_25 #define MODE_ENCODER_S_GPIO GPIO_NUM_25 /*!< Mode encoder switch GPIO. */
#define A_OPTICAL_DEVICE_A_GPIO GPIO_NUM_14 /*!< Connector EN2. */ #define A_OPTICAL_DEVICE_A_GPIO GPIO_NUM_14 /*!< Optical device A-phase GPIO for channel A (Connector EN2). */
#define A_OPTICAL_DEVICE_B_GPIO GPIO_NUM_13 #define A_OPTICAL_DEVICE_B_GPIO GPIO_NUM_13 /*!< Optical device B-phase GPIO for channel A. */
#define B_OPTICAL_DEVICE_A_GPIO GPIO_NUM_18 /*!< Connector EN3. */ #define B_OPTICAL_DEVICE_A_GPIO GPIO_NUM_18 /*!< Optical device A-phase GPIO for channel B (Connector EN3). */
#define B_OPTICAL_DEVICE_B_GPIO GPIO_NUM_19 #define B_OPTICAL_DEVICE_B_GPIO GPIO_NUM_19 /*!< Optical device B-phase GPIO for channel B. */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
{ {
#endif #endif
/**
* @brief Structure holding minimum free stack sizes for processing tasks.
*
* Tracks the minimum free stack size observed at runtime for each
* processing task, used for syslog monitoring and stack overflow detection.
*/
typedef struct typedef struct
{ {
uint32_t a_inclinometer_task_min_stack_size; 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; 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; 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; uint32_t b_tachometer_task_min_stack_size; /*!< Minimum free stack size of the B tachometer task. */
} task_stats_t; } task_stats_t;
#ifdef __cplusplus #ifdef __cplusplus
+24
View File
@@ -0,0 +1,24 @@
description: Universal Optical 2-Channel Angle Gauge / Tachometer
url: https://github.com/aZholtikov/ate0005
version: "1.1.2"
license: "Apache-2.0"
maintainers:
- "Alexey Zholtikov <alexey.zholtikov@yandex.ru>"
dependencies:
idf: ">=5.0"
zh_160x_i2c:
git: "https://github.com/aZholtikov/zh_160x_i2c.git"
zh_syslog:
git: "https://github.com/aZholtikov/zh_syslog.git"
zh_ota_server:
git: "https://github.com/aZholtikov/zh_ota_server.git"
zh_encoder:
git: "https://github.com/aZholtikov/zh_encoder.git"
zh_inclinometer:
git: "https://github.com/aZholtikov/zh_inclinometer"
version: "dev"
zh_tachometer:
git: "https://github.com/aZholtikov/zh_tachometer"
version: "dev"
zh_espnow:
git: "https://github.com/aZholtikov/zh_espnow"
-13
View File
@@ -3,19 +3,6 @@ CONFIG_BOOTLOADER_LOG_LEVEL_ERROR=y
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_GPIO_CTRL_FUNC_IN_IRAM=y
CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM=y
CONFIG_GPTIMER_ISR_CACHE_SAFE=y
CONFIG_I2C_ISR_IRAM_SAFE=y
CONFIG_LEDC_CTRL_FUNC_IN_IRAM=y
CONFIG_PCNT_CTRL_FUNC_IN_IRAM=y
CONFIG_PCNT_ISR_IRAM_SAFE=y
CONFIG_RMT_RECV_FUNC_IN_IRAM=y
CONFIG_RMT_TX_ISR_CACHE_SAFE=y
CONFIG_RMT_RX_ISR_CACHE_SAFE=y
CONFIG_SPI_MASTER_ISR_IN_IRAM=y
CONFIG_UART_ISR_IN_IRAM=y
CONFIG_HTTPD_WS_SUPPORT=y
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
CONFIG_FREERTOS_HZ=1000 CONFIG_FREERTOS_HZ=1000
CONFIG_LOG_DEFAULT_LEVEL_ERROR=y CONFIG_LOG_DEFAULT_LEVEL_ERROR=y