esp32 improvements
- better clock seconds - better alarm (image before audio, supposedly)
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user