Simplified NF and linear power averaging

multi_trace
erikkaashoek 5 years ago
parent a0c410fbcc
commit abb3e59f16

@ -269,6 +269,7 @@ extern float channel_power_watt[3];
extern const char * const unit_string[]; extern const char * const unit_string[];
extern uint16_t vbwSteps; extern uint16_t vbwSteps;
#ifdef TINYSA4 #ifdef TINYSA4
extern float measured_noise_figure;
extern freq_t ultra_threshold; extern freq_t ultra_threshold;
extern bool ultra; extern bool ultra;
extern float *drive_dBm; extern float *drive_dBm;
@ -1410,7 +1411,7 @@ void interpolate_maximum(int m);
void calibrate_modulation(int modulation, int8_t *correction); void calibrate_modulation(int modulation, int8_t *correction);
enum { 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 { enum {

@ -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) { } 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; float aNP = 0;
aNP = marker_to_value(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) { 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 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 amp_gain = expf(nf_gain/10.0 * logf(10.0));
float anf = mnf - (tnf - 1.0)/amp_gain; 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)) // powf(10,x) = expf(x * logf(10))
// log10f(x) = logf(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 xpos = 1 + (j%2)*(WIDTH/2) + CELLOFFSETX - x0;
int ypos = 1 + (j/2)*(16) - y0; int ypos = 1 + (j/2)*(16) - y0;
if (setting.measurement == M_NF_TINYSA) { 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 { } else {
if (setting.measurement == M_NF_VALIDATE) 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 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; break;
#endif #endif

@ -4067,7 +4067,18 @@ static volatile int dummy;
break; break;
case AV_4: actual_t[i] = (actual_t[i]*3.0 + RSSI) / 4.0; 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_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__ #ifdef __QUASI_PEAK__
case AV_QUASI: case AV_QUASI:
{ static float old_RSSI = -150.0; { static float old_RSSI = -150.0;

@ -1401,7 +1401,7 @@ int16_t Si446x_RSSI(void)
#endif #endif
#endif #endif
if (--i <= 0) break; if (--i <= 0) break;
// my_microsecond_delay(100); my_microsecond_delay(100);
}while(1); }while(1);
if (setting.repeat > 1 && setting.exp_aver == 1) if (setting.repeat > 1 && setting.exp_aver == 1)

@ -529,6 +529,7 @@ static const menuitem_t menu_connection[];
static const menuitem_t menu_settings3[]; static const menuitem_t menu_settings3[];
static const menuitem_t menu_curve[]; static const menuitem_t menu_curve[];
static const menuitem_t menu_curve_confirm[]; static const menuitem_t menu_curve_confirm[];
static const menuitem_t menu_measure_noise_figure[];
#endif #endif
static const menuitem_t menu_sweep[]; static const menuitem_t menu_sweep[];
static const menuitem_t menu_settings[]; static const menuitem_t menu_settings[];
@ -642,6 +643,23 @@ UI_FUNCTION_CALLBACK(menu_curve_confirm_cb)
menu_move_back(false); 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) static UI_FUNCTION_CALLBACK(menu_input_curve_prepare_cb)
{ {
(void)item; (void)item;
@ -1167,7 +1185,6 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb)
menu_move_back(false); menu_move_back(false);
markers_reset(); markers_reset();
#ifdef __MEASURE__
if ((data != M_OFF && setting.measurement != M_OFF) || data == M_OFF ) if ((data != M_OFF && setting.measurement != M_OFF) || data == M_OFF )
{ {
// reset_settings(setting.mode); // reset_settings(setting.mode);
@ -1347,13 +1364,27 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb)
#endif #endif
#ifdef __NOISE_FIGURE__ #ifdef __NOISE_FIGURE__
case M_NF_TINYSA: case M_NF_TINYSA:
reset_settings(setting.mode);
set_refer_output(-1);
nf_gain = 0; nf_gain = 0;
goto noise_figure; 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: case M_NF_VALIDATE:
validate:
nf_gain = 0.00001; // almost zero nf_gain = 0.00001; // almost zero
goto noise_figure; goto noise_figure;
case M_NF_AMPLIFIER: // noise figure case M_NF_AMPLIFIER: // noise figure
// reset_settings(setting.mode); // reset_settings(setting.mode);
reset_settings(setting.mode);
set_refer_output(-1);
kp_help_text = "Amplifier Gain "; kp_help_text = "Amplifier Gain ";
float old_gain = setting.external_gain; float old_gain = setting.external_gain;
ui_mode_keypad(KM_EXT_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].enabled = M_ENABLED;
markers[0].mtype = M_NOISE | M_AVER; // Not tracking markers[0].mtype = M_NOISE | M_AVER; // Not tracking
set_extra_lna(true); set_extra_lna(true);
kp_help_text = "Noise center frequency"; set_attenuation(0);
ui_mode_keypad(KM_CENTER); if (data != M_NF_VALIDATE) {
set_marker_frequency(0, uistat.value); kp_help_text = "Noise center frequency";
ui_mode_keypad(KM_CENTER);
set_marker_frequency(0, uistat.value);
#if 0 #if 0
kp_help_text = "Noise span"; kp_help_text = "Noise span";
ui_mode_keypad(KM_SPAN); ui_mode_keypad(KM_SPAN);
#else #else
set_sweep_frequency(ST_SPAN, 100000); set_sweep_frequency(ST_SPAN, 100000);
#endif #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_sweep_frequency(ST_SPAN, 0);
set_average(AV_100); set_average(AV_100);
if (data == M_NF_TINYSA || data == M_NF_VALIDATE ) {
menu_push_submenu(menu_measure_noise_figure);
goto leave;
}
break; break;
#endif #endif
#ifdef __FFT_DECONV__ #ifdef __FFT_DECONV__
@ -1383,11 +1422,11 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb)
break; break;
#endif #endif
} }
set_measurement(data);
#endif
// selection = -1; // selection = -1;
ui_mode_normal(); ui_mode_normal();
leave:
set_measurement(data);
// draw_cal_status(); // draw_cal_status();
} }
@ -2582,6 +2621,12 @@ static const menuitem_t menu_curve_confirm[] = {
{ MT_NONE, 0, NULL, NULL } // sentinel { 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 #endif
static const menuitem_t menu_actual_power[] = 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_ADV_CALLBACK | MT_LOW, 0,"LO OUTPUT", menu_lo_output_acb},
{ MT_SUBMENU, 0, "LEVEL\nCORRECTION", menu_actual_power}, { MT_SUBMENU, 0, "LEVEL\nCORRECTION", menu_actual_power},
{ MT_KEYPAD | MT_LOW, KM_IF, "IF FREQ", "0=auto IF"}, { 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 #ifndef TINYSA4
{ MT_KEYPAD, KM_REPEAT, "SAMPLE\nREPEAT", "1..100"}, { MT_KEYPAD, KM_REPEAT, "SAMPLE\nREPEAT", "1..100"},
#endif #endif
@ -2622,9 +2667,10 @@ static const menuitem_t menu_settings[] =
#ifdef __NOISE_FIGURE__ #ifdef __NOISE_FIGURE__
static const menuitem_t menu_measure_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_TINYSA, "MEASURE\nTINYSA NF",menu_measure_acb},
{ MT_ADV_CALLBACK, M_NF_VALIDATE, "VALIDATE\nTINYSA NF",menu_measure_acb}, { MT_ADV_CALLBACK, M_NF_STORE, "STORE\nTINYSA NF",menu_measure_acb},
{ MT_ADV_CALLBACK, M_NF_AMPLIFIER, "MEASURE\nAMPLIFIER 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 { MT_NONE, 0, NULL, menu_back} // next-> menu_back
}; };
#endif #endif

Loading…
Cancel
Save

Powered by TurnKey Linux.