basic working power sweep

This commit is contained in:
Jan Käberich 2021-07-09 22:26:44 +02:00
parent 7bc18881a5
commit 67489084e9
20 changed files with 598 additions and 303 deletions

View File

@ -400,30 +400,33 @@ void Calibration::correctTraces(Trace &S11, Trace &S12, Trace &S21, Trace &S22)
}
}
Calibration::InterpolationType Calibration::getInterpolation(Protocol::SweepSettings settings)
Calibration::InterpolationType Calibration::getInterpolation(double f_start, double f_stop, int npoints)
{
if(!points.size()) {
return InterpolationType::NoCalibration;
}
if(settings.f_start < points.front().frequency || settings.f_stop > points.back().frequency) {
if(f_start < points.front().frequency || f_stop > points.back().frequency) {
return InterpolationType::Extrapolate;
}
// Either exact or interpolation, check individual frequencies
uint32_t f_step;
if(settings.points > 1) {
f_step = (settings.f_stop - settings.f_start) / (settings.points - 1);
if(npoints > 1) {
f_step = (f_stop - f_start) / (npoints - 1);
} else {
f_step = settings.f_stop - settings.f_start;
f_step = f_stop - f_start;
}
for(uint64_t f = settings.f_start; f <= settings.f_stop; f += f_step) {
uint64_t f = f_start;
do {
if(find_if(points.begin(), points.end(), [&f](const Point& p){
return abs(f - p.frequency) < 100;
}) == points.end()) {
return InterpolationType::Interpolate;
}
}
f += f_step;
} while(f <= f_stop);
// if we get here all frequency points were matched
if(points.front().frequency == settings.f_start && points.back().frequency == settings.f_stop) {
if(points.front().frequency == f_start && points.back().frequency == f_stop) {
return InterpolationType::Unchanged;
} else {
return InterpolationType::Exact;
@ -617,7 +620,7 @@ std::vector<Trace *> Calibration::getErrorTermTraces()
case 10: d.y = p.re22; break;
case 11: d.y = p.re03; break;
}
traces[i]->addData(d);
traces[i]->addData(d, TraceMath::DataType::Frequency);
}
}
return traces;
@ -665,7 +668,7 @@ std::vector<Trace *> Calibration::getMeasurementTraces()
} else {
d.y = complex<double>(p.real_S22, p.imag_S22);
}
t->addData(d);
t->addData(d, TraceMath::DataType::Frequency);
}
traces.push_back(t);
}

View File

@ -59,7 +59,7 @@ public:
NoCalibration, // No calibration available
};
InterpolationType getInterpolation(Protocol::SweepSettings settings);
InterpolationType getInterpolation(double f_start, double f_stop, int points);
static Measurement MeasurementFromString(QString s);
static QString MeasurementToString(Measurement m);

View File

@ -4,7 +4,7 @@
#include <QStyle>
#include "CustomWidgets/informationbox.h"
CalibrationTraceDialog::CalibrationTraceDialog(Calibration *cal, Protocol::SweepSettings sweep, Calibration::Type type) :
CalibrationTraceDialog::CalibrationTraceDialog(Calibration *cal, double f_min, double f_max, Calibration::Type type) :
QDialog(nullptr),
ui(new Ui::CalibrationTraceDialog),
cal(cal),
@ -28,7 +28,7 @@ CalibrationTraceDialog::CalibrationTraceDialog(Calibration *cal, Protocol::Sweep
if(type != Calibration::Type::None) {
auto kit = cal->getCalibrationKit();
auto isTRL = type == Calibration::Type::TRL;
if(kit.minFreq(isTRL) > sweep.f_start || kit.maxFreq(isTRL) < sweep.f_stop) {
if(kit.minFreq(isTRL) > f_min || kit.maxFreq(isTRL) < f_max) {
InformationBox::ShowMessage("Warning", "The calibration kit does not completely cover the currently selected span. "
"Applying a calibration will not be possible for any measurements taken with these settings.");
}

View File

@ -15,7 +15,7 @@ class CalibrationTraceDialog : public QDialog
Q_OBJECT
public:
explicit CalibrationTraceDialog(Calibration *cal, Protocol::SweepSettings sweep, Calibration::Type type = Calibration::Type::None);
explicit CalibrationTraceDialog(Calibration *cal, double f_min, double f_max, Calibration::Type type = Calibration::Type::None);
~CalibrationTraceDialog();
public slots:

View File

@ -52,7 +52,12 @@ void Trace::clear() {
emit outputSamplesChanged(0, 0);
}
void Trace::addData(const Trace::Data& d) {
void Trace::addData(const Trace::Data& d, DataType domain) {
if(this->domain != domain) {
clear();
this->domain = domain;
emit typeChanged(this);
}
// add or replace data in vector while keeping it sorted with increasing frequency
auto lower = lower_bound(data.begin(), data.end(), d, [](const Data &lhs, const Data &rhs) -> bool {
return lhs.x < rhs.x;
@ -90,18 +95,11 @@ void Trace::addData(const Trace::Data& d) {
emit outputSamplesChanged(index, index + 1);
}
void Trace::addData(const Trace::Data &d, const Protocol::SweepSettings &s)
{
settings.VNA = s;
settings.valid = true;
addData(d);
}
void Trace::addData(const Trace::Data &d, const Protocol::SpectrumAnalyzerSettings &s)
{
settings.SA = s;
settings.valid = true;
addData(d);
addData(d, DataType::Frequency);
}
void Trace::setName(QString name) {
@ -128,7 +126,7 @@ void Trace::fillFromTouchstone(Touchstone &t, unsigned int parameter)
Data d;
d.x = tData.frequency;
d.y = t.point(i).S[parameter];
addData(d);
addData(d, DataType::Frequency);
}
// check if parameter is square (e.i. S11/S22/S33/...)
parameter++;
@ -217,7 +215,7 @@ QString Trace::fillFromCSV(CSV &csv, unsigned int parameter)
Data d;
d.x = xColumn[i];
d.y = complex<double>(real[i], imag[i]);
addData(d);
addData(d, DataType::Frequency);
}
reflection = false;
createdFromFile = true;
@ -236,13 +234,13 @@ void Trace::fillFromDatapoints(Trace &S11, Trace &S12, Trace &S21, Trace &S22, c
Trace::Data td;
td.x = d.frequency;
td.y = complex<double>(d.real_S11, d.imag_S11);
S11.addData(td);
S11.addData(td, DataType::Frequency);
td.y = complex<double>(d.real_S12, d.imag_S12);
S12.addData(td);
S12.addData(td, DataType::Frequency);
td.y = complex<double>(d.real_S21, d.imag_S21);
S21.addData(td);
S21.addData(td, DataType::Frequency);
td.y = complex<double>(d.real_S22, d.imag_S22);
S22.addData(td);
S22.addData(td, DataType::Frequency);
}
}

View File

@ -42,8 +42,7 @@ public:
void clear();
void addData(const Data& d);
void addData(const Data& d, const Protocol::SweepSettings& s);
void addData(const Data& d, DataType domain);
void addData(const Data& d, const Protocol::SpectrumAnalyzerSettings& s);
void setName(QString name);
void setVelocityFactor(double v);
@ -179,7 +178,6 @@ private:
std::set<Marker*> markers;
struct {
union {
Protocol::SweepSettings VNA;
Protocol::SpectrumAnalyzerSettings SA;
};
bool valid;

View File

@ -205,12 +205,22 @@ void TraceModel::clearLiveData()
}
}
void TraceModel::addVNAData(const Protocol::Datapoint &d, const Protocol::SweepSettings& settings)
void TraceModel::addVNAData(const Protocol::Datapoint &d, TraceMath::DataType datatype)
{
for(auto t : traces) {
if (t->isLive() && !t->isPaused()) {
Trace::Data td;
td.x = d.frequency;
switch(datatype) {
case TraceMath::DataType::Frequency:
td.x = d.frequency;
break;
case TraceMath::DataType::Power:
td.x = (double) d.cdbm / 100.0;
break;
default:
// invalid type, can not add
return;
}
switch(t->liveParameter()) {
case Trace::LiveParameter::S11: td.y = complex<double>(d.real_S11, d.imag_S11); break;
case Trace::LiveParameter::S12: td.y = complex<double>(d.real_S12, d.imag_S12); break;
@ -220,7 +230,7 @@ void TraceModel::addVNAData(const Protocol::Datapoint &d, const Protocol::SweepS
// not a VNA trace, skip
continue;
}
t->addData(td, settings);
t->addData(td, datatype);
}
}
}

View File

@ -54,7 +54,7 @@ signals:
public slots:
void clearLiveData();
void addVNAData(const Protocol::Datapoint& d, const Protocol::SweepSettings& settings);
void addVNAData(const Protocol::Datapoint& d, TraceMath::DataType datatype);
void addSAData(const Protocol::SpectrumAnalyzerResult& d, const Protocol::SpectrumAnalyzerSettings& settings);
private:

View File

@ -190,7 +190,7 @@ void TraceSmithChart::draw(QPainter &p) {
for(int i=1;i<nPoints;i++) {
auto last = trace->sample(i-1);
auto now = trace->sample(i);
if (limitToSpan && (last.x < sweep_fmin || now.x > sweep_fmax)) {
if (limitToSpan && (trace->getDataType() == Trace::DataType::Frequency) && (last.x < sweep_fmin || now.x > sweep_fmax)) {
continue;
}
if(isnan(now.y.real())) {

View File

@ -1047,7 +1047,7 @@ QString TraceXYPlot::mouseText(QPoint pos)
QPointF coords[2];
coords[0] = pixelToPlotValue(pos, 0);
coords[1] = pixelToPlotValue(pos, 1);
int significantDigits = floor(log10(XAxis.rangeMax)) - floor(log10((XAxis.rangeMax - XAxis.rangeMin) / 1000.0)) + 1;
int significantDigits = floor(log10(abs(XAxis.rangeMax))) - floor(log10((abs(XAxis.rangeMax - XAxis.rangeMin)) / 1000.0)) + 1;
ret += Unit::ToString(coords[0].x(), AxisUnit(XAxis.type), "fpnum kMG", significantDigits) + "\n";
for(int i=0;i<2;i++) {
if(YAxis[i].type != YAxisType::Disabled) {
@ -1082,6 +1082,6 @@ QString TraceXYPlot::AxisUnit(TraceXYPlot::XAxisType type)
case XAxisType::Time: return "s";
case XAxisType::Distance: return "m";
case XAxisType::Power: return "dBm";
default: return ""; break;
default: return "";
}
}

View File

@ -303,7 +303,8 @@ VNA::VNA(AppWindow *window)
sbPowerLow->setSuffix("dbm");
sbPowerLow->setToolTip("Stimulus level");
sbPowerLow->setKeyboardTracking(false);
// TODO connect
connect(sbPowerLow, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &VNA::SetStartPower);
connect(this, &VNA::startPowerChanged, sbPowerLow, &QDoubleSpinBox::setValue);
powerSweepActions.push_back(tb_sweep->addWidget(new QLabel("From:")));
powerSweepActions.push_back(tb_sweep->addWidget(sbPowerLow));
@ -315,7 +316,8 @@ VNA::VNA(AppWindow *window)
sbPowerHigh->setSuffix("dbm");
sbPowerHigh->setToolTip("Stimulus level");
sbPowerHigh->setKeyboardTracking(false);
// TODO connect
connect(sbPowerHigh, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &VNA::SetStopPower);
connect(this, &VNA::stopPowerChanged, sbPowerHigh, &QDoubleSpinBox::setValue);
powerSweepActions.push_back(tb_sweep->addWidget(new QLabel("To:")));
powerSweepActions.push_back(tb_sweep->addWidget(sbPowerHigh));
@ -323,7 +325,8 @@ VNA::VNA(AppWindow *window)
width = QFontMetrics(ePowerFreq->font()).width("3.00000GHz") + 15;
ePowerFreq->setFixedWidth(width);
ePowerFreq->setToolTip("Start frequency");
// TODO connect
connect(ePowerFreq, &SIUnitEdit::valueChanged, this, &VNA::SetPowerSweepFrequency);
connect(this, &VNA::powerSweepFrequencyChanged, ePowerFreq, &SIUnitEdit::setValueQuiet);
powerSweepActions.push_back(tb_sweep->addWidget(new QLabel("at:")));
powerSweepActions.push_back(tb_sweep->addWidget(ePowerFreq));
@ -345,34 +348,6 @@ VNA::VNA(AppWindow *window)
frequencySweepActions.push_back(tb_acq->addWidget(new QLabel("Level:")));
frequencySweepActions.push_back(tb_acq->addWidget(dbm));
auto configureToolbarForFrequencySweep = [=](){
for(auto a : frequencySweepActions) {
a->setVisible(true);
}
for(auto a : powerSweepActions) {
a->setVisible(false);
}
};
auto configureToolbarForPowerSweep = [=](){
for(auto a : frequencySweepActions) {
a->setVisible(false);
}
for(auto a : powerSweepActions) {
a->setVisible(true);
}
};
connect(cbSweepType, &QComboBox::currentTextChanged, [=](QString text) {
if(text == "Frequency") {
configureToolbarForFrequencySweep();
} else if(text == "Power") {
configureToolbarForPowerSweep();
}
});
// initial setup is frequency sweep
configureToolbarForFrequencySweep();
auto points = new QSpinBox();
points->setFixedWidth(55);
points->setRange(1, 9999);
@ -487,6 +462,41 @@ VNA::VNA(AppWindow *window)
tb_cal->addWidget(cbType);
window->addToolBar(tb_cal);
auto configureToolbarForFrequencySweep = [=](){
for(auto a : frequencySweepActions) {
a->setVisible(true);
}
for(auto a : powerSweepActions) {
a->setVisible(false);
}
// enable calibration menu entries
calData->setEnabled(true);
};
auto configureToolbarForPowerSweep = [=](){
for(auto a : frequencySweepActions) {
a->setVisible(false);
}
for(auto a : powerSweepActions) {
a->setVisible(true);
}
// disable calibration menu entries
calData->setEnabled(false);
};
connect(cbSweepType, qOverload<int>(&QComboBox::currentIndexChanged), [=](int index) {
SetSweepType((SweepType) index);
});
connect(this, &VNA::sweepTypeChanged, [=](SweepType sw) {
if(sw == SweepType::Frequency) {
configureToolbarForFrequencySweep();
} else if(sw == SweepType::Power) {
configureToolbarForPowerSweep();
}
});
// initial setup is frequency sweep
SetSweepType(SweepType::Frequency);
toolbars.insert(tb_cal);
// auto tb_portExtension = portExtension.createToolbar();
@ -514,20 +524,17 @@ VNA::VNA(AppWindow *window)
// Set initial sweep settings
auto pref = Preferences::getInstance();
if(pref.Acquisition.alwaysExciteBothPorts) {
settings.excitePort1 = 1;
settings.excitePort2 = 1;
} else {
settings.excitePort1 = traceModel.PortExcitationRequired(1);
settings.excitePort2 = traceModel.PortExcitationRequired(2);
}
if(pref.Startup.RememberSweepSettings) {
LoadSweepSettings();
} else {
settings.f_start = pref.Startup.DefaultSweep.start;
settings.f_stop = pref.Startup.DefaultSweep.stop;
settings.Freq.start = pref.Startup.DefaultSweep.f_start;
settings.Freq.stop = pref.Startup.DefaultSweep.f_stop;
SetSourceLevel(pref.Startup.DefaultSweep.f_excitation);
ConstrainAndUpdateFrequencies();
SetSourceLevel(pref.Startup.DefaultSweep.excitation);
SetStartPower(pref.Startup.DefaultSweep.dbm_start);
SetStopPower(pref.Startup.DefaultSweep.dbm_stop);
SetPowerSweepFrequency(pref.Startup.DefaultSweep.dbm_freq);
SetIFBandwidth(pref.Startup.DefaultSweep.bandwidth);
SetAveraging(pref.Startup.DefaultSweep.averaging);
SetPoints(pref.Startup.DefaultSweep.points);
@ -544,9 +551,25 @@ VNA::VNA(AppWindow *window)
finalize(central);
}
Calibration::InterpolationType VNA::getCalInterpolation()
{
double f_min, f_max;
switch(settings.sweepType) {
case SweepType::Frequency:
f_min = settings.Freq.start;
f_max = settings.Freq.stop;
break;
case SweepType::Power:
f_min = settings.Power.frequency;
f_max = settings.Power.frequency;
break;
}
return cal.getInterpolation(f_min, f_max, settings.npoints);
}
QString VNA::getCalStyle()
{
Calibration::InterpolationType interpol = cal.getInterpolation(settings);
Calibration::InterpolationType interpol = getCalInterpolation();
QString style = "";
switch (interpol)
{
@ -568,7 +591,7 @@ QString VNA::getCalStyle()
QString VNA::getCalToolTip()
{
Calibration::InterpolationType interpol = cal.getInterpolation(settings);
Calibration::InterpolationType interpol = getCalInterpolation();
QString txt = "";
switch (interpol)
{
@ -579,8 +602,8 @@ QString VNA::getCalToolTip()
{
QString lo = Unit::ToString(cal.getMinFreq(), "", " kMG", 5);
QString hi = Unit::ToString(cal.getMaxFreq(), "", " kMG", 5);
if (settings.f_start < cal.getMinFreq() ) { lo = "<font color=\"red\">" + lo + "</font>";}
if (settings.f_stop > cal.getMaxFreq() ) { hi = "<font color=\"red\">" + hi + "</font>";}
if (settings.Freq.start < cal.getMinFreq() ) { lo = "<font color=\"red\">" + lo + "</font>";}
if (settings.Freq.stop > cal.getMaxFreq() ) { hi = "<font color=\"red\">" + hi + "</font>";}
txt =
"limits: " + lo + " - " + hi
+ "<br>"
@ -688,14 +711,14 @@ void VNA::NewDatapoint(Protocol::Datapoint d)
if(!calWaitFirst || d.pointNum == 0) {
calWaitFirst = false;
cal.addMeasurement(calMeasurement, d);
if(d.pointNum == settings.points - 1) {
if(d.pointNum == settings.npoints - 1) {
calMeasuring = false;
qDebug() << "Calibration measurement" << cal.MeasurementToString(calMeasurement) << "complete";
emit CalibrationMeasurementComplete(calMeasurement);
}
}
}
int percentage = (((average.currentSweep() - 1) * 100) + (d.pointNum + 1) * 100 / settings.points) / averages;
int percentage = (((average.currentSweep() - 1) * 100) + (d.pointNum + 1) * 100 / settings.npoints) / averages;
calDialog.setValue(percentage);
}
if(calValid) {
@ -706,9 +729,19 @@ void VNA::NewDatapoint(Protocol::Datapoint d)
deembedding.Deembed(d);
}
traceModel.addVNAData(d, settings);
TraceMath::DataType type;
switch(settings.sweepType) {
case SweepType::Frequency:
type = TraceMath::DataType::Frequency;
break;
case SweepType::Power:
type = TraceMath::DataType::Power;
break;
}
traceModel.addVNAData(d, type);
emit dataChanged();
if(d.pointNum == settings.points - 1) {
if(d.pointNum == settings.npoints - 1) {
UpdateAverageCount();
markerModel->updateMarkers();
}
@ -726,11 +759,39 @@ void VNA::UpdateAverageCount()
void VNA::SettingsChanged(std::function<void (Device::TransmissionResult)> cb)
{
settings.suppressPeaks = Preferences::getInstance().Acquisition.suppressPeaks ? 1 : 0;
// assemble VNA protocol settings
Protocol::SweepSettings s;
s.suppressPeaks = Preferences::getInstance().Acquisition.suppressPeaks ? 1 : 0;
if(Preferences::getInstance().Acquisition.alwaysExciteBothPorts) {
s.excitePort1 = 1;
s.excitePort2 = 1;
} else {
s.excitePort1 = traceModel.PortExcitationRequired(1);
s.excitePort2 = traceModel.PortExcitationRequired(2);
}
settings.excitingPort1 = s.excitePort1;
settings.excitingPort2 = s.excitePort2;
if(settings.sweepType == SweepType::Frequency) {
s.fixedPowerSetting = Preferences::getInstance().Acquisition.adjustPowerLevel ? 0 : 1;
s.f_start = settings.Freq.start;
s.f_stop = settings.Freq.stop;
s.points = settings.npoints;
s.if_bandwidth = settings.bandwidth;
s.cdbm_excitation_start = settings.Freq.excitation_power * 100;
s.cdbm_excitation_stop = settings.Freq.excitation_power * 100;
} else if(settings.sweepType == SweepType::Power) {
s.fixedPowerSetting = 0;
s.f_start = settings.Power.frequency;
s.f_stop = settings.Power.frequency;
s.points = settings.npoints;
s.if_bandwidth = settings.bandwidth;
s.cdbm_excitation_start = settings.Power.start * 100;
s.cdbm_excitation_stop = settings.Power.stop * 100;
}
if(window->getDevice() && Mode::getActiveMode() == this) {
window->getDevice()->Configure(settings, [=](Device::TransmissionResult res){
window->getDevice()->Configure(s, [=](Device::TransmissionResult res){
// device received command, reset traces now
average.reset(settings.points);
average.reset(s.points);
traceModel.clearLiveData();
UpdateAverageCount();
UpdateCalWidget();
@ -739,7 +800,7 @@ void VNA::SettingsChanged(std::function<void (Device::TransmissionResult)> cb)
}
});
}
emit traceModel.SpanChanged(settings.f_start, settings.f_stop);
emit traceModel.SpanChanged(s.f_start, s.f_stop);
}
void VNA::StartImpedanceMatching()
@ -748,38 +809,48 @@ void VNA::StartImpedanceMatching()
dialog->show();
}
void VNA::SetSweepType(SweepType sw)
{
if(settings.sweepType != sw) {
settings.sweepType = sw;
emit sweepTypeChanged(sw);
SettingsChanged();
}
}
void VNA::SetStartFreq(double freq)
{
settings.f_start = freq;
if(settings.f_stop < freq) {
settings.f_stop = freq;
settings.Freq.start = freq;
if(settings.Freq.stop < freq) {
settings.Freq.stop = freq;
}
ConstrainAndUpdateFrequencies();
}
void VNA::SetStopFreq(double freq)
{
settings.f_stop = freq;
if(settings.f_start > freq) {
settings.f_start = freq;
settings.Freq.stop = freq;
if(settings.Freq.start > freq) {
settings.Freq.start = freq;
}
ConstrainAndUpdateFrequencies();
}
void VNA::SetCenterFreq(double freq)
{
auto old_span = settings.f_stop - settings.f_start;
auto old_span = settings.Freq.stop - settings.Freq.start;
if (freq - old_span / 2 <= Device::Info().limits_minFreq) {
// would shift start frequency below minimum
settings.f_start = 0;
settings.f_stop = 2 * freq;
settings.Freq.start = 0;
settings.Freq.stop = 2 * freq;
} else if(freq + old_span / 2 >= Device::Info().limits_maxFreq) {
// would shift stop frequency above maximum
settings.f_start = 2 * freq - Device::Info().limits_maxFreq;
settings.f_stop = Device::Info().limits_maxFreq;
settings.Freq.start = 2 * freq - Device::Info().limits_maxFreq;
settings.Freq.stop = Device::Info().limits_maxFreq;
} else {
settings.f_start = freq - old_span / 2;
settings.f_stop = freq + old_span / 2;
settings.Freq.start = freq - old_span / 2;
settings.Freq.stop = freq + old_span / 2;
}
ConstrainAndUpdateFrequencies();
}
@ -787,48 +858,48 @@ void VNA::SetCenterFreq(double freq)
void VNA::SetSpan(double span)
{
auto maxFreq = Preferences::getInstance().Acquisition.harmonicMixing ? Device::Info().limits_maxFreqHarmonic : Device::Info().limits_maxFreq;
auto old_center = (settings.f_start + settings.f_stop) / 2;
auto old_center = (settings.Freq.start + settings.Freq.stop) / 2;
if(old_center < Device::Info().limits_minFreq + span / 2) {
// would shift start frequency below minimum
settings.f_start = Device::Info().limits_minFreq;
settings.f_stop = Device::Info().limits_minFreq + span;
settings.Freq.start = Device::Info().limits_minFreq;
settings.Freq.stop = Device::Info().limits_minFreq + span;
} else if(old_center > maxFreq - span / 2) {
// would shift stop frequency above maximum
settings.f_start = maxFreq - span;
settings.f_stop = maxFreq;
settings.Freq.start = maxFreq - span;
settings.Freq.stop = maxFreq;
} else {
settings.f_start = old_center - span / 2;
settings.f_stop = settings.f_start + span;
settings.Freq.start = old_center - span / 2;
settings.Freq.stop = settings.Freq.start + span;
}
ConstrainAndUpdateFrequencies();
}
void VNA::SetFullSpan()
{
settings.f_start = Device::Info().limits_minFreq;
settings.f_stop = Device::Info().limits_maxFreq;
settings.Freq.start = Device::Info().limits_minFreq;
settings.Freq.stop = Device::Info().limits_maxFreq;
ConstrainAndUpdateFrequencies();
}
void VNA::SpanZoomIn()
{
auto center = (settings.f_start + settings.f_stop) / 2;
auto old_span = settings.f_stop - settings.f_start;
settings.f_start = center - old_span / 4;
settings.f_stop = center + old_span / 4;
auto center = (settings.Freq.start + settings.Freq.stop) / 2;
auto old_span = settings.Freq.stop - settings.Freq.start;
settings.Freq.start = center - old_span / 4;
settings.Freq.stop = center + old_span / 4;
ConstrainAndUpdateFrequencies();
}
void VNA::SpanZoomOut()
{
auto center = (settings.f_start + settings.f_stop) / 2;
auto old_span = settings.f_stop - settings.f_start;
auto center = (settings.Freq.start + settings.Freq.stop) / 2;
auto old_span = settings.Freq.stop - settings.Freq.start;
if(center > old_span) {
settings.f_start = center - old_span;
settings.Freq.start = center - old_span;
} else {
settings.f_start = 0;
settings.Freq.start = 0;
}
settings.f_stop = center + old_span;
settings.Freq.stop = center + old_span;
ConstrainAndUpdateFrequencies();
}
@ -840,7 +911,28 @@ void VNA::SetSourceLevel(double level)
level = Device::Info().limits_cdbm_min / 100.0;
}
emit sourceLevelChanged(level);
settings.cdbm_excitation = level * 100;
settings.Freq.excitation_power = level;
SettingsChanged();
}
void VNA::SetStartPower(double level)
{
settings.Power.start = level;
emit startPowerChanged(level);
SettingsChanged();
}
void VNA::SetStopPower(double level)
{
settings.Power.stop = level;
emit stopPowerChanged(level);
SettingsChanged();
}
void VNA::SetPowerSweepFrequency(double freq)
{
settings.Power.frequency = freq;
emit powerSweepFrequencyChanged(freq);
SettingsChanged();
}
@ -852,7 +944,7 @@ void VNA::SetPoints(unsigned int points)
points = 2;
}
emit pointsChanged(points);
settings.points = points;
settings.npoints = points;
SettingsChanged();
}
@ -863,8 +955,8 @@ void VNA::SetIFBandwidth(double bandwidth)
} else if(bandwidth < Device::Info().limits_minIFBW) {
bandwidth = Device::Info().limits_minIFBW;
}
settings.if_bandwidth = bandwidth;
emit IFBandwidthChanged(bandwidth);
settings.bandwidth = bandwidth;
emit IFBandwidthChanged(settings.bandwidth);
SettingsChanged();
}
@ -883,10 +975,10 @@ void VNA::ExcitationRequired(bool port1, bool port2)
port2 = true;
}
// check if settings actually changed
if(settings.excitePort1 != port1
|| settings.excitePort2 != port2) {
settings.excitePort1 = port1;
settings.excitePort2 = port2;
if(settings.excitingPort1 != port1
|| settings.excitingPort2 != port2) {
settings.excitingPort1 = port1;
settings.excitingPort2 = port2;
SettingsChanged();
}
}
@ -915,10 +1007,16 @@ void VNA::ApplyCalibration(Calibration::Type type)
DisableCalibration(true);
}
} else {
// Not all required traces available
InformationBox::ShowMessageBlocking("Missing calibration measurements", "Not all calibration measurements for this type of calibration have been taken. The calibration can be enabled after the missing measurements have been acquired.");
DisableCalibration(true);
StartCalibrationDialog(type);
if(settings.sweepType == SweepType::Frequency) {
// Not all required traces available
InformationBox::ShowMessageBlocking("Missing calibration measurements", "Not all calibration measurements for this type of calibration have been taken. The calibration can be enabled after the missing measurements have been acquired.");
DisableCalibration(true);
StartCalibrationDialog(type);
} else {
// Not all required traces available
InformationBox::ShowMessageBlocking("Missing calibration measurements", "Not all calibration measurements for this type of calibration have been taken. Please switch to frequency sweep to take these measurements.");
DisableCalibration(true);
}
}
}
@ -971,7 +1069,7 @@ void VNA::SetupSCPI()
return "";
}
}, [=](QStringList) -> QString {
return QString::number(settings.f_stop - settings.f_start);
return QString::number(settings.Freq.stop - settings.Freq.start);
}));
scpi_freq->add(new SCPICommand("START", [=](QStringList params) -> QString {
unsigned long newval;
@ -982,7 +1080,7 @@ void VNA::SetupSCPI()
return "";
}
}, [=](QStringList) -> QString {
return QString::number(settings.f_start);
return QString::number(settings.Freq.start);
}));
scpi_freq->add(new SCPICommand("CENTer", [=](QStringList params) -> QString {
unsigned long newval;
@ -993,7 +1091,7 @@ void VNA::SetupSCPI()
return "";
}
}, [=](QStringList) -> QString {
return QString::number((settings.f_start + settings.f_stop)/2);
return QString::number((settings.Freq.start + settings.Freq.stop)/2);
}));
scpi_freq->add(new SCPICommand("STOP", [=](QStringList params) -> QString {
unsigned long newval;
@ -1004,7 +1102,7 @@ void VNA::SetupSCPI()
return "";
}
}, [=](QStringList) -> QString {
return QString::number(settings.f_stop);
return QString::number(settings.Freq.stop);
}));
scpi_freq->add(new SCPICommand("FULL", [=](QStringList params) -> QString {
Q_UNUSED(params)
@ -1022,7 +1120,7 @@ void VNA::SetupSCPI()
return "";
}
}, [=](QStringList) -> QString {
return QString::number(settings.if_bandwidth);
return QString::number(settings.bandwidth);
}));
scpi_acq->add(new SCPICommand("POINTS", [=](QStringList params) -> QString {
unsigned long newval;
@ -1033,7 +1131,7 @@ void VNA::SetupSCPI()
return "";
}
}, [=](QStringList) -> QString {
return QString::number(settings.points);
return QString::number(settings.npoints);
}));
scpi_acq->add(new SCPICommand("AVG", [=](QStringList params) -> QString {
unsigned long newval;
@ -1063,7 +1161,7 @@ void VNA::SetupSCPI()
return "";
}
}, [=](QStringList) -> QString {
return QString::number(settings.cdbm_excitation / 100.0);
return QString::number(settings.Freq.excitation_power);
}));
SCPINode::add(traceWidget);
auto scpi_cal = new SCPINode("CALibration");
@ -1122,19 +1220,19 @@ void VNA::ConstrainAndUpdateFrequencies()
} else {
maxFreq = Device::Info().limits_maxFreq;
}
if(settings.f_stop > maxFreq) {
settings.f_stop = maxFreq;
if(settings.Freq.stop > maxFreq) {
settings.Freq.stop = maxFreq;
}
if(settings.f_start > settings.f_stop) {
settings.f_start = settings.f_stop;
if(settings.Freq.start > settings.Freq.stop) {
settings.Freq.start = settings.Freq.stop;
}
if(settings.f_start < Device::Info().limits_minFreq) {
settings.f_start = Device::Info().limits_minFreq;
if(settings.Freq.start < Device::Info().limits_minFreq) {
settings.Freq.start = Device::Info().limits_minFreq;
}
emit startFreqChanged(settings.f_start);
emit stopFreqChanged(settings.f_stop);
emit spanChanged(settings.f_stop - settings.f_start);
emit centerFreqChanged((settings.f_stop + settings.f_start)/2);
emit startFreqChanged(settings.Freq.start);
emit stopFreqChanged(settings.Freq.stop);
emit spanChanged(settings.Freq.stop - settings.Freq.start);
emit centerFreqChanged((settings.Freq.stop + settings.Freq.start)/2);
SettingsChanged();
}
@ -1142,24 +1240,39 @@ void VNA::LoadSweepSettings()
{
auto pref = Preferences::getInstance();
QSettings s;
settings.f_start = s.value("SweepStart", pref.Startup.DefaultSweep.start).toULongLong();
settings.f_stop = s.value("SweepStop", pref.Startup.DefaultSweep.stop).toULongLong();
auto typeString = s.value("SweepType", pref.Startup.DefaultSweep.type).toString();
if(typeString == "Power") {
SetSweepType(SweepType::Power);
} else {
SetSweepType(SweepType::Frequency);
}
// frequency sweep settings
settings.Freq.start = s.value("SweepFreqStart", pref.Startup.DefaultSweep.f_start).toULongLong();
settings.Freq.stop = s.value("SweepFreqStop", pref.Startup.DefaultSweep.f_stop).toULongLong();
SetSourceLevel(s.value("SweepFreqLevel", pref.Startup.DefaultSweep.f_excitation).toDouble());
// power sweep settings
SetStartPower(s.value("SweepPowerStart", pref.Startup.DefaultSweep.dbm_start).toDouble());
SetStopPower(s.value("SweepPowerStop", pref.Startup.DefaultSweep.dbm_stop).toDouble());
SetPowerSweepFrequency(s.value("SweepFreqStop", pref.Startup.DefaultSweep.dbm_freq).toULongLong());
SetPoints(s.value("SweepPoints", pref.Startup.DefaultSweep.points).toInt());
SetIFBandwidth(s.value("SweepBandwidth", pref.Startup.DefaultSweep.bandwidth).toUInt());
SetAveraging(s.value("SweepAveraging", pref.Startup.DefaultSweep.averaging).toInt());
SetSourceLevel(s.value("SweepLevel", pref.Startup.DefaultSweep.excitation).toDouble());
ConstrainAndUpdateFrequencies();
}
void VNA::StoreSweepSettings()
{
QSettings s;
s.setValue("SweepStart", static_cast<unsigned long long>(settings.f_start));
s.setValue("SweepStop", static_cast<unsigned long long>(settings.f_stop));
s.setValue("SweepBandwidth", settings.if_bandwidth);
s.setValue("SweepPoints", settings.points);
s.setValue("SweepType", settings.sweepType == SweepType::Frequency ? "Frequency" : "Power");
s.setValue("SweepFreqStart", static_cast<unsigned long long>(settings.Freq.start));
s.setValue("SweepFreqStop", static_cast<unsigned long long>(settings.Freq.stop));
s.setValue("SweepFreqLevel", settings.Freq.excitation_power);
s.setValue("SweepPowerStart", settings.Power.start);
s.setValue("SweepPowerStop", settings.Power.stop);
s.setValue("SweepPowerFreq", static_cast<unsigned long long>(settings.Power.frequency));
s.setValue("SweepBandwidth", settings.bandwidth);
s.setValue("SweepPoints", settings.npoints);
s.setValue("SweepAveraging", averages);
s.setValue("SweepLevel", (double) settings.cdbm_excitation / 100.0);
}
void VNA::StopSweep()
@ -1171,7 +1284,7 @@ void VNA::StopSweep()
void VNA::StartCalibrationDialog(Calibration::Type type)
{
auto traceDialog = new CalibrationTraceDialog(&cal, settings, type);
auto traceDialog = new CalibrationTraceDialog(&cal, settings.Freq.start, settings.Freq.stop, type);
connect(traceDialog, &CalibrationTraceDialog::triggerMeasurement, this, &VNA::StartCalibrationMeasurement);
connect(traceDialog, &CalibrationTraceDialog::applyCalibration, this, &VNA::ApplyCalibration);
connect(this, &VNA::CalibrationMeasurementComplete, traceDialog, &CalibrationTraceDialog::measurementComplete);

View File

@ -15,7 +15,7 @@
class VNA : public Mode, public SCPINode
{
Q_OBJECT
public:
public:
VNA(AppWindow *window);
void deactivate() override;
@ -29,10 +29,33 @@ public:
void updateGraphColors();
enum class SweepType {
Frequency = 0,
Power = 1,
};
using Settings = struct {
SweepType sweepType;
struct {
double start;
double stop;
double excitation_power;
} Freq;
struct {
double start;
double stop;
double frequency;
} Power;
int npoints;
double bandwidth;
bool excitingPort1;
bool excitingPort2;
};
private slots:
void NewDatapoint(Protocol::Datapoint d);
void StartImpedanceMatching();
// Sweep control
void SetSweepType(SweepType sw);
void SetStartFreq(double freq);
void SetStopFreq(double freq);
void SetCenterFreq(double freq);
@ -42,6 +65,11 @@ private slots:
void SpanZoomOut();
// Acquisition control
void SetSourceLevel(double level);
// Power sweep settings
void SetStartPower(double level);
void SetStopPower(double level);
void SetPowerSweepFrequency(double freq);
void SetPoints(unsigned int points);
void SetIFBandwidth(double bandwidth);
void SetAveraging(unsigned int averages);
@ -70,7 +98,7 @@ private:
private slots:
void EnableDeembedding(bool enable);
private:
Protocol::SweepSettings settings;
Settings settings;
unsigned int averages;
TraceModel traceModel;
TraceWidget *traceWidget;
@ -85,6 +113,7 @@ private:
bool calMeasuring;
bool calWaitFirst;
QProgressDialog calDialog;
Calibration::InterpolationType getCalInterpolation();
QString getCalStyle();
QString getCalToolTip();
@ -105,6 +134,7 @@ private:
signals:
void dataChanged();
void sweepTypeChanged(SweepType sw);
void startFreqChanged(double freq);
void stopFreqChanged(double freq);
void centerFreqChanged(double freq);
@ -115,6 +145,10 @@ signals:
void IFBandwidthChanged(double bandwidth);
void averagingChanged(unsigned int averages);
void startPowerChanged(double level);
void stopPowerChanged(double level);
void powerSweepFrequencyChanged(double freq);
void CalibrationDisabled();
void CalibrationApplied(Calibration::Type type);
};

View File

@ -18,46 +18,42 @@ PreferencesDialog::PreferencesDialog(Preferences *pref, QWidget *parent) :
{
ui->setupUi(this);
auto setDefaultSettingsEnabled = [=](bool en) {
ui->StartupSweepType->setEnabled(en);
ui->StartupSweepStart->setEnabled(en);
ui->StartupSweepStop->setEnabled(en);
ui->StartupSweepPoints->setEnabled(en);
ui->StartupSweepPowerStart->setEnabled(en);
ui->StartupSweepPowerStop->setEnabled(en);
ui->StartupSweepPowerFrequency->setEnabled(en);
ui->StartupSweepLevel->setEnabled(en);
ui->StartupSweepBandwidth->setEnabled(en);
ui->StartupSweepAveraging->setEnabled(en);
ui->StartupGeneratorFrequency->setEnabled(en);
ui->StartupGeneratorLevel->setEnabled(en);
ui->StartupSAStart->setEnabled(en);
ui->StartupSAStop->setEnabled(en);
ui->StartupSARBW->setEnabled(en);
ui->StartupSAWindow->setEnabled(en);
ui->StartupSADetector->setEnabled(en);
ui->StartupSAAveraging->setEnabled(en);
ui->StartupSASignalID->setEnabled(en);
};
// Setup GUI connections and adjustments
// Startup page
connect(ui->StartupSweepLastUsed, &QPushButton::clicked, [=](){
ui->StartupSweepStart->setEnabled(false);
ui->StartupSweepStop->setEnabled(false);
ui->StartupSweepPoints->setEnabled(false);
ui->StartupSweepLevel->setEnabled(false);
ui->StartupSweepBandwidth->setEnabled(false);
ui->StartupSweepAveraging->setEnabled(false);
ui->StartupGeneratorFrequency->setEnabled(false);
ui->StartupGeneratorLevel->setEnabled(false);
ui->StartupSAStart->setEnabled(false);
ui->StartupSAStop->setEnabled(false);
ui->StartupSARBW->setEnabled(false);
ui->StartupSAWindow->setEnabled(false);
ui->StartupSADetector->setEnabled(false);
ui->StartupSAAveraging->setEnabled(false);
ui->StartupSASignalID->setEnabled(false);
setDefaultSettingsEnabled(false);
});
connect(ui->StartupSweepDefault, &QPushButton::clicked, [=](){
ui->StartupSweepStart->setEnabled(true);
ui->StartupSweepStop->setEnabled(true);
ui->StartupSweepPoints->setEnabled(true);
ui->StartupSweepLevel->setEnabled(true);
ui->StartupSweepBandwidth->setEnabled(true);
ui->StartupSweepAveraging->setEnabled(true);
ui->StartupGeneratorFrequency->setEnabled(true);
ui->StartupGeneratorLevel->setEnabled(true);
ui->StartupSAStart->setEnabled(true);
ui->StartupSAStop->setEnabled(true);
ui->StartupSARBW->setEnabled(true);
ui->StartupSAWindow->setEnabled(true);
ui->StartupSADetector->setEnabled(true);
ui->StartupSAAveraging->setEnabled(true);
ui->StartupSASignalID->setEnabled(true);
setDefaultSettingsEnabled(true);
});
ui->StartupSweepStart->setUnit("Hz");
ui->StartupSweepStart->setPrefixes(" kMG");
ui->StartupSweepStop->setUnit("Hz");
ui->StartupSweepStop->setPrefixes(" kMG");
ui->StartupSweepPowerFrequency->setUnit("Hz");
ui->StartupSweepPowerFrequency->setPrefixes(" kMG");
ui->StartupSweepBandwidth->setUnit("Hz");
ui->StartupSweepBandwidth->setPrefixes(" k");
ui->StartupGeneratorFrequency->setUnit("Hz");
@ -110,11 +106,15 @@ PreferencesDialog::PreferencesDialog(Preferences *pref, QWidget *parent) :
// apply GUI state to settings
p->Startup.ConnectToFirstDevice = ui->StartupAutoconnect->isChecked();
p->Startup.RememberSweepSettings = ui->StartupSweepLastUsed->isChecked();
p->Startup.DefaultSweep.start = ui->StartupSweepStart->value();
p->Startup.DefaultSweep.stop = ui->StartupSweepStop->value();
p->Startup.DefaultSweep.type = ui->StartupSweepType->currentText();
p->Startup.DefaultSweep.f_start = ui->StartupSweepStart->value();
p->Startup.DefaultSweep.f_stop = ui->StartupSweepStop->value();
p->Startup.DefaultSweep.f_excitation = ui->StartupSweepLevel->value();
p->Startup.DefaultSweep.dbm_start = ui->StartupSweepPowerStart->value();
p->Startup.DefaultSweep.dbm_stop = ui->StartupSweepPowerStop->value();
p->Startup.DefaultSweep.dbm_freq = ui->StartupSweepPowerFrequency->value();
p->Startup.DefaultSweep.bandwidth = ui->StartupSweepBandwidth->value();
p->Startup.DefaultSweep.points = ui->StartupSweepPoints->value();
p->Startup.DefaultSweep.excitation = ui->StartupSweepLevel->value();
p->Startup.DefaultSweep.averaging = ui->StartupSweepAveraging->value();
p->Startup.Generator.frequency = ui->StartupGeneratorFrequency->value();
p->Startup.Generator.level = ui->StartupGeneratorLevel->value();
@ -126,6 +126,7 @@ PreferencesDialog::PreferencesDialog(Preferences *pref, QWidget *parent) :
p->Startup.SA.signalID = ui->StartupSASignalID->isChecked();
p->Acquisition.alwaysExciteBothPorts = ui->AcquisitionAlwaysExciteBoth->isChecked();
p->Acquisition.suppressPeaks = ui->AcquisitionSuppressPeaks->isChecked();
p->Acquisition.adjustPowerLevel = ui->AcquisitionAdjustPowerLevel->isChecked();
p->Acquisition.harmonicMixing = ui->AcquisitionUseHarmonic->isChecked();
p->Acquisition.useDFTinSAmode = ui->AcquisitionUseDFT->isChecked();
p->Acquisition.RBWLimitForDFT = ui->AcquisitionDFTlimitRBW->value();
@ -165,11 +166,15 @@ void PreferencesDialog::setInitialGUIState()
} else {
ui->StartupSweepDefault->click();
}
ui->StartupSweepStart->setValueQuiet(p->Startup.DefaultSweep.start);
ui->StartupSweepStop->setValueQuiet(p->Startup.DefaultSweep.stop);
ui->StartupSweepType->setCurrentText(p->Startup.DefaultSweep.type);
ui->StartupSweepStart->setValueQuiet(p->Startup.DefaultSweep.f_start);
ui->StartupSweepStop->setValueQuiet(p->Startup.DefaultSweep.f_stop);
ui->StartupSweepLevel->setValue(p->Startup.DefaultSweep.f_excitation);
ui->StartupSweepPowerStart->setValue(p->Startup.DefaultSweep.dbm_start);
ui->StartupSweepPowerStop->setValue(p->Startup.DefaultSweep.dbm_stop);
ui->StartupSweepPowerFrequency->setValueQuiet(p->Startup.DefaultSweep.dbm_freq);
ui->StartupSweepBandwidth->setValueQuiet(p->Startup.DefaultSweep.bandwidth);
ui->StartupSweepPoints->setValue(p->Startup.DefaultSweep.points);
ui->StartupSweepLevel->setValue(p->Startup.DefaultSweep.excitation);
ui->StartupGeneratorFrequency->setValue(p->Startup.Generator.frequency);
ui->StartupGeneratorLevel->setValue(p->Startup.Generator.level);
ui->StartupSweepAveraging->setValue(p->Startup.DefaultSweep.averaging);
@ -183,6 +188,7 @@ void PreferencesDialog::setInitialGUIState()
ui->AcquisitionAlwaysExciteBoth->setChecked(p->Acquisition.alwaysExciteBothPorts);
ui->AcquisitionSuppressPeaks->setChecked(p->Acquisition.suppressPeaks);
ui->AcquisitionAdjustPowerLevel->setChecked(p->Acquisition.adjustPowerLevel);
ui->AcquisitionUseHarmonic->setChecked(p->Acquisition.harmonicMixing);
ui->AcquisitionUseDFT->setChecked(p->Acquisition.useDFTinSAmode);
ui->AcquisitionDFTlimitRBW->setValue(p->Acquisition.RBWLimitForDFT);

View File

@ -22,11 +22,17 @@ public:
bool ConnectToFirstDevice;
bool RememberSweepSettings;
struct {
double start;
double stop;
QString type;
double f_start;
double f_stop;
double f_excitation;
double dbm_start;
double dbm_stop;
double dbm_freq;
int points;
double bandwidth;
double excitation;
int averaging;
} DefaultSweep;
struct {
@ -46,6 +52,7 @@ public:
struct {
bool alwaysExciteBothPorts;
bool suppressPeaks;
bool adjustPowerLevel;
bool harmonicMixing;
bool useDFTinSAmode;
double RBWLimitForDFT;
@ -76,14 +83,18 @@ private:
QString name;
QVariant def;
};
const std::array<SettingDescription, 29> descr = {{
const std::array<SettingDescription, 34> descr = {{
{&Startup.ConnectToFirstDevice, "Startup.ConnectToFirstDevice", true},
{&Startup.RememberSweepSettings, "Startup.RememberSweepSettings", false},
{&Startup.DefaultSweep.start, "Startup.DefaultSweep.start", 1000000.0},
{&Startup.DefaultSweep.stop, "Startup.DefaultSweep.stop", 6000000000.0},
{&Startup.DefaultSweep.type, "Startup.DefaultSweep.type", "Frequency"},
{&Startup.DefaultSweep.f_start, "Startup.DefaultSweep.start", 1000000.0},
{&Startup.DefaultSweep.f_stop, "Startup.DefaultSweep.stop", 6000000000.0},
{&Startup.DefaultSweep.f_excitation, "Startup.DefaultSweep.excitation", -10.00},
{&Startup.DefaultSweep.dbm_start, "Startup.DefaultSweep.dbm_start", -30.00},
{&Startup.DefaultSweep.dbm_stop, "Startup.DefaultSweep.dbm_stop", -10.0},
{&Startup.DefaultSweep.dbm_freq, "Startup.DefaultSweep.dbm_freq", 1000000000.0},
{&Startup.DefaultSweep.points, "Startup.DefaultSweep.points", 501},
{&Startup.DefaultSweep.bandwidth, "Startup.DefaultSweep.bandwidth", 1000.0},
{&Startup.DefaultSweep.excitation, "Startup.DefaultSweep.excitation", -10.00},
{&Startup.DefaultSweep.averaging, "Startup.DefaultSweep.averaging", 1},
{&Startup.Generator.frequency, "Startup.Generator.frequency", 1000000000.0},
{&Startup.Generator.level, "Startup.Generator.level", -10.00},
@ -96,6 +107,7 @@ private:
{&Startup.SA.signalID, "Startup.SA.signalID", true},
{&Acquisition.alwaysExciteBothPorts, "Acquisition.alwaysExciteBothPorts", true},
{&Acquisition.suppressPeaks, "Acquisition.suppressPeaks", true},
{&Acquisition.adjustPowerLevel, "Acquisition.adjustPowerLevel", false},
{&Acquisition.harmonicMixing, "Acquisition.harmonicMixing", false},
{&Acquisition.useDFTinSAmode, "Acquisition.useDFTinSAmode", true},
{&Acquisition.RBWLimitForDFT, "Acquisition.RBWLimitForDFT", 3000.0},

View File

@ -6,15 +6,15 @@
<rect>
<x>0</x>
<y>0</y>
<width>613</width>
<height>794</height>
<width>919</width>
<height>875</height>
</rect>
</property>
<property name="windowTitle">
<string>Preferences</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
<item>
<widget class="QTreeWidget" name="treeWidget">
@ -73,7 +73,7 @@
</size>
</property>
<property name="currentIndex">
<number>2</number>
<number>0</number>
</property>
<widget class="QWidget" name="Startup">
<layout class="QHBoxLayout" name="horizontalLayout_4">
@ -145,96 +145,203 @@
<property name="title">
<string>Vector Network Analyzer</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Start:</string>
</property>
</widget>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QLabel" name="label_24">
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="StartupSweepType">
<item>
<property name="text">
<string>Frequency Sweep</string>
</property>
</item>
<item>
<property name="text">
<string>Power Sweep</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<widget class="SIUnitEdit" name="StartupSweepStart"/>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QGroupBox" name="groupBox_10">
<property name="title">
<string>Frequency Sweep:</string>
</property>
<layout class="QFormLayout" name="formLayout_6">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Start:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="SIUnitEdit" name="StartupSweepStart"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Stop:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="SIUnitEdit" name="StartupSweepStop"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Simulus level:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="StartupSweepLevel">
<property name="suffix">
<string>dbm</string>
</property>
<property name="minimum">
<double>-42.000000000000000</double>
</property>
<property name="maximum">
<double>0.000000000000000</double>
</property>
<property name="singleStep">
<double>0.250000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_11">
<property name="title">
<string>Power Sweep:</string>
</property>
<layout class="QFormLayout" name="formLayout_7">
<item row="0" column="0">
<widget class="QLabel" name="label_21">
<property name="text">
<string>Start:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="StartupSweepPowerStart">
<property name="suffix">
<string>dbm</string>
</property>
<property name="minimum">
<double>-42.000000000000000</double>
</property>
<property name="maximum">
<double>0.000000000000000</double>
</property>
<property name="singleStep">
<double>0.250000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Stop:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="StartupSweepPowerStop">
<property name="suffix">
<string>dbm</string>
</property>
<property name="minimum">
<double>-42.000000000000000</double>
</property>
<property name="maximum">
<double>0.000000000000000</double>
</property>
<property name="singleStep">
<double>0.250000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_23">
<property name="text">
<string>Frequency:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="SIUnitEdit" name="StartupSweepPowerFrequency"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Stop:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="SIUnitEdit" name="StartupSweepStop"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Simulus level:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="StartupSweepLevel">
<property name="suffix">
<string>dbm</string>
</property>
<property name="minimum">
<double>-42.000000000000000</double>
</property>
<property name="maximum">
<double>0.000000000000000</double>
</property>
<property name="singleStep">
<double>0.250000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Points:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="StartupSweepPoints">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>4501</number>
</property>
<property name="value">
<number>501</number>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>IF bandwitdh:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="SIUnitEdit" name="StartupSweepBandwidth"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>Averaging:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="StartupSweepAveraging">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>99</number>
</property>
</widget>
<item>
<layout class="QFormLayout" name="formLayout_8">
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Points:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="StartupSweepPoints">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>4501</number>
</property>
<property name="value">
<number>501</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>IF bandwitdh:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="SIUnitEdit" name="StartupSweepBandwidth"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>Averaging:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="StartupSweepAveraging">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>99</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
@ -479,6 +586,16 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="AcquisitionAdjustPowerLevel">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If enabled, the step attenuator setting will be changed during the sweep to keep the selected output power across frequency as accurate as possible.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Adjust power level during sweep</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="AcquisitionUseHarmonic">
<property name="text">
@ -683,7 +800,7 @@
</item>
</layout>
</item>
<item>
<item row="1" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>

View File

@ -53,6 +53,9 @@ QString Unit::ToString(double value, QString unit, QString prefixes, int precisi
value /= SIPrefixToFactor(prefixes[prefixIndex].toLatin1());
stringstream ss;
ss << std::fixed;
if(precision < 0) {
precision = 0;
}
if(preDotDigits >= 0) {
if(precision - preDotDigits < 0) {
ss << std::setprecision(0);

View File

@ -14,6 +14,7 @@ using Datapoint = struct _datapoint {
float real_S12, imag_S12;
float real_S22, imag_S22;
uint64_t frequency;
int16_t cdbm;
uint16_t pointNum;
};

View File

@ -221,10 +221,10 @@ void FPGA::WriteSweepConfig(uint16_t pointnum, bool lowband, uint32_t *SourceReg
}
send[2] = (LO_M & 0x000F) << 12 | LO_FRAC;
send[3] = LO_DIV_A << 13 | LO_VCO << 7 | LO_N << 1;
send[4] = Source_Power << 14 | (uint16_t) attenuation << 7 | Source_M >> 5;
if (lowband) {
send[3] |= 0x0001;
}
send[4] = Source_Power << 14 | (uint16_t) attenuation << 7 | Source_M >> 5;
send[5] = (Source_M & 0x001F) << 11 | Source_FRAC >> 1;
send[6] = (Source_FRAC & 0x0001) << 15 | Source_DIV_A << 12 | Source_VCO << 6 | Source_N;
SwitchBytes(send[0]);

View File

@ -48,7 +48,6 @@ void Generator::Setup(Protocol::GeneratorSettings g) {
m.SourceHighPower = (int) MAX2871::Power::n4dbm;
m.SourceHighband = false;
m.SourceLowPower = (int) amplitude.lowBandPower;
m.SourceHighPower = (int) MAX2871::Power::n4dbm;
} else {
m.SourceLowEN = 0;
m.SourceLowFrequency = HW::BandSwitchFrequency;
@ -66,7 +65,7 @@ void Generator::Setup(Protocol::GeneratorSettings g) {
}
m.SourceHighband = true;
m.SourceHighPower = (int) amplitude.highBandPower;
m.SourceLowPower = (int) MAX2871::Power::n4dbm;
m.SourceLowPower = (int) Si5351C::DriveStrength::mA2;
}
m.attenuator = amplitude.attenuator;

View File

@ -274,6 +274,7 @@ bool VNA::MeasurementDone(const FPGA::SamplingResult &result) {
auto port2 = port2_raw / ref;
data.pointNum = pointCnt;
data.frequency = settings.f_start + (settings.f_stop - settings.f_start) * pointCnt / (settings.points - 1);
data.cdbm = settings.cdbm_excitation_start + (settings.cdbm_excitation_stop - settings.cdbm_excitation_start) * pointCnt / (settings.points - 1);
if(excitingPort1) {
data.real_S11 = port1.real();
data.imag_S11 = port1.imag();