From abb3e59f16134e7c8441574bc28746de55a2ac20 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 6 Jun 2021 10:36:32 +0200 Subject: [PATCH] Simplified NF and linear power averaging --- nanovna.h | 3 ++- plot.c | 12 ++++----- sa_core.c | 13 +++++++++- si4468.c | 2 +- ui_sa.c | 74 ++++++++++++++++++++++++++++++++++++++++++++----------- 5 files changed, 81 insertions(+), 23 deletions(-) diff --git a/nanovna.h b/nanovna.h index 4007328..fd6d19b 100644 --- a/nanovna.h +++ b/nanovna.h @@ -269,6 +269,7 @@ extern float channel_power_watt[3]; extern const char * const unit_string[]; extern uint16_t vbwSteps; #ifdef TINYSA4 +extern float measured_noise_figure; extern freq_t ultra_threshold; extern bool ultra; extern float *drive_dBm; @@ -1410,7 +1411,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_TINYSA, M_NF_VALIDATE, M_NF_AMPLIFIER, 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_STORE, M_NF_VALIDATE, M_NF_AMPLIFIER, M_DECONV }; enum { diff --git a/plot.c b/plot.c index ab04da6..b76a6c4 100644 --- a/plot.c +++ b/plot.c @@ -1642,13 +1642,13 @@ static void cell_draw_marker_info(int x0, int y0) } 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 + measured_noise_figure = aNP + 173.93 - nf_gain; // measured noise figure at 20C if (setting.measurement != M_NF_TINYSA) { - float mnf = expf(mNF/10.0 * logf(10)); // measure noise factor + float mnf = expf(measured_noise_figure/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)); float anf = mnf - (tnf - 1.0)/amp_gain; - mNF = 10.0*logf(anf)/logf(10.0); + measured_noise_figure = 10.0*logf(anf)/logf(10.0); } // powf(10,x) = expf(x * logf(10)) // log10f(x) = logf(x)/logf(10) @@ -1659,12 +1659,12 @@ static void cell_draw_marker_info(int x0, int y0) int xpos = 1 + (j%2)*(WIDTH/2) + CELLOFFSETX - x0; int ypos = 1 + (j/2)*(16) - y0; if (setting.measurement == M_NF_TINYSA) { - cell_printf(xpos, ypos, FONT_b"TINYSA NF: %4.1f", mNF); + cell_printf(xpos, ypos, FONT_b"TINYSA NF: %4.1f", measured_noise_figure); } else { if (setting.measurement == M_NF_VALIDATE) - cell_printf(xpos, ypos, FONT_b"TINYSA NF ERROR: %4.1f", mNF); + cell_printf(xpos, ypos, FONT_b"TINYSA NF ERROR: %4.1f", measured_noise_figure); else - cell_printf(xpos, ypos, FONT_b"GAIN: %4.1fdB NF: %4.1f", nf_gain, mNF); + cell_printf(xpos, ypos, FONT_b"GAIN: %4.1fdB NF: %4.1f", nf_gain, measured_noise_figure); } break; #endif diff --git a/sa_core.c b/sa_core.c index 2dd5354..3941e05 100644 --- a/sa_core.c +++ b/sa_core.c @@ -4067,7 +4067,18 @@ static volatile int dummy; break; case AV_4: actual_t[i] = (actual_t[i]*3.0 + RSSI) / 4.0; break; case AV_16: actual_t[i] = (actual_t[i]*15.0 + RSSI) / 16.0; break; - case AV_100:actual_t[i] = (actual_t[i]*(scan_after_dirty-1) + RSSI) / scan_after_dirty; break; + case AV_100: +#ifdef TINYSA4 + { + int old_unit = setting.unit; + setting.unit = U_WATT; // Power averaging should always be done in Watts + actual_t[i] = to_dBm((value(actual_t[i])*(scan_after_dirty-1) + value(RSSI)) / scan_after_dirty ); + setting.unit = old_unit; + } +#else + actual_t[i] = (actual_t[i]*(scan_after_dirty-1) + RSSI)/ scan_after_dirty; +#endif + break; #ifdef __QUASI_PEAK__ case AV_QUASI: { static float old_RSSI = -150.0; diff --git a/si4468.c b/si4468.c index 660e8d4..2792ef7 100644 --- a/si4468.c +++ b/si4468.c @@ -1401,7 +1401,7 @@ int16_t Si446x_RSSI(void) #endif #endif if (--i <= 0) break; -// my_microsecond_delay(100); + my_microsecond_delay(100); }while(1); if (setting.repeat > 1 && setting.exp_aver == 1) diff --git a/ui_sa.c b/ui_sa.c index 8d9186c..be6287f 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -529,6 +529,7 @@ static const menuitem_t menu_connection[]; static const menuitem_t menu_settings3[]; static const menuitem_t menu_curve[]; static const menuitem_t menu_curve_confirm[]; +static const menuitem_t menu_measure_noise_figure[]; #endif static const menuitem_t menu_sweep[]; static const menuitem_t menu_settings[]; @@ -642,6 +643,23 @@ UI_FUNCTION_CALLBACK(menu_curve_confirm_cb) menu_move_back(false); } +float measured_noise_figure; + +UI_FUNCTION_CALLBACK(menu_noise_figure_confirm_cb) +{ + (void)item; + if (data) { + if (measured_noise_figure > 3 && measured_noise_figure < 15) { + config.noise_figure = measured_noise_figure; + config_save(); + nf_gain = 0.00001; // almost zero + set_measurement(M_NF_VALIDATE); // Continue to validate + return; + } + } + menu_move_back(false); +} + static UI_FUNCTION_CALLBACK(menu_input_curve_prepare_cb) { (void)item; @@ -1167,7 +1185,6 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb) menu_move_back(false); markers_reset(); -#ifdef __MEASURE__ if ((data != M_OFF && setting.measurement != M_OFF) || data == M_OFF ) { // reset_settings(setting.mode); @@ -1347,13 +1364,27 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb) #endif #ifdef __NOISE_FIGURE__ case M_NF_TINYSA: + reset_settings(setting.mode); + set_refer_output(-1); nf_gain = 0; goto noise_figure; + case M_NF_STORE: + if (measured_noise_figure > 3 && measured_noise_figure < 15) { + config.noise_figure = measured_noise_figure; + config_save(); + data = M_NF_VALIDATE; // Continue to validate + goto validate; + } else + data = M_NF_TINYSA; // Continue to measure + break; case M_NF_VALIDATE: +validate: nf_gain = 0.00001; // almost zero goto noise_figure; case M_NF_AMPLIFIER: // noise figure // reset_settings(setting.mode); + reset_settings(setting.mode); + set_refer_output(-1); kp_help_text = "Amplifier Gain "; float old_gain = setting.external_gain; ui_mode_keypad(KM_EXT_GAIN); @@ -1363,18 +1394,26 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb) 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); + set_attenuation(0); + if (data != M_NF_VALIDATE) { + 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); + kp_help_text = "Noise span"; + ui_mode_keypad(KM_SPAN); #else - set_sweep_frequency(ST_SPAN, 100000); + set_sweep_frequency(ST_SPAN, 100000); #endif - set_RBW(get_sweep_frequency(ST_SPAN)/100 / 100); + set_RBW(get_sweep_frequency(ST_SPAN)/100 / 100); + } + // set_sweep_frequency(ST_SPAN, 0); set_average(AV_100); + if (data == M_NF_TINYSA || data == M_NF_VALIDATE ) { + menu_push_submenu(menu_measure_noise_figure); + goto leave; + } break; #endif #ifdef __FFT_DECONV__ @@ -1383,11 +1422,11 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb) break; #endif } - set_measurement(data); -#endif // selection = -1; ui_mode_normal(); +leave: + set_measurement(data); // draw_cal_status(); } @@ -2582,6 +2621,12 @@ static const menuitem_t menu_curve_confirm[] = { { MT_NONE, 0, NULL, NULL } // sentinel }; +static const menuitem_t menu_noise_figure_confirm[] = { + { MT_CALLBACK, 1, "STORE\nTINYSA NF", menu_noise_figure_confirm_cb }, + { MT_CALLBACK, 0, "CANCEL", menu_noise_figure_confirm_cb }, + { MT_NONE, 0, NULL, NULL } // sentinel +}; + #endif static const menuitem_t menu_actual_power[] = @@ -2602,7 +2647,7 @@ static const menuitem_t menu_settings[] = { MT_ADV_CALLBACK | MT_LOW, 0,"LO OUTPUT", menu_lo_output_acb}, { MT_SUBMENU, 0, "LEVEL\nCORRECTION", menu_actual_power}, { MT_KEYPAD | MT_LOW, KM_IF, "IF FREQ", "0=auto IF"}, - { MT_SUBMENU,0, "SCAN SPEED", menu_scanning_speed}, + { MT_SUBMENU,0, "SCAN\nSPEED", menu_scanning_speed}, #ifndef TINYSA4 { MT_KEYPAD, KM_REPEAT, "SAMPLE\nREPEAT", "1..100"}, #endif @@ -2622,9 +2667,10 @@ static const menuitem_t menu_settings[] = #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_ADV_CALLBACK, M_NF_TINYSA, "MEASURE\nTINYSA NF",menu_measure_acb}, + { MT_ADV_CALLBACK, M_NF_STORE, "STORE\nTINYSA NF",menu_measure_acb}, + { MT_ADV_CALLBACK, M_NF_VALIDATE, "VALIDATE\nTINYSA NF",menu_measure_acb}, + { MT_ADV_CALLBACK, M_NF_AMPLIFIER, "MEASURE\nAMP NF",menu_measure_acb}, { MT_NONE, 0, NULL, menu_back} // next-> menu_back }; #endif