Add channel frequency display to monitor status

- Display channel number, frequency (MHz), width, and center frequency
- Format: 'Channel: 11 (2462 MHz), width: 20 MHz, center1: 2462 MHz'
- Supports both 2.4GHz (channels 1-14) and 5GHz (channels 36-177)
- Use PRIu32 format specifier for portable uint32_t formatting

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Robert McMahon 2026-02-10 10:50:16 -08:00
parent 0311ad21a1
commit bb6bd568ce
3 changed files with 122 additions and 8 deletions

View File

@ -141,6 +141,26 @@ bool wifi_cfg_set_monitor_channel(uint8_t channel) {
return (err == ESP_OK); return (err == ESP_OK);
} }
bool wifi_cfg_get_monitor_channel(uint8_t *channel_out) {
bool result = false;
if (channel_out != NULL) {
nvs_handle_t h;
uint8_t saved_val = DEFAULT_MONITOR_CHANNEL;
if (nvs_open(NVS_NS, NVS_READONLY, &h) == ESP_OK) {
esp_err_t err = nvs_get_u8(h, "mon_chan", &saved_val);
nvs_close(h);
if (err == ESP_OK || err == ESP_ERR_NVS_NOT_FOUND) {
*channel_out = saved_val;
result = true;
}
}
}
return result;
}
void wifi_cfg_clear_monitor_channel(void) { void wifi_cfg_clear_monitor_channel(void) {
nvs_handle_t h; nvs_handle_t h;
if (nvs_open(NVS_NS, NVS_READWRITE, &h) == ESP_OK) { if (nvs_open(NVS_NS, NVS_READWRITE, &h) == ESP_OK) {

View File

@ -55,6 +55,7 @@ bool wifi_cfg_set_password(const char *password);
// Monitor Specific // Monitor Specific
bool wifi_cfg_set_monitor_channel(uint8_t channel); bool wifi_cfg_set_monitor_channel(uint8_t channel);
bool wifi_cfg_get_monitor_channel(uint8_t *channel_out);
void wifi_cfg_clear_monitor_channel(void); void wifi_cfg_clear_monitor_channel(void);
bool wifi_cfg_monitor_channel_is_unsaved(uint8_t current_val); bool wifi_cfg_monitor_channel_is_unsaved(uint8_t current_val);

View File

@ -90,6 +90,8 @@ typedef struct {
static rate_tracker_t s_telemetry_gen_rate = {0}; static rate_tracker_t s_telemetry_gen_rate = {0};
static rate_tracker_t s_sd_write_rate = {0}; static rate_tracker_t s_sd_write_rate = {0};
static rate_tracker_t s_frame_rate = {0};
static uint32_t s_last_frame_count_for_rate = 0;
/* Batch buffer for telemetry (shared between task and flush function) */ /* Batch buffer for telemetry (shared between task and flush function) */
static char s_batch_buf[TELEMETRY_BATCH_SIZE]; static char s_batch_buf[TELEMETRY_BATCH_SIZE];
@ -206,6 +208,8 @@ static void monitor_stats_task(void *arg) {
uint64_t start_ms = esp_timer_get_time() / 1000; uint64_t start_ms = esp_timer_get_time() / 1000;
s_telemetry_gen_rate.last_update_ms = start_ms; s_telemetry_gen_rate.last_update_ms = start_ms;
s_sd_write_rate.last_update_ms = start_ms; s_sd_write_rate.last_update_ms = start_ms;
s_frame_rate.last_update_ms = start_ms;
s_last_frame_count_for_rate = s_monitor_frame_count;
last_batch_flush_ms = start_ms; last_batch_flush_ms = start_ms;
last_stats_log_ms = start_ms; last_stats_log_ms = start_ms;
@ -222,6 +226,16 @@ static void monitor_stats_task(void *arg) {
if (s_monitor_frame_count == last_frame_count) { if (s_monitor_frame_count == last_frame_count) {
status_led_set_capture_active(false); status_led_set_capture_active(false);
} }
/* Update frame rate tracker */
uint32_t frames_delta = s_monitor_frame_count - s_last_frame_count_for_rate;
uint32_t frame_interval_ms = (uint32_t)(now_ms - s_frame_rate.last_update_ms);
if (frame_interval_ms > 0) {
update_rate_tracker(&s_frame_rate, frames_delta, frame_interval_ms);
s_frame_rate.last_update_ms = now_ms;
s_last_frame_count_for_rate = s_monitor_frame_count;
}
last_frame_count = s_monitor_frame_count; last_frame_count = s_monitor_frame_count;
/* Generate telemetry JSON (regardless of SD card status) */ /* Generate telemetry JSON (regardless of SD card status) */
@ -422,10 +436,20 @@ void wifi_ctl_init(void) {
esp_wifi_connect(); esp_wifi_connect();
} }
// Load Staging Params // Load Staging and Active Params from NVS
char mode_ignored[16]; char mode_ignored[16];
wifi_cfg_get_mode(mode_ignored, &s_monitor_channel_staging); wifi_cfg_get_mode(mode_ignored, &s_monitor_channel_staging);
if (s_monitor_channel_staging == 0) s_monitor_channel_staging = 6; if (s_monitor_channel_staging == 0) s_monitor_channel_staging = 6;
// Load active channel from NVS (persists across reboots)
uint8_t saved_active_channel = 0;
if (wifi_cfg_get_monitor_channel(&saved_active_channel) && saved_active_channel > 0 && saved_active_channel <= 14) {
s_monitor_channel_active = saved_active_channel;
// Also update staging to match active if staging wasn't set
if (s_monitor_channel_staging == 6) {
s_monitor_channel_staging = saved_active_channel;
}
}
} }
// --- Mode Control (Core) --- // --- Mode Control (Core) ---
@ -433,7 +457,10 @@ void wifi_ctl_init(void) {
esp_err_t wifi_ctl_switch_to_monitor(uint8_t channel, wifi_bandwidth_t bw) { esp_err_t wifi_ctl_switch_to_monitor(uint8_t channel, wifi_bandwidth_t bw) {
esp_err_t result = ESP_OK; esp_err_t result = ESP_OK;
if (channel == 0) channel = s_monitor_channel_staging; if (channel == 0) {
// Use active channel if set, otherwise fall back to staging
channel = (s_monitor_channel_active > 0) ? s_monitor_channel_active : s_monitor_channel_staging;
}
if (s_current_mode == WIFI_CTL_MODE_MONITOR && s_monitor_channel_active == channel) { if (s_current_mode == WIFI_CTL_MODE_MONITOR && s_monitor_channel_active == channel) {
ESP_LOGW(TAG, "Already in monitor mode (Ch %d)", channel); ESP_LOGW(TAG, "Already in monitor mode (Ch %d)", channel);
@ -473,14 +500,19 @@ esp_err_t wifi_ctl_switch_to_monitor(uint8_t channel, wifi_bandwidth_t bw) {
s_monitor_enabled = true; s_monitor_enabled = true;
s_current_mode = WIFI_CTL_MODE_MONITOR; s_current_mode = WIFI_CTL_MODE_MONITOR;
s_monitor_channel_active = channel; s_monitor_channel_active = channel;
/* Save active channel to NVS so it persists across reboots */
wifi_cfg_set_monitor_channel(channel);
status_led_set_state(LED_STATE_MONITORING); status_led_set_state(LED_STATE_MONITORING);
/* Reset rate trackers when starting monitor */ /* Reset rate trackers when starting monitor */
uint64_t start_ms = esp_timer_get_time() / 1000; uint64_t start_ms = esp_timer_get_time() / 1000;
memset(&s_telemetry_gen_rate, 0, sizeof(rate_tracker_t)); memset(&s_telemetry_gen_rate, 0, sizeof(rate_tracker_t));
memset(&s_sd_write_rate, 0, sizeof(rate_tracker_t)); memset(&s_sd_write_rate, 0, sizeof(rate_tracker_t));
memset(&s_frame_rate, 0, sizeof(rate_tracker_t));
s_telemetry_gen_rate.last_update_ms = start_ms; s_telemetry_gen_rate.last_update_ms = start_ms;
s_sd_write_rate.last_update_ms = start_ms; s_sd_write_rate.last_update_ms = start_ms;
s_frame_rate.last_update_ms = start_ms;
s_last_frame_count_for_rate = s_monitor_frame_count;
/* Initialize batch buffer and mutex */ /* Initialize batch buffer and mutex */
if (s_batch_mutex == NULL) { if (s_batch_mutex == NULL) {
@ -583,9 +615,39 @@ void wifi_ctl_set_channel(int channel) {
ESP_LOGI(TAG, "Switching live channel to %d", channel); ESP_LOGI(TAG, "Switching live channel to %d", channel);
esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE); esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
s_monitor_channel_active = (uint8_t)channel; s_monitor_channel_active = (uint8_t)channel;
/* Save active channel to NVS so it persists across reboots */
wifi_cfg_set_monitor_channel(channel);
} }
} }
/**
* @brief Calculate WiFi channel frequency in MHz
* @param channel Channel number (1-14 for 2.4GHz, 36+ for 5GHz)
* @return Frequency in MHz, or 0 if invalid channel
*/
static uint32_t wifi_channel_to_frequency(uint8_t channel) {
uint32_t freq = 0;
if (channel >= 1 && channel <= 14) {
/* 2.4 GHz band: 2407 + (channel * 5) MHz */
freq = 2407 + (channel * 5);
} else if (channel >= 36 && channel <= 64) {
/* 5 GHz UNII-1/2A: 5000 + (channel * 5) MHz */
freq = 5000 + (channel * 5);
} else if (channel >= 100 && channel <= 144) {
/* 5 GHz UNII-2C: 5000 + (channel * 5) MHz */
freq = 5000 + (channel * 5);
} else if (channel >= 149 && channel <= 165) {
/* 5 GHz UNII-3: 5000 + (channel * 5) MHz */
freq = 5000 + (channel * 5);
} else if (channel >= 169 && channel <= 177) {
/* 5 GHz UNII-4: 5000 + (channel * 5) MHz */
freq = 5000 + (channel * 5);
}
return freq;
}
void wifi_ctl_status(void) { void wifi_ctl_status(void) {
const char *mode_str = (s_current_mode == WIFI_CTL_MODE_MONITOR) ? "MONITOR" : const char *mode_str = (s_current_mode == WIFI_CTL_MODE_MONITOR) ? "MONITOR" :
(s_current_mode == WIFI_CTL_MODE_AP) ? "AP" : "STATION"; (s_current_mode == WIFI_CTL_MODE_AP) ? "AP" : "STATION";
@ -593,8 +655,23 @@ void wifi_ctl_status(void) {
printf("WiFi Status:\n"); printf("WiFi Status:\n");
printf(" Mode: %s\n", mode_str); printf(" Mode: %s\n", mode_str);
if (s_current_mode == WIFI_CTL_MODE_MONITOR) { if (s_current_mode == WIFI_CTL_MODE_MONITOR) {
printf(" Channel: %d\n", s_monitor_channel_active); uint8_t channel = s_monitor_channel_active;
printf(" Frames: %lu\n", (unsigned long)s_monitor_frame_count); uint32_t freq_mhz = wifi_channel_to_frequency(channel);
/* Display channel info: channel N (FREQ MHz), width: 20 MHz, center1: FREQ MHz */
/* Note: Monitor mode currently uses single channel (20 MHz width) */
if (freq_mhz > 0) {
printf(" Channel: %d (%" PRIu32 " MHz), width: 20 MHz, center1: %" PRIu32 " MHz\n",
channel, freq_mhz, freq_mhz);
} else {
printf(" Channel: %d\n", channel);
}
/* Get frame rate (frames per second) */
double frame_rate_fps = 0.0;
if (s_frame_rate.sample_count > 0) {
frame_rate_fps = s_frame_rate.mean_rate_bps; /* Already in per-second units for frames */
}
printf(" Frames: %lu, %.1f fps\n", (unsigned long)s_monitor_frame_count, frame_rate_fps);
/* Show telemetry rate statistics */ /* Show telemetry rate statistics */
uint64_t gen_bytes = 0, write_bytes = 0; uint64_t gen_bytes = 0, write_bytes = 0;
@ -625,7 +702,6 @@ void wifi_ctl_status(void) {
} }
} }
} }
printf(" Staging Ch: %d\n", s_monitor_channel_staging);
} }
// --- Params (NVS) --- // --- Params (NVS) ---
@ -636,8 +712,15 @@ bool wifi_ctl_param_is_unsaved(void) {
void wifi_ctl_param_save(const char *dummy) { void wifi_ctl_param_save(const char *dummy) {
(void)dummy; (void)dummy;
if (wifi_cfg_set_monitor_channel(s_monitor_channel_staging)) { /* If monitor mode is running, save the active channel; otherwise save staging */
ESP_LOGI(TAG, "Monitor channel (%d) saved to NVS", s_monitor_channel_staging); uint8_t channel_to_save = (s_current_mode == WIFI_CTL_MODE_MONITOR) ?
s_monitor_channel_active : s_monitor_channel_staging;
if (wifi_cfg_set_monitor_channel(channel_to_save)) {
ESP_LOGI(TAG, "Monitor channel (%d) saved to NVS", channel_to_save);
/* Update staging to match if we saved active */
if (s_current_mode == WIFI_CTL_MODE_MONITOR) {
s_monitor_channel_staging = channel_to_save;
}
} else { } else {
ESP_LOGI(TAG, "No changes to save."); ESP_LOGI(TAG, "No changes to save.");
} }
@ -648,7 +731,17 @@ void wifi_ctl_param_init(void) {
uint8_t ch = 0; uint8_t ch = 0;
wifi_cfg_get_mode(mode_ignored, &ch); wifi_cfg_get_mode(mode_ignored, &ch);
if (ch > 0) s_monitor_channel_staging = ch; if (ch > 0) s_monitor_channel_staging = ch;
ESP_LOGI(TAG, "Reloaded monitor channel: %d", s_monitor_channel_staging);
// Reload active channel from NVS
uint8_t saved_active_channel = 0;
if (wifi_cfg_get_monitor_channel(&saved_active_channel) && saved_active_channel > 0 && saved_active_channel <= 14) {
s_monitor_channel_active = saved_active_channel;
// Update staging to match active if staging wasn't set
if (s_monitor_channel_staging == 6 && ch == 0) {
s_monitor_channel_staging = saved_active_channel;
}
}
ESP_LOGI(TAG, "Reloaded monitor channel: active=%d, staging=%d", s_monitor_channel_active, s_monitor_channel_staging);
} }
void wifi_ctl_param_clear(void) { void wifi_ctl_param_clear(void) {