Skip to content

Commit

Permalink
vna_qt: add impedance, capacitance, and inductance graph views
Browse files Browse the repository at this point in the history
  • Loading branch information
xaxaxa committed Apr 6, 2019
1 parent 1fb44ae commit 20d8993
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 42 deletions.
9 changes: 1 addition & 8 deletions vna_qt/mainwindow.C
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,7 @@ void MainWindow::loadSettings() {
refreshRecentFiles();
cks = settings.value("calkits").value<CalKitSettings>();

nv.graphLimits = {
{-1000,-999, 12},
{-70, 30, 10}, //TYPE_MAG=1
{-180, 180, 10}, //TYPE_PHASE
{0, 50, 10}, //TYPE_GRPDELAY
{1, 11, 10}, //TYPE_SWR
{-1000,-999, 10} //TYPE_COMPLEX
};
nv.graphLimits = NetworkView::defaultGraphLimits;
}

void MainWindow::populateCalTypes() {
Expand Down
10 changes: 5 additions & 5 deletions vna_qt/markerslider.ui
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>6</number>
<number>3</number>
</property>
<property name="topMargin">
<number>0</number>
Expand Down Expand Up @@ -123,13 +123,13 @@
<string notr="true">color: red; font-weight: bold</string>
</property>
<property name="text">
<string>TextLabel</string>
<string>-100.1 Ω</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="margin">
<number>5</number>
<number>0</number>
</property>
</widget>
</item>
Expand All @@ -145,13 +145,13 @@
<string notr="true">color: blue; font-weight: bold</string>
</property>
<property name="text">
<string>TextLabel</string>
<string>TextLabel1</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="margin">
<number>5</number>
<number>0</number>
</property>
</widget>
</item>
Expand Down
138 changes: 115 additions & 23 deletions vna_qt/networkview.C
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,30 @@
using namespace std;
using namespace xaxaxa;

const vector<array<double,3> > NetworkView::defaultGraphLimits = {
{-1000,-999, 12},
{-80, 30, 11}, //TYPE_MAG=1
{-180, 180, 12}, //TYPE_PHASE
{0, 50, 10}, //TYPE_GRPDELAY
{1, 11, 10}, //TYPE_SWR
{0, 200, 10}, //TYPE_Z_RE
{-200, 200, 10}, //TYPE_Z_IM
{0, 200, 10}, //TYPE_Z_MAG
{0, 1000, 10}, //TYPE_Z_CAP
{0, 1000, 10}, //TYPE_Z_IND
{0, 1000, 10}, //TYPE_Y_RE
{-1000, 1000, 10}, //TYPE_Y_IM
{0, 1000, 10}, //TYPE_Y_MAG
{0, 1000, 10}, //TYPE_Y_CAP
{0, 1000, 10}, //TYPE_Y_IND
{-1000,-999, 10} //TYPE_COMPLEX
};

NetworkView::NetworkView() {
xAxisValueStr = [](double val) {
return to_string(val);
};
graphLimits = {
{-1000,-999, 12},
{-80, 30, 11}, //TYPE_MAG=1
{-180, 180, 12}, //TYPE_PHASE
{0, 50, 10}, //TYPE_GRPDELAY
{1, 11, 10}, //TYPE_SWR
{-1000,-999, 10} //TYPE_COMPLEX
};
graphLimits = NetworkView::defaultGraphLimits;
}

void NetworkView::init(QLayout *sliderContainer) {
Expand Down Expand Up @@ -55,12 +67,30 @@ GraphPanel* NetworkView::createGraphView(bool freqDomain, bool tr) {
case SParamViewSource::TYPE_MAG: name = "mag"; break;
case SParamViewSource::TYPE_PHASE: name = "arg"; break;
case SParamViewSource::TYPE_SWR: name = "swr"; break;
case SParamViewSource::TYPE_Z_RE: name = "Z_re"; break;
case SParamViewSource::TYPE_Z_IM: name = "Z_im"; break;
case SParamViewSource::TYPE_Z_MAG: name = "|Z|"; break;
case SParamViewSource::TYPE_Z_CAP: name = "Cseries"; break;
case SParamViewSource::TYPE_Z_IND: name = "Lseries"; break;
case SParamViewSource::TYPE_Y_RE: name = "Y_re"; break;
case SParamViewSource::TYPE_Y_IM: name = "Y_im"; break;
case SParamViewSource::TYPE_Y_MAG: name = "|Y|"; break;
case SParamViewSource::TYPE_Y_CAP: name = "Cparallel"; break;
case SParamViewSource::TYPE_Y_IND: name = "Lparallel"; break;
}
for(int row=0;row<2;row++)
for(int col=0;col<2;col++) {
if(tr && col==1) continue;

// group delay only makes sense in frequency domain view
if(!freqDomain && i==SParamViewSource::TYPE_GRPDELAY) continue;

// impedance parameters only make sense for Snn, not Snm,
// and also only in frequency domain.
if(i >= SParamViewSource::TYPE_Z_RE && i <= SParamViewSource::TYPE_Y_IND) {
if(row != col) continue;
if(!freqDomain) continue;
}
string desc = name + "(S" + to_string(row+1) + to_string(col+1) + ")";
graphTraces.push_back(desc);
graphSources.push_back({row, col, SParamViewSource::Types(i)});
Expand Down Expand Up @@ -116,6 +146,16 @@ void NetworkView::updateXAxis(double start, double step, int cnt) {
case SParamViewSource::TYPE_SWR:
case SParamViewSource::TYPE_PHASE:
case SParamViewSource::TYPE_GRPDELAY:
case SParamViewSource::TYPE_Z_RE:
case SParamViewSource::TYPE_Z_IM:
case SParamViewSource::TYPE_Z_MAG:
case SParamViewSource::TYPE_Z_CAP:
case SParamViewSource::TYPE_Z_IND:
case SParamViewSource::TYPE_Y_RE:
case SParamViewSource::TYPE_Y_IM:
case SParamViewSource::TYPE_Y_MAG:
case SParamViewSource::TYPE_Y_CAP:
case SParamViewSource::TYPE_Y_IND:
{
auto* series = dynamic_cast<QLineSeries*>(tmp.view);
series->clear();
Expand Down Expand Up @@ -160,17 +200,19 @@ void NetworkView::updateView(int viewIndex, int freqIndex) {
}
return;
}
double freqHz = xAxisAt(freqIndex)*1e6; // only meaningful in frequency domain
SParamView tmp = this->views.at(viewIndex);

VNACalibratedValue val = this->values.at(freqIndex);
complex<double> entry = val(tmp.src.row,tmp.src.col);
double z0 = 50;
complex<double> Z = -z0*(entry+1.)/(entry-1.);
complex<double> Y = -(entry-1.)/(z0*(entry+1.));

switch(tmp.src.type) {
case SParamViewSource::TYPE_MAG:
case SParamViewSource::TYPE_SWR:
case SParamViewSource::TYPE_PHASE:
case SParamViewSource::TYPE_GRPDELAY:
{
if(tmp.src.type == SParamViewSource::TYPE_COMPLEX) {
auto* view = dynamic_cast<PolarView*>(tmp.view);
view->points.at(freqIndex) = entry;
} else {
auto* series = dynamic_cast<QLineSeries*>(tmp.view);
double y = 0;
switch(tmp.src.type) {
Expand All @@ -183,6 +225,36 @@ void NetworkView::updateView(int viewIndex, int freqIndex) {
case SParamViewSource::TYPE_PHASE:
y = arg(entry)*180./M_PI;
break;
case SParamViewSource::TYPE_Z_RE:
y = Z.real();
break;
case SParamViewSource::TYPE_Z_IM:
y = Z.imag();
break;
case SParamViewSource::TYPE_Z_MAG:
y = abs(Z);
break;
case SParamViewSource::TYPE_Z_CAP: // capacitance in pF
y = -capacitance_inductance(freqHz, Z.imag()) * 1e12;
break;
case SParamViewSource::TYPE_Z_IND: // inductance in nH
y = capacitance_inductance(freqHz, Z.imag()) * 1e9;
break;
case SParamViewSource::TYPE_Y_RE:
y = Y.real() * 1000;
break;
case SParamViewSource::TYPE_Y_IM:
y = Y.imag() * 1000;
break;
case SParamViewSource::TYPE_Y_MAG:
y = abs(Y) * 1000;
break;
case SParamViewSource::TYPE_Y_CAP: // capacitance in pF
y = -capacitance_inductance_Y(freqHz, Y.imag()) * 1e12;
break;
case SParamViewSource::TYPE_Y_IND: // inductance in nH
y = capacitance_inductance_Y(freqHz, Y.imag()) * 1e9;
break;
case SParamViewSource::TYPE_GRPDELAY:
{
if(freqIndex>0) {
Expand All @@ -197,16 +269,26 @@ void NetworkView::updateView(int viewIndex, int freqIndex) {
}
default: assert(false);
}

// clamp values to avoid enlarging labels
switch(tmp.src.type) {
case SParamViewSource::TYPE_Z_CAP:
case SParamViewSource::TYPE_Z_IND:
case SParamViewSource::TYPE_Y_CAP:
case SParamViewSource::TYPE_Y_IND:
if(y < 0) y = 0;
if(y > 999) y = 999;
break;
case SParamViewSource::TYPE_Z_RE:
case SParamViewSource::TYPE_Z_IM:
case SParamViewSource::TYPE_Z_MAG:
if(y < -999) y = -999;
if(y > 999) y = 999;
break;
default: break;
}

series->replace(freqIndex,series->at(freqIndex).x(), y);
break;
}
case SParamViewSource::TYPE_COMPLEX:
{
auto* view = dynamic_cast<PolarView*>(tmp.view);
view->points.at(freqIndex) = entry;
break;
}
default: assert(false);
}
}

Expand Down Expand Up @@ -262,6 +344,16 @@ void NetworkView::updateBottomLabels(int marker) {
case SParamViewSource::TYPE_SWR: fmt = "%.2lf:1"; break;
case SParamViewSource::TYPE_PHASE: fmt = "%.1lf °"; break;
case SParamViewSource::TYPE_GRPDELAY: fmt = "%.2lf ns"; break;
case SParamViewSource::TYPE_Z_RE: fmt = "%.1lf Ω"; break;
case SParamViewSource::TYPE_Z_IM: fmt = "%.1lf Ω"; break;
case SParamViewSource::TYPE_Z_MAG: fmt = "%.1lf Ω"; break;
case SParamViewSource::TYPE_Z_CAP: fmt = "%.1lf pF"; break;
case SParamViewSource::TYPE_Z_IND: fmt = "%.2lf nH"; break;
case SParamViewSource::TYPE_Y_RE: fmt = "%.1lf mS"; break;
case SParamViewSource::TYPE_Y_IM: fmt = "%.1lf mS"; break;
case SParamViewSource::TYPE_Y_MAG: fmt = "%.1lf mS"; break;
case SParamViewSource::TYPE_Y_CAP: fmt = "%.1lf pF"; break;
case SParamViewSource::TYPE_Y_IND: fmt = "%.2lf nH"; break;
default: fmt = "%.2lf";
}
marker.ms->setLabelText(j, ssprintf(32, fmt, series->at(marker.freqIndex).y()));
Expand Down
23 changes: 18 additions & 5 deletions vna_qt/networkview.H
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,23 @@ struct SParamViewSource {
int row,col; // which S parameter are we viewing
enum Types {
UNDEFINED=0,
TYPE_MAG=1, // view must be QLineSeries
TYPE_PHASE, // view must be QLineSeries
TYPE_GRPDELAY, // view must be QLineSeries
TYPE_SWR, // view must be QLineSeries
TYPE_COMPLEX, // view must be PolarView
// view must be QLineSeries:
TYPE_MAG=1, // display the magnitude of Snn
TYPE_PHASE, // display the phase of Snn
TYPE_GRPDELAY, // group delay calculated from change in phase
TYPE_SWR, // standing wave ratio
TYPE_Z_RE, // real part of series equivalent impedance
TYPE_Z_IM, // imaginary part of series equivalent impedance
TYPE_Z_MAG, // magnitude of series equivalent impedance
TYPE_Z_CAP, // capacitance (in pF), series equivalent
TYPE_Z_IND, // inductance (in nH), series equivalent
TYPE_Y_RE, // real part of parallel equivalent admittance, mS
TYPE_Y_IM, // imaginary part of parallel equivalent admittance, mS
TYPE_Y_MAG, // magnitude of parallel equivalent admittance, mS
TYPE_Y_CAP, // capacitance (in pF), parallel equivalent
TYPE_Y_IND, // inductance (in nH), parallel equivalent
// view must be PolarView:
TYPE_COMPLEX,
_LAST
} type;
};
Expand Down Expand Up @@ -84,6 +96,7 @@ public:
// min, max, and division count of the y axis of the graph, indexed by SParamViewSource::Types
vector<array<double,3> > graphLimits;

static const vector<array<double,3> > defaultGraphLimits;


NetworkView();
Expand Down
6 changes: 5 additions & 1 deletion vna_qt/utility.H
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,16 @@ inline double swr(double power) {
return (double)fmin(11.0,(d+1)/(d-1));
}

// freq is in Hz, Z is in ohms
// freq is in Hz, Z is in ohms.
// if return value is positive, it is in henries;
// if return value is negative, it is in farads.
inline double capacitance_inductance(double freq, double Z) {
if(Z>0) return Z/(2*M_PI*freq);
return 1./(2*Z*M_PI*freq);
}
// freq is in Hz, Y is in mhos
// if return value is positive, it is in henries;
// if return value is negative, it is in farads.
inline double capacitance_inductance_Y(double freq, double Y) {
if(Y<0) return -1./(2*Y*M_PI*freq);
return -Y/(2*M_PI*freq);
Expand Down

0 comments on commit 20d8993

Please sign in to comment.