esp32 improvements

- better clock seconds
- better alarm (image before audio, supposedly)
This commit is contained in:
Mikkeli Matlock
2026-02-15 22:55:53 +09:00
parent 0b2f274719
commit d63322d304
3 changed files with 48 additions and 16 deletions

View File

@@ -35,6 +35,7 @@ static uint8_t s_img_buf[STATUS_IMG_BYTES];
static lv_img_dsc_t s_img_dsc; 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_pending = false; /* expecting binary frame with image data */
static volatile bool s_img_updated = false; /* new image ready for UI consumption */ 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 */ /* Forward declarations */
static void playback_task(void *arg); 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) { if (len == STATUS_IMG_BYTES) {
memcpy(s_img_buf, data, STATUS_IMG_BYTES); memcpy(s_img_buf, data, STATUS_IMG_BYTES);
s_img_updated = true; s_img_updated = true;
if (s_img_notify_task) {
xTaskNotifyGive(s_img_notify_task);
}
ESP_LOGI(TAG, "Status image received (%d bytes)", len); ESP_LOGI(TAG, "Status image received (%d bytes)", len);
} else { } else {
ESP_LOGW(TAG, "Status image size mismatch: got %d, expected %d", len, STATUS_IMG_BYTES); 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; 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) const lv_img_dsc_t *audio_client_get_status_image(bool *updated)
{ {
if (updated) { if (updated) {

View File

@@ -1,6 +1,8 @@
#pragma once #pragma once
#include <stdbool.h> #include <stdbool.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include "lvgl.h" #include "lvgl.h"
#ifdef __cplusplus #ifdef __cplusplus
@@ -30,6 +32,12 @@ void audio_client_stop(void);
/** Get current audio client state. */ /** Get current audio client state. */
audio_state_t audio_client_get_state(void); 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. * Get the latest status image descriptor.
* @param updated Set to true if a new image arrived since last call, then reset. * @param updated Set to true if a new image arrived since last call, then reset.

View File

@@ -82,11 +82,13 @@ void UserApp_TaskInit(void)
/* Start WebSocket client */ /* Start WebSocket client */
ws_client_start(); ws_client_start();
/* Start audio streaming client */
audio_client_start();
/* Sensor polling task - Core 1, 4KB stack */ /* 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 */ /* Button handling task - Core 1 */
xTaskCreatePinnedToCore(button_task, "button", 2 * 1024, NULL, 2, NULL, 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; float temp = 0, humidity = 0;
rtcTimeStruct_t rtc_time = {}; rtcTimeStruct_t rtc_time = {};
int sensor_divider = 0; int sensor_divider = 0;
TickType_t last_sensor_tick = xTaskGetTickCount();
for (;;) { 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); Rtc_GetTime(&rtc_time);
/* Read SHTC3 + battery every 5 seconds */ /* Read SHTC3 + battery every 5 seconds */
@@ -203,23 +228,13 @@ static void sensor_task(void *arg)
} }
sensor_divider = (sensor_divider + 1) % 5; sensor_divider = (sensor_divider + 1) % 5;
/* Update clock every second */ /* Update clock */
if (Lvgl_lock(100)) { if (Lvgl_lock(100)) {
dashboard_ui_update_time(rtc_time.hour, rtc_time.minute, rtc_time.second, dashboard_ui_update_time(rtc_time.hour, rtc_time.minute, rtc_time.second,
rtc_time.year, rtc_time.month, rtc_time.day, rtc_time.year, rtc_time.month, rtc_time.day,
rtc_time.week); rtc_time.week);
Lvgl_unlock(); 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));
} }
} }