diff --git a/firmware/esp32-csi-node/main/led_indicator.c b/firmware/esp32-csi-node/main/led_indicator.c index ae1b80da..e50741d5 100644 --- a/firmware/esp32-csi-node/main/led_indicator.c +++ b/firmware/esp32-csi-node/main/led_indicator.c @@ -81,6 +81,40 @@ static void led_task(void *arg) led_strip_refresh(s_led_strip); vTaskDelay(pdMS_TO_TICKS(500)); break; + + case LED_STATE_MMWAVE_ERROR: + /* Slow Blinking Yellow */ + toggle = !toggle; + if (toggle) { + led_strip_set_pixel(s_led_strip, 0, 100, 100, 0); + } else { + led_strip_clear(s_led_strip); + } + led_strip_refresh(s_led_strip); + vTaskDelay(pdMS_TO_TICKS(1000)); + break; + + case LED_STATE_SWARM_ERROR: + /* Slow Blinking Magenta */ + toggle = !toggle; + if (toggle) { + led_strip_set_pixel(s_led_strip, 0, 100, 0, 100); + } else { + led_strip_clear(s_led_strip); + } + led_strip_refresh(s_led_strip); + vTaskDelay(pdMS_TO_TICKS(1000)); + break; + + case LED_STATE_SWARM_ACTIVE: + /* Quick Blip Magenta */ + led_strip_set_pixel(s_led_strip, 0, 100, 0, 100); + led_strip_refresh(s_led_strip); + vTaskDelay(pdMS_TO_TICKS(100)); + led_strip_clear(s_led_strip); + led_strip_refresh(s_led_strip); + s_current_state = LED_STATE_CONNECTED; + break; } } } diff --git a/firmware/esp32-csi-node/main/led_indicator.h b/firmware/esp32-csi-node/main/led_indicator.h index d868086f..dcedb6d1 100644 --- a/firmware/esp32-csi-node/main/led_indicator.h +++ b/firmware/esp32-csi-node/main/led_indicator.h @@ -17,6 +17,9 @@ typedef enum { LED_STATE_CONNECTED, LED_STATE_WIFI_ERROR, LED_STATE_MOCK_MODE, + LED_STATE_MMWAVE_ERROR, + LED_STATE_SWARM_ERROR, + LED_STATE_SWARM_ACTIVE, } led_indicator_state_t; /** diff --git a/firmware/esp32-csi-node/main/main.c b/firmware/esp32-csi-node/main/main.c index 63ca4cbd..779cb60f 100644 --- a/firmware/esp32-csi-node/main/main.c +++ b/firmware/esp32-csi-node/main/main.c @@ -291,8 +291,11 @@ void app_main(void) ESP_LOGI(TAG, "mmWave sensor: %s (caps=0x%04x)", mmwave_type_name(mw.type), mw.capabilities); } - } else { + } else if (mmwave_ret == ESP_ERR_NOT_FOUND) { ESP_LOGI(TAG, "No mmWave sensor detected (CSI-only mode)"); + } else { + ESP_LOGE(TAG, "mmWave sensor init error: %s", esp_err_to_name(mmwave_ret)); + led_indicator_set_state(LED_STATE_MMWAVE_ERROR); } /* ADR-066: Initialize swarm bridge to Cognitum Seed (if configured). */ diff --git a/firmware/esp32-csi-node/main/swarm_bridge.c b/firmware/esp32-csi-node/main/swarm_bridge.c index b6b485b2..deeb5d68 100644 --- a/firmware/esp32-csi-node/main/swarm_bridge.c +++ b/firmware/esp32-csi-node/main/swarm_bridge.c @@ -19,6 +19,7 @@ #include "esp_app_desc.h" #include "esp_netif.h" #include "esp_http_client.h" +#include "led_indicator.h" static const char *TAG = "swarm"; @@ -233,6 +234,7 @@ static void swarm_task(void *arg) /* Get firmware version string. */ const esp_app_desc_t *app = esp_app_get_description(); const char *fw_ver = app ? app->version : "unknown"; + ESP_LOGI(TAG, "Firmware version: %s", fw_ver); /* Get local IP. */ char ip_str[16]; @@ -251,8 +253,10 @@ static void swarm_task(void *arg) if (swarm_post_json(client, json, len) == ESP_OK) { s_cnt_regs++; ESP_LOGI(TAG, "registered node %u with seed (id=%lu)", s_node_id, (unsigned long)reg_id); + led_indicator_set_state(LED_STATE_SWARM_ACTIVE); } else { ESP_LOGW(TAG, "registration failed — will retry on next heartbeat"); + led_indicator_set_state(LED_STATE_SWARM_ERROR); } } @@ -278,15 +282,12 @@ static void swarm_task(void *arg) xSemaphoreGive(s_mutex); uint32_t uptime_s = (uint32_t)(esp_timer_get_time() / 1000000ULL); - uint32_t free_heap = esp_get_free_heap_size(); uint32_t ts = (uint32_t)(esp_timer_get_time() / 1000ULL); /* ---- Heartbeat ---- */ if ((now - last_heartbeat) >= pdMS_TO_TICKS(s_cfg.heartbeat_sec * 1000U)) { last_heartbeat = now; - bool presence = vit_valid && (vit.flags & 0x01); - /* Heartbeat ID: node_id * 1000000 + 100000 + ts_sec */ uint32_t hb_id = (uint32_t)s_node_id * 1000000U + 100000U + (uptime_s % 100000U); char json[SWARM_JSON_BUF]; @@ -297,6 +298,9 @@ static void swarm_task(void *arg) if (swarm_post_json(client, json, len) == ESP_OK) { s_cnt_heartbeats++; + led_indicator_set_state(LED_STATE_SWARM_ACTIVE); + } else { + led_indicator_set_state(LED_STATE_SWARM_ERROR); } } @@ -316,6 +320,9 @@ static void swarm_task(void *arg) if (swarm_post_json(client, json, len) == ESP_OK) { s_cnt_ingests++; + led_indicator_set_state(LED_STATE_SWARM_ACTIVE); + } else { + led_indicator_set_state(LED_STATE_SWARM_ERROR); } } }