diff --git a/include/config.h b/include/config.h index 3df1b16..5a30371 100644 --- a/include/config.h +++ b/include/config.h @@ -73,6 +73,7 @@ constexpr uint8_t BATCH_QUEUE_DEPTH = 10; constexpr BatchRetryPolicy BATCH_RETRY_POLICY = BatchRetryPolicy::Keep; constexpr uint32_t WATCHDOG_TIMEOUT_SEC = 120; constexpr bool ENABLE_HA_DISCOVERY = true; +constexpr bool SERIAL_DEBUG_MODE = true; constexpr uint8_t NUM_SENDERS = 1; inline constexpr uint16_t EXPECTED_SENDER_IDS[NUM_SENDERS] = { diff --git a/src/main.cpp b/src/main.cpp index 92702eb..25f440e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,8 +13,10 @@ #include "display_ui.h" #include "test_mode.h" #include +#include #ifdef ARDUINO_ARCH_ESP32 #include +#include #endif static DeviceRole g_role = DeviceRole::Sender; @@ -83,6 +85,19 @@ static MeterData g_inflight_samples[METER_BATCH_MAX_SAMPLES]; static uint8_t g_inflight_count = 0; static uint16_t g_inflight_batch_id = 0; static bool g_inflight_active = false; +static uint32_t g_last_debug_log_ms = 0; + +static void serial_debug_printf(const char *fmt, ...) { + if (!SERIAL_DEBUG_MODE) { + return; + } + char buf[256]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + Serial.println(buf); +} static uint16_t g_last_batch_id_rx[NUM_SENDERS] = {}; @@ -359,6 +374,10 @@ static bool send_inflight_batch(uint32_t ts_for_display) { if (!meterBatchToJson(g_inflight_samples, g_inflight_count, g_inflight_batch_id, json, &g_sender_faults, g_sender_last_error)) { return false; } + if (SERIAL_DEBUG_MODE) { + serial_debug_printf("tx: batch_id=%u count=%u json_len=%u", g_inflight_batch_id, g_inflight_count, static_cast(json.length())); + Serial.println(json); + } static uint8_t compressed[BATCH_MAX_COMPRESSED]; size_t compressed_len = 0; @@ -369,6 +388,9 @@ static bool send_inflight_batch(uint32_t ts_for_display) { bool ok = send_batch_payload(compressed, compressed_len, ts_for_display, g_inflight_batch_id); if (ok) { g_last_batch_send_ms = millis(); + serial_debug_printf("tx: sent batch_id=%u len=%u", g_inflight_batch_id, static_cast(compressed_len)); + } else { + serial_debug_printf("tx: send failed batch_id=%u", g_inflight_batch_id); } return ok; } @@ -496,6 +518,13 @@ void setup() { g_boot_ms = millis(); g_role = detect_role(); init_device_ids(g_short_id, g_device_id, sizeof(g_device_id)); + if (SERIAL_DEBUG_MODE) { +#ifdef ARDUINO_ARCH_ESP32 + serial_debug_printf("boot: reset_reason=%d", static_cast(esp_reset_reason())); +#endif + serial_debug_printf("boot: role=%s short_id=%04X dev=%s", g_role == DeviceRole::Sender ? "sender" : "receiver", + g_short_id, g_device_id); + } lora_init(); display_init(); @@ -545,6 +574,17 @@ static void sender_loop() { uint32_t now_ms = millis(); display_set_sender_queue(g_batch_count, g_build_count > 0); display_set_sender_batches(g_last_acked_batch_id, g_batch_id); + if (SERIAL_DEBUG_MODE && now_ms - g_last_debug_log_ms >= 5000) { + g_last_debug_log_ms = now_ms; + serial_debug_printf("state: Q=%u%s A=%u C=%u inflight=%u ack_pending=%u retries=%u", + g_batch_count, + g_build_count > 0 ? "+" : "", + g_last_acked_batch_id, + g_batch_id, + g_inflight_count, + g_batch_ack_pending ? 1 : 0, + g_batch_retry_count); + } if (now_ms - g_last_sample_ms >= METER_SAMPLE_INTERVAL_MS) { g_last_sample_ms = now_ms; @@ -593,6 +633,7 @@ static void sender_loop() { if (ack_sender == g_short_id && ack_receiver == rx.device_id_short && g_batch_ack_pending && ack_id == g_last_sent_batch_id) { g_last_acked_batch_id = ack_id; + serial_debug_printf("ack: ok batch_id=%u", ack_id); finish_inflight_batch(); } } @@ -601,8 +642,11 @@ static void sender_loop() { if (g_batch_ack_pending && (now_ms - g_last_batch_send_ms >= BATCH_ACK_TIMEOUT_MS)) { if (g_batch_retry_count < BATCH_MAX_RETRIES) { g_batch_retry_count++; + serial_debug_printf("ack: timeout batch_id=%u retry=%u", g_inflight_batch_id, g_batch_retry_count); resend_inflight_batch(last_sample_ts()); } else { + serial_debug_printf("ack: failed batch_id=%u policy=%s", g_inflight_batch_id, + BATCH_RETRY_POLICY == BatchRetryPolicy::Drop ? "drop" : "keep"); if (BATCH_RETRY_POLICY == BatchRetryPolicy::Drop) { finish_inflight_batch(); } else {