From 6aa31c51ea127d72bb9d16253f71314dcc355b3a Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Fri, 14 May 2021 13:30:36 +0200 Subject: [PATCH] Improved measurements --- plot.c | 18 ++++++++++--- sa_core.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++--------- ui_sa.c | 10 +++++++- 3 files changed, 87 insertions(+), 16 deletions(-) diff --git a/plot.c b/plot.c index d9dfa8e..05844b4 100644 --- a/plot.c +++ b/plot.c @@ -1498,16 +1498,28 @@ 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; cell_printf(xpos, ypos, FONT_b"DEVIATION:%6.1QHz", dev); - } else if (setting.measurement == M_THD && markers[0].enabled && (markers[0].index << 5) > sweep_points ) { +#ifdef TINYSA4 +#define THD_SHIFT 7 +#else +#define THD_SHIFT 6 +#endif + } else if (setting.measurement == M_THD && markers[0].enabled && (markers[0].index << THD_SHIFT) > sweep_points ) { int old_unit = setting.unit; setting.unit = U_WATT; float p = marker_to_value(0); int h_i = 2; freq_t f = markers[0].frequency; float h = 0.0; + int h_count = 0; + int search_gate = 10; + if (markers[0].index < search_gate) + search_gate = markers[0].index * 2 / 3; while (f * h_i < frequencies[sweep_points-1]) { - if (search_maximum(1, f*h_i, 4*h_i) ) // use marker 1 for searching harmonics + if (search_maximum(1, f*h_i, search_gate) ) { // use marker 1 for searching harmonics + h_count++; + f = (f * 3 + markers[1].frequency / h_i) >> 2; h += marker_to_value(1); + } h_i++; } float thd = 100.0 * sa_sqrtf(h/p); @@ -1516,7 +1528,7 @@ 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; - cell_printf(xpos, ypos, FONT_b"THD: %4.1f%%", thd); + cell_printf(xpos, ypos, FONT_b"#%d THD: %4.1f%%", h_count, thd); break; } } else diff --git a/sa_core.c b/sa_core.c index 3f53df5..06da112 100644 --- a/sa_core.c +++ b/sa_core.c @@ -2105,18 +2105,24 @@ done: #endif } -#ifdef TINYSA4 -#define frequency_seatch_gate 60 // 120% of the RBW -#else -#define frequency_seatch_gate 100 // 200% of the RBW -#endif +//#ifdef TINYSA4 +//#define frequency_seatch_gate 60 // 120% of the RBW +//#else +//#define frequency_seatch_gate 100 // 200% of the RBW +//#endif int binary_search_frequency(freq_t f) // Search which index in the frequency tabled matches with frequency f using actual_rbw { int L = 0; - int R = (sizeof frequencies)/sizeof(int) - 1; - freq_t fmin = f - actual_rbw_x10 * frequency_seatch_gate; - freq_t fplus = f + actual_rbw_x10 * frequency_seatch_gate; + int frequency_seatch_gate = (frequencies[1] - frequencies[0]) >> 1; + if (f < frequencies[0]) + return -1; + if (f > frequencies[sweep_points-1]) + return -1; +// int R = (sizeof frequencies)/sizeof(int) - 1; + int R = sweep_points - 1; + freq_t fmin = f - frequency_seatch_gate; // actual_rbw_x10 * frequency_seatch_gate; + freq_t fplus = f + frequency_seatch_gate; // actual_rbw_x10 * frequency_seatch_gate; while (L <= R) { int m = (L + R) / 2; if (frequencies[m] < fmin) @@ -2129,6 +2135,37 @@ int binary_search_frequency(freq_t f) // Search which index in the frequenc return -1; } +int index_of_frequency(freq_t f) // Search which index in the frequency tabled matches with frequency f using actual_rbw +{ + freq_t f_step = frequencies[1] - frequencies[0]; + if (f_step == 0) + return 0; + if (f < frequencies[0]) + return -1; + if (f > frequencies[sweep_points-1]) + return -1; + int i = (f + (f_step >> 1))* sweep_points / (frequencies[sweep_points-1] - frequencies[0]); + return i; +#if 0 + // int R = (sizeof frequencies)/sizeof(int) - 1; + int L = 0; + int R = sweep_points - 1; + freq_t fmin = f - frequency_seatch_gate; // actual_rbw_x10 * frequency_seatch_gate; + freq_t fplus = f + frequency_seatch_gate; // actual_rbw_x10 * frequency_seatch_gate; + while (L <= R) { + int m = (L + R) / 2; + if (frequencies[m] < fmin) + L = m + 1; + else if (frequencies[m] > fplus) + R = m - 1; + else + return m; // index is m + } +#endif +} + + + void interpolate_maximum(int m) { const int idx = markers[m].index; @@ -2154,7 +2191,7 @@ void interpolate_maximum(int m) int search_maximum(int m, freq_t center, int span) { - int center_index = binary_search_frequency(center); + int center_index = index_of_frequency(center); if (center_index < 0) return false; int from = center_index - span/2; @@ -2212,6 +2249,15 @@ search_maximum(int m, freq_t center, int span) } } } + if (false && !found) { + temppeakIndex = from; + temppeakLevel = actual_t[from]; + for (int i = from+1; i <= to; i++) { + if (temppeakLevel 10) { // ----- IMD measurement - markers[1].enabled = search_maximum(1, frequencies[markers[0].index]*2, 8); - markers[2].enabled = search_maximum(2, frequencies[markers[0].index]*3, 12); - markers[3].enabled = search_maximum(3, frequencies[markers[0].index]*4, 16); +#ifdef TINYSA4 +#define H_SPACING 7 +#else +#define H_SPACING 4 +#endif + markers[1].enabled = search_maximum(1, frequencies[markers[0].index]*2, 2*H_SPACING); + markers[2].enabled = search_maximum(2, frequencies[markers[0].index]*3, 3*H_SPACING); + markers[3].enabled = search_maximum(3, frequencies[markers[0].index]*4, 4*H_SPACING); #ifdef TINYSA4 } else if (setting.measurement == M_AM && markers[0].index > 10) { // ----------AM measurement int l = markers[1].index; diff --git a/ui_sa.c b/ui_sa.c index 2a3496e..f5a9786 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -1156,7 +1156,13 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb) kp_help_text = "Frequency of fundamental"; ui_mode_keypad(KM_CENTER); set_sweep_frequency(ST_START, 0); - set_sweep_frequency(ST_STOP, uistat.value*5); +#ifdef TINYSA4 +#define IMD_RANGE 10 +#else +#define IMD_RANGE 5 +#endif + set_sweep_frequency(ST_STOP, uistat.value*IMD_RANGE); + set_average(AV_4); // set_measurement(M_IMD); break; case M_OIP3: // OIP3 @@ -1175,6 +1181,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb) int right = uistat.value; set_sweep_frequency(ST_CENTER, (left+right)/2); set_sweep_frequency(ST_SPAN, (right - left)*5); + set_average(AV_4); // set_measurement(M_OIP3); break; case M_PHASE_NOISE: // Phase noise @@ -1305,6 +1312,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb) // set_measurement(M_FM); break; case M_THD: + set_average(AV_4); // set_measurement(M_THD); break; #ifdef __CHANNEL_POWER__