Add find-me LED locate on master and slaves via ESP-NOW.

UART FIND_ME (client_id 0 = local ring, >0 = unicast), ESPNOW_FIND_ME payload, CLI/dashboard buttons per slave.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-19 22:04:07 +02:00
co-authored by Cursor
parent 8931912583
commit efd6260201
25 changed files with 659 additions and 84 deletions
+36 -9
View File
@@ -20,6 +20,9 @@ static led_strip_handle_t led_ring;
#define LED_RING_PIN 7
#define LED_RING_BLINK_ON_MS 350
#define LED_RING_BLINK_OFF_MS 150
#define LED_RING_FIND_ME_ON_MS 300
#define LED_RING_FIND_ME_OFF_MS 150
#define LED_RING_FIND_ME_BLINKS_PER_COLOR 3
static QueueHandle_t led_queue;
@@ -67,6 +70,21 @@ static void ring_fill_color(uint8_t r, uint8_t g, uint8_t b) {
}
}
static void ring_blink_scaled(uint8_t r, uint8_t g, uint8_t b, uint8_t intensity,
uint8_t count, uint16_t on_ms, uint16_t off_ms) {
led_ring_scale_rgb(&r, &g, &b, intensity);
for (uint8_t n = 0; n < count; n++) {
ring_fill_color(r, g, b);
led_strip_refresh(led_ring);
vTaskDelay(pdMS_TO_TICKS(on_ms));
led_strip_clear(led_ring);
led_strip_refresh(led_ring);
if (n + 1 < count) {
vTaskDelay(pdMS_TO_TICKS(off_ms));
}
}
}
void vTaskLedRing(void *pvParameters) {
led_strip_config_t ring_config = {
.strip_gpio_num = LED_RING_PIN,
@@ -109,15 +127,19 @@ void vTaskLedRing(void *pvParameters) {
} else if (cmd.mode == LED_CMD_BLINK) {
uint16_t on_ms = cmd.blink_ms > 0 ? cmd.blink_ms : LED_RING_BLINK_ON_MS;
uint8_t count = cmd.blink_count > 0 ? cmd.blink_count : 1;
for (uint8_t n = 0; n < count; n++) {
ring_fill_color(r, g, b);
led_strip_refresh(led_ring);
vTaskDelay(pdMS_TO_TICKS(on_ms));
led_strip_clear(led_ring);
led_strip_refresh(led_ring);
if (n + 1 < count) {
vTaskDelay(pdMS_TO_TICKS(LED_RING_BLINK_OFF_MS));
ring_blink_scaled(cmd.r, cmd.g, cmd.b, cmd.intensity, count, on_ms,
LED_RING_BLINK_OFF_MS);
continue;
} else if (cmd.mode == LED_CMD_FIND_ME) {
static const struct {
uint8_t r, g, b;
} colors[] = {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}};
for (size_t c = 0; c < sizeof(colors) / sizeof(colors[0]); c++) {
ring_blink_scaled(colors[c].r, colors[c].g, colors[c].b,
LED_RING_FULL_INTENSITY, LED_RING_FIND_ME_BLINKS_PER_COLOR,
LED_RING_FIND_ME_ON_MS, LED_RING_FIND_ME_OFF_MS);
if (c + 1 < sizeof(colors) / sizeof(colors[0])) {
vTaskDelay(pdMS_TO_TICKS(LED_RING_FIND_ME_OFF_MS));
}
}
continue;
@@ -195,3 +217,8 @@ void led_ring_blink_once(uint8_t r, uint8_t g, uint8_t b) {
void led_ring_ota_success(void) { led_ring_blink_once(0, 255, 0); }
void led_ring_ota_failed(void) { led_ring_blink_once(255, 0, 0); }
void led_ring_find_me(void) {
led_command_t cmd = {.mode = LED_CMD_FIND_ME};
led_ring_send_command(&cmd);
}