From 90d19a9dfd294eb6c9d514b63514671032920dd4 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Fri, 4 Jun 2021 18:59:58 +0200 Subject: [PATCH] Improved NF measurement procedure --- nanovna.h | 3 ++- plot.c | 13 ++++++++----- sa_core.c | 5 +++-- si4468.c | 16 +++++++++++++--- ui_sa.c | 39 +++++++++++++++++++++++++++++++++------ 5 files changed, 59 insertions(+), 17 deletions(-) diff --git a/nanovna.h b/nanovna.h index 1f77133..f3cc214 100644 --- a/nanovna.h +++ b/nanovna.h @@ -1029,6 +1029,7 @@ typedef struct setting bool extra_lna; uint8_t ultra; // enum ?? int R; // KM_R + int32_t exp_aver; #endif int64_t test_argument; // used for tests uint32_t checksum; // must be last and at 4 byte boundary @@ -1407,7 +1408,7 @@ void interpolate_maximum(int m); void calibrate_modulation(int modulation, int8_t *correction); enum { - M_OFF, M_IMD, M_OIP3, M_PHASE_NOISE, M_SNR, M_PASS_BAND, M_LINEARITY, M_AM, M_FM, M_THD, M_CP, M_NF, M_DECONV + M_OFF, M_IMD, M_OIP3, M_PHASE_NOISE, M_SNR, M_PASS_BAND, M_LINEARITY, M_AM, M_FM, M_THD, M_CP, M_NF_TINYSA, M_NF_VALIDATE, M_NF_AMPLIFIER, M_DECONV }; enum { diff --git a/plot.c b/plot.c index f93b756..c5e1dd1 100644 --- a/plot.c +++ b/plot.c @@ -1625,11 +1625,11 @@ static void cell_draw_marker_info(int x0, int y0) break; } #ifdef __NOISE_FIGURE__ - } else if (i>=2 && setting.measurement == M_NF && markers[0].enabled) { + } else if (i>=2 && (setting.measurement == M_NF_TINYSA || setting.measurement == M_NF_VALIDATE || setting.measurement == M_NF_AMPLIFIER) && markers[0].enabled) { float aNP = 0; aNP = marker_to_value(0); float mNF = aNP + 173.93 - nf_gain; // measured noise figure at 20C - if (nf_gain != 0) { + if (setting.measurement != M_NF_TINYSA) { float mnf = expf(mNF/10.0 * logf(10)); // measure noise factor float tnf = expf(config.noise_figure/10.0 * logf(10.0)); // tinySA noise factor float amp_gain = expf(nf_gain/10.0 * logf(10.0)); @@ -1644,10 +1644,13 @@ static void cell_draw_marker_info(int x0, int y0) // j = 1; int xpos = 1 + (j%2)*(WIDTH/2) + CELLOFFSETX - x0; int ypos = 1 + (j/2)*(16) - y0; - if (nf_gain != 0) { - cell_printf(xpos, ypos, FONT_b"GAIN: %4.1fdB NF: %4.1f", nf_gain, mNF); - } else { + if (setting.measurement == M_NF_TINYSA) { cell_printf(xpos, ypos, FONT_b"TINYSA NF: %4.1f", mNF); + } else { + if (setting.measurement == M_NF_VALIDATE) + cell_printf(xpos, ypos, FONT_b"TINYSA NF ERROR: %4.1f", mNF); + else + cell_printf(xpos, ypos, FONT_b"GAIN: %4.1fdB NF: %4.1f", nf_gain, mNF); } break; #endif diff --git a/sa_core.c b/sa_core.c index 5119438..9ca0dfd 100644 --- a/sa_core.c +++ b/sa_core.c @@ -201,6 +201,7 @@ void reset_settings(int m) ultra_threshold = config.ultra_threshold; ultra = config.ultra; drive_dBm = (float *) (setting.mode == M_GENHIGH && config.high_out_adf4350 ? adf_drive_dBm : si_drive_dBm); + setting.exp_aver = 1; #endif update_min_max_freq(); setting.frequency_var = 0; @@ -4189,7 +4190,7 @@ static volatile int dummy; // Update actual time on change on status panel uint32_t delta = abs((int)(setting.actual_sweep_time_us - setting.measure_sweep_time_us)); if ((delta<<3) > setting.actual_sweep_time_us){ // update if delta > 1/8 - redraw_request|=REDRAW_CAL_STATUS; + redraw_request|=REDRAW_CAL_STATUS | REDRAW_FREQUENCY; } setting.actual_sweep_time_us = setting.measure_sweep_time_us; // Not possible reduce sweep time, it minimum! @@ -4517,7 +4518,7 @@ static volatile int dummy; #endif } #ifdef __CHANNEL_POWER__ - } else if (setting.measurement == M_CP || setting.measurement == M_SNR || setting.measurement == M_NF) { // ----------------CHANNEL_POWER measurement + } else if (setting.measurement == M_CP || setting.measurement == M_SNR || setting.measurement == M_NF_TINYSA|| setting.measurement == M_NF_VALIDATE|| setting.measurement == M_NF_AMPLIFIER) { // ----------------CHANNEL_POWER measurement freq_t bw = get_sweep_frequency(ST_SPAN)/3; int old_unit = setting.unit; setting.unit = U_WATT; diff --git a/si4468.c b/si4468.c index 82422b7..660e8d4 100644 --- a/si4468.c +++ b/si4468.c @@ -1319,6 +1319,7 @@ const uint8_t dBm_to_volt [] = 5, 5, }; +static int32_t RSSI_RAW = 0; void SI4432_Listen(int s) { @@ -1356,7 +1357,8 @@ int16_t Si446x_RSSI(void) #endif int i = setting.repeat; - int32_t RSSI_RAW = 0; + if (setting.exp_aver == 1) + RSSI_RAW = 0; // SI4463_WAIT_CTS; // Wait for CTS do{ // if (MODE_INPUT(setting.mode) && RSSI_R @@ -1387,14 +1389,22 @@ int16_t Si446x_RSSI(void) } RSSI_RAW += DEVICE_TO_PURE_RSSI(RSSI_RAW_ARRAY[1]); +#else +#ifdef TINYSA4 + if (setting.exp_aver == 1) + RSSI_RAW += DEVICE_TO_PURE_RSSI(RSSI_RAW_ARRAY[0]); + else + RSSI_RAW = ((setting.exp_aver-1) * RSSI_RAW + DEVICE_TO_PURE_RSSI(RSSI_RAW_ARRAY[0]))/setting.exp_aver; + #else RSSI_RAW += DEVICE_TO_PURE_RSSI(RSSI_RAW_ARRAY[0]); +#endif #endif if (--i <= 0) break; - my_microsecond_delay(100); +// my_microsecond_delay(100); }while(1); - if (setting.repeat > 1) + if (setting.repeat > 1 && setting.exp_aver == 1) RSSI_RAW = RSSI_RAW / setting.repeat; return RSSI_RAW; diff --git a/ui_sa.c b/ui_sa.c index 870b4c3..855abbb 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -423,6 +423,7 @@ enum { KM_ATTACK, #ifdef TINYSA4 KM_LPF, + KM_EXP_AVER, #endif KM_LEVEL, #ifdef __LIMITS__ @@ -483,6 +484,7 @@ static const struct { [KM_ATTACK] = {keypads_positive , "ATTACK"}, // KM_ATTACK #ifdef TINYSA4 [KM_LPF] = {keypads_freq , "ULTRA\nSTART"}, // KM_LPF +[KM_EXP_AVER] = {keypads_positive , "EXPONENTIAL\nAVERAGING"}, //KM_EXP_AVER #endif [KM_LEVEL] = {keypads_plusmin , "LEVEL"}, // KM_LEVEL #ifdef __LIMITS__ @@ -1344,21 +1346,32 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb) break; #endif #ifdef __NOISE_FIGURE__ - case M_NF: // noise figure + case M_NF_TINYSA: + nf_gain = 0; + goto noise_figure; + case M_NF_VALIDATE: + nf_gain = 0.00001; // almost zero + goto noise_figure; + case M_NF_AMPLIFIER: // noise figure // reset_settings(setting.mode); - markers[0].enabled = M_ENABLED; - markers[0].mtype = M_NOISE | M_AVER; // Not tracking - set_extra_lna(true); kp_help_text = "Amplifier Gain "; float old_gain = setting.external_gain; ui_mode_keypad(KM_EXT_GAIN); nf_gain = setting.external_gain; setting.external_gain = old_gain; + noise_figure: + markers[0].enabled = M_ENABLED; + markers[0].mtype = M_NOISE | M_AVER; // Not tracking + set_extra_lna(true); kp_help_text = "Noise center frequency"; ui_mode_keypad(KM_CENTER); set_marker_frequency(0, uistat.value); +#if 0 kp_help_text = "Noise span"; ui_mode_keypad(KM_SPAN); +#else + set_sweep_frequency(ST_SPAN, 100000); +#endif set_RBW(get_sweep_frequency(ST_SPAN)/100 / 100); // set_sweep_frequency(ST_SPAN, 0); set_average(AV_100); @@ -2606,6 +2619,16 @@ static const menuitem_t menu_settings[] = { MT_NONE, 0, NULL, menu_back} // next-> menu_back }; +#ifdef __NOISE_FIGURE__ +static const menuitem_t menu_measure_noise_figure[] = +{ + { MT_ADV_CALLBACK, M_NF_TINYSA, "MEASURE\nTINYSA NF",menu_measure_acb}, + { MT_ADV_CALLBACK, M_NF_VALIDATE, "VALIDATE\nTINYSA NF",menu_measure_acb}, + { MT_ADV_CALLBACK, M_NF_AMPLIFIER, "MEASURE\nAMPLIFIER NF",menu_measure_acb}, + { MT_NONE, 0, NULL, menu_back} // next-> menu_back +}; +#endif + static const menuitem_t menu_measure2[] = { { MT_ADV_CALLBACK, M_AM, "AM", menu_measure_acb}, { MT_ADV_CALLBACK, M_FM, "FM", menu_measure_acb}, @@ -2617,7 +2640,7 @@ static const menuitem_t menu_measure2[] = { { MT_ADV_CALLBACK | MT_LOW, M_LINEARITY, "LINEAR", menu_measure_acb}, #endif #ifdef __NOISE_FIGURE__ -{ MT_ADV_CALLBACK | MT_LOW, M_NF, "NOISE\nFIGURE", menu_measure_acb}, +{ MT_SUBMENU | MT_LOW, 0, "NOISE\nFIGURE", menu_measure_noise_figure}, #endif #ifdef __FFT_DECONV__ { MT_ADV_CALLBACK, M_DECONV, "DECONV", menu_measure_acb}, @@ -2719,6 +2742,7 @@ static const menuitem_t menu_display[] = { // { MT_ADV_CALLBACK,2, "SUBTRACT\nSTORED",menu_storage_acb}, #ifdef __VBW__ { MT_SUBMENU, 0, "VBW", menu_vbw}, + { MT_KEYPAD, KM_EXP_AVER, "EXP\nAVER", NULL}, #endif #ifdef __LIMITS__ { MT_SUBMENU, 0, "LIMITS", menu_limit_select}, @@ -3099,6 +3123,9 @@ set_numeric_value(void) config_save(); ultra_threshold = config.ultra_threshold; break; + case KM_EXP_AVER: + setting.exp_aver = uistat.value; + dirty = true; #endif case KM_LEVEL: break; @@ -3417,7 +3444,7 @@ redraw_cal_status: calculate_step_delay(); setting.actual_sweep_time_us = calc_min_sweep_time_us(); } - ili9341_set_foreground(setting.step_delay ? LCD_BRIGHT_COLOR_GREEN : LCD_FG_COLOR); + ili9341_set_foreground((setting.step_delay || setting.sweep_time_us ) ? LCD_BRIGHT_COLOR_GREEN : LCD_FG_COLOR); #if 0 // Activate for sweep time debugging lcd_printf(x, y, "%cScan:\n%5.3Fs", fscan[setting.step_delay_mode&3], (float)setting.sweep_time_us/ONE_SECOND_TIME); #endif