mirror of
https://github.com/jankae/LibreVNA.git
synced 2026-04-04 14:07:30 +00:00
optional 2xthru impedance correction
This commit is contained in:
parent
0f7c397a8a
commit
7352ad07b5
14 changed files with 1265 additions and 367 deletions
|
|
@ -22,111 +22,11 @@ PortExtension::PortExtension()
|
|||
port2.delay = 0;
|
||||
port2.velocityFactor = 0.66;
|
||||
|
||||
measuring = false;
|
||||
kit = nullptr;
|
||||
}
|
||||
|
||||
void PortExtension::transformDatapoint(Protocol::Datapoint &d)
|
||||
{
|
||||
if(measuring) {
|
||||
if(measurements.size() > 0) {
|
||||
if(d.pointNum == 0) {
|
||||
// sweep complete, evaluate measurement
|
||||
|
||||
double last_phase = 0.0;
|
||||
double phasediff_sum = 0.0;
|
||||
vector<double> att_x, att_y;
|
||||
double avg_x = 0.0, avg_y = 0.0;
|
||||
for(auto m : measurements) {
|
||||
// grab correct measurement
|
||||
complex<double> reflection;
|
||||
if(isPort1) {
|
||||
reflection = complex<double>(m.real_S11, m.imag_S11);
|
||||
} else {
|
||||
reflection = complex<double>(m.real_S22, m.imag_S22);
|
||||
}
|
||||
// remove calkit if specified
|
||||
if(!isIdeal) {
|
||||
complex<double> calStandard;
|
||||
auto standards = kit->toSOLT(m.frequency);
|
||||
if(isOpen) {
|
||||
calStandard = standards.Open;
|
||||
} else {
|
||||
calStandard = standards.Short;
|
||||
}
|
||||
// remove effect of calibration standard
|
||||
reflection /= calStandard;
|
||||
}
|
||||
// sum phase differences to previous point
|
||||
auto phase = arg(reflection);
|
||||
if(m.pointNum == 0) {
|
||||
last_phase = phase;
|
||||
} else {
|
||||
auto phasediff = phase - last_phase;
|
||||
last_phase = phase;
|
||||
if(phasediff > M_PI) {
|
||||
phasediff -= 2 * M_PI;
|
||||
} else if(phasediff <= -M_PI) {
|
||||
phasediff += 2 * M_PI;
|
||||
}
|
||||
phasediff_sum += phasediff;
|
||||
qDebug() << phasediff;
|
||||
}
|
||||
|
||||
double x = sqrt(m.frequency / measurements.back().frequency);
|
||||
double y = 20*log10(abs(reflection));
|
||||
att_x.push_back(x);
|
||||
att_y.push_back(y);
|
||||
avg_x += x;
|
||||
avg_y += y;
|
||||
}
|
||||
auto phase = phasediff_sum / (measurements.size() - 1);
|
||||
auto freq_diff = measurements[1].frequency - measurements[0].frequency;
|
||||
auto delay = -phase / (2 * M_PI * freq_diff);
|
||||
// measured delay is two-way but port extension expects one-way
|
||||
delay /= 2;
|
||||
|
||||
// calculate linear regression with transformed square root model
|
||||
avg_x /= measurements.size();
|
||||
avg_y /= measurements.size();
|
||||
double sum_top = 0.0;
|
||||
double sum_bottom = 0.0;
|
||||
for(unsigned int i=0;i<att_x.size();i++) {
|
||||
sum_top += (att_x[i] - avg_x)*(att_y[i] - avg_y);
|
||||
sum_bottom += (att_x[i] - avg_x)*(att_x[i] - avg_x);
|
||||
}
|
||||
double beta = sum_top / sum_bottom;
|
||||
double alpha = avg_y - beta * avg_x;
|
||||
|
||||
double DCloss = -alpha / 2;
|
||||
double loss = -beta / 2;
|
||||
double freq = measurements.back().frequency;
|
||||
if(isPort1) {
|
||||
ui->P1Time->setValue(delay);
|
||||
ui->P1DCloss->setValue(DCloss);
|
||||
ui->P1Loss->setValue(loss);
|
||||
ui->P1Frequency->setValue(freq);
|
||||
} else {
|
||||
ui->P2Time->setValue(delay);
|
||||
ui->P2DCloss->setValue(DCloss);
|
||||
ui->P2Loss->setValue(loss);
|
||||
ui->P2Frequency->setValue(freq);
|
||||
}
|
||||
|
||||
if(msgBox) {
|
||||
msgBox->close();
|
||||
msgBox = nullptr;
|
||||
}
|
||||
measurements.clear();
|
||||
} else {
|
||||
measurements.push_back(d);
|
||||
}
|
||||
} else if(d.pointNum == 0) {
|
||||
// first point of sweep, start measurement
|
||||
measurements.push_back(d);
|
||||
}
|
||||
}
|
||||
|
||||
if(port1.enabled || port2.enabled) {
|
||||
// Convert measurements to complex variables
|
||||
auto S11 = complex<double>(d.real_S11, d.imag_S11);
|
||||
|
|
@ -299,16 +199,94 @@ void PortExtension::edit()
|
|||
dialog->show();
|
||||
}
|
||||
|
||||
void PortExtension::measurementCompleted(std::vector<Protocol::Datapoint> m)
|
||||
{
|
||||
if(m.size() > 0) {
|
||||
double last_phase = 0.0;
|
||||
double phasediff_sum = 0.0;
|
||||
vector<double> att_x, att_y;
|
||||
double avg_x = 0.0, avg_y = 0.0;
|
||||
for(auto p : m) {
|
||||
// grab correct measurement
|
||||
complex<double> reflection;
|
||||
if(isPort1) {
|
||||
reflection = complex<double>(p.real_S11, p.imag_S11);
|
||||
} else {
|
||||
reflection = complex<double>(p.real_S22, p.imag_S22);
|
||||
}
|
||||
// remove calkit if specified
|
||||
if(!isIdeal) {
|
||||
complex<double> calStandard;
|
||||
auto standards = kit->toSOLT(p.frequency);
|
||||
if(isOpen) {
|
||||
calStandard = standards.Open;
|
||||
} else {
|
||||
calStandard = standards.Short;
|
||||
}
|
||||
// remove effect of calibration standard
|
||||
reflection /= calStandard;
|
||||
}
|
||||
// sum phase differences to previous point
|
||||
auto phase = arg(reflection);
|
||||
if(p.pointNum == 0) {
|
||||
last_phase = phase;
|
||||
} else {
|
||||
auto phasediff = phase - last_phase;
|
||||
last_phase = phase;
|
||||
if(phasediff > M_PI) {
|
||||
phasediff -= 2 * M_PI;
|
||||
} else if(phasediff <= -M_PI) {
|
||||
phasediff += 2 * M_PI;
|
||||
}
|
||||
phasediff_sum += phasediff;
|
||||
qDebug() << phasediff;
|
||||
}
|
||||
|
||||
double x = sqrt(p.frequency / m.back().frequency);
|
||||
double y = 20*log10(abs(reflection));
|
||||
att_x.push_back(x);
|
||||
att_y.push_back(y);
|
||||
avg_x += x;
|
||||
avg_y += y;
|
||||
}
|
||||
auto phase = phasediff_sum / (m.size() - 1);
|
||||
auto freq_diff = m[1].frequency - m[0].frequency;
|
||||
auto delay = -phase / (2 * M_PI * freq_diff);
|
||||
// measured delay is two-way but port extension expects one-way
|
||||
delay /= 2;
|
||||
|
||||
// calculate linear regression with transformed square root model
|
||||
avg_x /= m.size();
|
||||
avg_y /= m.size();
|
||||
double sum_top = 0.0;
|
||||
double sum_bottom = 0.0;
|
||||
for(unsigned int i=0;i<att_x.size();i++) {
|
||||
sum_top += (att_x[i] - avg_x)*(att_y[i] - avg_y);
|
||||
sum_bottom += (att_x[i] - avg_x)*(att_x[i] - avg_x);
|
||||
}
|
||||
double beta = sum_top / sum_bottom;
|
||||
double alpha = avg_y - beta * avg_x;
|
||||
|
||||
double DCloss = -alpha / 2;
|
||||
double loss = -beta / 2;
|
||||
double freq = m.back().frequency;
|
||||
if(isPort1) {
|
||||
ui->P1Time->setValue(delay);
|
||||
ui->P1DCloss->setValue(DCloss);
|
||||
ui->P1Loss->setValue(loss);
|
||||
ui->P1Frequency->setValue(freq);
|
||||
} else {
|
||||
ui->P2Time->setValue(delay);
|
||||
ui->P2DCloss->setValue(DCloss);
|
||||
ui->P2Loss->setValue(loss);
|
||||
ui->P2Frequency->setValue(freq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PortExtension::startMeasurement()
|
||||
{
|
||||
measurements.clear();
|
||||
msgBox = new QMessageBox(QMessageBox::Information, "Auto port extension", "Taking measurement...", QMessageBox::Cancel);
|
||||
connect(msgBox, &QMessageBox::rejected, [=]() {
|
||||
measuring = false;
|
||||
measurements.clear();
|
||||
});
|
||||
msgBox->show();
|
||||
measuring = true;
|
||||
emit triggerMeasurement(isPort1, false, false, !isPort1);
|
||||
}
|
||||
|
||||
void PortExtension::setCalkit(Calkit *kit)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue