diff --git a/components/audio_client/audio_client.cpp b/components/audio_client/audio_client.cpp index cf77a43..7b575bc 100644 --- a/components/audio_client/audio_client.cpp +++ b/components/audio_client/audio_client.cpp @@ -35,6 +35,7 @@ static uint8_t s_img_buf[STATUS_IMG_BYTES]; static lv_img_dsc_t s_img_dsc; static volatile bool s_img_pending = false; /* expecting binary frame with image data */ static volatile bool s_img_updated = false; /* new image ready for UI consumption */ +static TaskHandle_t s_img_notify_task = NULL; /* task to wake on new image */ /* Forward declarations */ static void playback_task(void *arg); @@ -121,6 +122,9 @@ static void handle_binary_frame(const uint8_t *data, int len) if (len == STATUS_IMG_BYTES) { memcpy(s_img_buf, data, STATUS_IMG_BYTES); s_img_updated = true; + if (s_img_notify_task) { + xTaskNotifyGive(s_img_notify_task); + } ESP_LOGI(TAG, "Status image received (%d bytes)", len); } else { ESP_LOGW(TAG, "Status image size mismatch: got %d, expected %d", len, STATUS_IMG_BYTES); @@ -262,6 +266,11 @@ audio_state_t audio_client_get_state(void) return s_state; } +void audio_client_set_image_notify_task(TaskHandle_t task) +{ + s_img_notify_task = task; +} + const lv_img_dsc_t *audio_client_get_status_image(bool *updated) { if (updated) { diff --git a/components/audio_client/audio_client.h b/components/audio_client/audio_client.h index c5c0866..a061f90 100644 --- a/components/audio_client/audio_client.h +++ b/components/audio_client/audio_client.h @@ -1,6 +1,8 @@ #pragma once #include +#include +#include #include "lvgl.h" #ifdef __cplusplus @@ -30,6 +32,12 @@ void audio_client_stop(void); /** Get current audio client state. */ audio_state_t audio_client_get_state(void); +/** + * Register a task to be notified (via xTaskNotifyGive) when a new status + * image arrives. Call before audio_client_start(). + */ +void audio_client_set_image_notify_task(TaskHandle_t task); + /** * Get the latest status image descriptor. * @param updated Set to true if a new image arrived since last call, then reset. diff --git a/components/user_app/user_app.cpp b/components/user_app/user_app.cpp index 4a100bc..4677a7b 100644 --- a/components/user_app/user_app.cpp +++ b/components/user_app/user_app.cpp @@ -82,11 +82,13 @@ void UserApp_TaskInit(void) /* Start WebSocket client */ ws_client_start(); - /* Start audio streaming client */ - audio_client_start(); - /* Sensor polling task - Core 1, 4KB stack */ - xTaskCreatePinnedToCore(sensor_task, "sensor", 4 * 1024, NULL, 3, NULL, 1); + TaskHandle_t sensor_handle = NULL; + xTaskCreatePinnedToCore(sensor_task, "sensor", 4 * 1024, NULL, 3, &sensor_handle, 1); + + /* Start audio streaming client, notify sensor task on new images */ + audio_client_set_image_notify_task(sensor_handle); + audio_client_start(); /* Button handling task - Core 1 */ xTaskCreatePinnedToCore(button_task, "button", 2 * 1024, NULL, 2, NULL, 1); @@ -182,9 +184,32 @@ static void sensor_task(void *arg) float temp = 0, humidity = 0; rtcTimeStruct_t rtc_time = {}; int sensor_divider = 0; + TickType_t last_sensor_tick = xTaskGetTickCount(); for (;;) { - /* Read RTC every second */ + /* + * Sleep until either: + * - a new status image arrives (xTaskNotifyGive from audio_client), or + * - 1 second elapses (clock refresh cadence) + */ + ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(1000)); + + /* Check for status image updates immediately */ + bool img_updated = false; + const lv_img_dsc_t *img = audio_client_get_status_image(&img_updated); + if (img_updated && Lvgl_lock(100)) { + dashboard_ui_update_status_image(img); + Lvgl_unlock(); + } + + /* Sensor + clock updates at ~1s cadence (skip if woken early) */ + TickType_t now = xTaskGetTickCount(); + if ((now - last_sensor_tick) < pdMS_TO_TICKS(900)) { + continue; + } + last_sensor_tick = now; + + /* Read RTC */ Rtc_GetTime(&rtc_time); /* Read SHTC3 + battery every 5 seconds */ @@ -203,23 +228,13 @@ static void sensor_task(void *arg) } sensor_divider = (sensor_divider + 1) % 5; - /* Update clock every second */ + /* Update clock */ if (Lvgl_lock(100)) { dashboard_ui_update_time(rtc_time.hour, rtc_time.minute, rtc_time.second, rtc_time.year, rtc_time.month, rtc_time.day, rtc_time.week); Lvgl_unlock(); } - - /* Poll for status image updates */ - bool img_updated = false; - const lv_img_dsc_t *img = audio_client_get_status_image(&img_updated); - if (img_updated && Lvgl_lock(100)) { - dashboard_ui_update_status_image(img); - Lvgl_unlock(); - } - - vTaskDelay(pdMS_TO_TICKS(1000)); } }