NanoVNA-H
NanoVNA-H copied to clipboard
(Reopened) Unexplained behaviour of calibration correction around high concentration of poles and zeros
This issue is intended to be appended to issue #38, that I closed for a mistake and I'm unable to reopen.
Hi DisLord.
I already fixed this while I added the RF switch to the schematic.
I implemented a simple extrapolation algorithm computed on the two closest measured calibration points, instead of the interpolation at the two edge of the band change point.
It works great at 300MHz, but the IS_HARMONIC _MODE macro fails to detect the other band changes (the 900MHz) probably because it has been forgotten to be changed when the instrument has been extended above 900MHz.
Anyways this is my the code for the moment that works at 300MHz:
Place this in the define area for enabling this new interpolation/extrapolation algorithm:
#define __NewBandChangeInterpolation__ 1
Place this into static void cal_interpolate(int s):
#if __NewBandChangeInterpolation__ == 1
float k1 = (float)(f - src->_frequencies[j])
/ (src->_frequencies[j+1] - src->_frequencies[j]);
// avoid glitch between freqs in different harmonics mode
if (IS_HARMONIC_MODE(src->_frequencies[j]) != IS_HARMONIC_MODE(src->_frequencies[j+1])) {
int m;
if (IS_HARMONIC_MODE(f)){
float k0 = 2 - k1;
k1 = k1 - 1;
for (eterm = 0; eterm < 5; eterm++) {
cal_data[eterm][i][0] = src->_cal_data[eterm][j+1][0] * k0 + src->_cal_data[eterm][j+2][0] * k1;
cal_data[eterm][i][1] = src->_cal_data[eterm][j+1][1] * k0 + src->_cal_data[eterm][j+2][1] * k1;
}
}
else{
float k0 = - k1;
k1 = k1 + 1;
if (j == 0){
m = j;
}
else{
m = j - 1;
}
for (eterm = 0; eterm < 5; eterm++) {
cal_data[eterm][i][0] = src->_cal_data[eterm][m][0] * k0 + src->_cal_data[eterm][j][0] * k1;
cal_data[eterm][i][1] = src->_cal_data[eterm][m][1] * k0 + src->_cal_data[eterm][j][1] * k1;
}
}
}
else{
float k0 = 1.0 - k1;
for (eterm = 0; eterm < 5; eterm++) {
cal_data[eterm][i][0] = src->_cal_data[eterm][j][0] * k0 + src->_cal_data[eterm][j+1][0] * k1;
cal_data[eterm][i][1] = src->_cal_data[eterm][j][1] * k0 + src->_cal_data[eterm][j+1][1] * k1;
}
}
break;
#else
float k1 = (float)(f - src->_frequencies[j])
/ (src->_frequencies[j+1] - src->_frequencies[j]);
// avoid glitch between freqs in different harmonics mode
if (IS_HARMONIC_MODE(src->_frequencies[j]) != IS_HARMONIC_MODE(src->_frequencies[j+1])) {
// assume f[j] < f[j+1]
k1 = IS_HARMONIC_MODE(f) ? 1.0 : 0.0;
}
float k0 = 1.0 - k1;
for (eterm = 0; eterm < 5; eterm++) {
cal_data[eterm][i][0] = src->_cal_data[eterm][j][0] * k0 + src->_cal_data[eterm][j+1][0] * k1;
cal_data[eterm][i][1] = src->_cal_data[eterm][j][1] * k0 + src->_cal_data[eterm][j+1][1] * k1;
}
break;
#endif
instead of the current:
float k1 = (float)(f - src->_frequencies[j])
/ (src->_frequencies[j+1] - src->_frequencies[j]);
// avoid glitch between freqs in different harmonics mode
if (IS_HARMONIC_MODE(src->_frequencies[j]) != IS_HARMONIC_MODE(src->_frequencies[j+1])) {
// assume f[j] < f[j+1]
k1 = IS_HARMONIC_MODE(f) ? 1.0 : 0.0;
}
float k0 = 1.0 - k1;
for (eterm = 0; eterm < 5; eterm++) {
cal_data[eterm][i][0] = src->_cal_data[eterm][j][0] * k0 + src->_cal_data[eterm][j+1][0] * k1;
cal_data[eterm][i][1] = src->_cal_data[eterm][j][1] * k0 + src->_cal_data[eterm][j+1][1] * k1;
}
break;
Now I'm working at office and I'll try fix it the IS_HARMONIC macro in the next days. Instead, in case you'll fix it before, please let me know, thank you.
Massimo - IK1IZA
Hi DisLord, Ok, to fix the glitches at the band change points do as follow.
Substitute the IS_HARMONIC_MODE(f) macro with the function int8_t IS_HARMONIC_MODE(uint32_t freq) here below
int8_t IS_HARMONIC_MODE(uint32_t freq){
if (freq > FREQ_HARMONICS * 5 ) {
return 3;
}
else{
if (freq > FREQ_HARMONICS * 3) {
return 2;
}
else{
if (freq > FREQ_HARMONICS) {
return 1;
}
else{
return 0;
}
}
}
}
And change the code into static void cal_interpolate(int s) this way:
#if __NewBandChangeInterpolation__ == 1
float k1 = (float)(f - src->_frequencies[j])
/ (src->_frequencies[j+1] - src->_frequencies[j]);
// avoid glitch between freqs in different harmonics mode
if (IS_HARMONIC_MODE(src->_frequencies[j]) != IS_HARMONIC_MODE(src->_frequencies[j+1])) {
int m;
if (IS_HARMONIC_MODE(f)==IS_HARMONIC_MODE(src->_frequencies[j+1])){
float k0 = 2 - k1;
k1 = k1 - 1;
for (eterm = 0; eterm < 5; eterm++) {
cal_data[eterm][i][0] = src->_cal_data[eterm][j+1][0] * k0 + src->_cal_data[eterm][j+2][0] * k1;
cal_data[eterm][i][1] = src->_cal_data[eterm][j+1][1] * k0 + src->_cal_data[eterm][j+2][1] * k1;
}
}
else{
float k0 = - k1;
k1 = k1 + 1;
if (j == 0){
m = j;
}
else{
m = j - 1;
}
for (eterm = 0; eterm < 5; eterm++) {
cal_data[eterm][i][0] = src->_cal_data[eterm][m][0] * k0 + src->_cal_data[eterm][j][0] * k1;
cal_data[eterm][i][1] = src->_cal_data[eterm][m][1] * k0 + src->_cal_data[eterm][j][1] * k1;
}
}
}
else{
float k0 = 1.0 - k1;
for (eterm = 0; eterm < 5; eterm++) {
cal_data[eterm][i][0] = src->_cal_data[eterm][j][0] * k0 + src->_cal_data[eterm][j+1][0] * k1;
cal_data[eterm][i][1] = src->_cal_data[eterm][j][1] * k0 + src->_cal_data[eterm][j+1][1] * k1;
}
}
break;
#else
float k1 = (float)(f - src->_frequencies[j])
/ (src->_frequencies[j+1] - src->_frequencies[j]);
// avoid glitch between freqs in different harmonics mode
if (IS_HARMONIC_MODE(src->_frequencies[j]) != IS_HARMONIC_MODE(src->_frequencies[j+1])) {
// assume f[j] < f[j+1]
k1 = IS_HARMONIC_MODE(f) ? 1.0 : 0.0;
}
float k0 = 1.0 - k1;
for (eterm = 0; eterm < 5; eterm++) {
cal_data[eterm][i][0] = src->_cal_data[eterm][j][0] * k0 + src->_cal_data[eterm][j+1][0] * k1;
cal_data[eterm][i][1] = src->_cal_data[eterm][j][1] * k0 + src->_cal_data[eterm][j+1][1] * k1;
}
break;
#endif
Substantially the only line changed respect my previous message is this:
if (IS_HARMONIC_MODE(f)){
Which turned to:
if (IS_HARMONIC_MODE(f)==IS_HARMONIC_MODE(src->_frequencies[j+1])){
After that, the glitches at the band change points are fixed.
Have a great day, Massimo - IK1IZA