diff --git a/Software/PC_Application/Calibration/calibration.cpp b/Software/PC_Application/Calibration/calibration.cpp index 8cec07d..2aa1a45 100644 --- a/Software/PC_Application/Calibration/calibration.cpp +++ b/Software/PC_Application/Calibration/calibration.cpp @@ -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 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 Calibration::getMeasurementTraces() } else { d.y = complex(p.real_S22, p.imag_S22); } - t->addData(d); + t->addData(d, TraceMath::DataType::Frequency); } traces.push_back(t); } diff --git a/Software/PC_Application/Calibration/calibration.h b/Software/PC_Application/Calibration/calibration.h index 98470ab..b45b9b5 100644 --- a/Software/PC_Application/Calibration/calibration.h +++ b/Software/PC_Application/Calibration/calibration.h @@ -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); diff --git a/Software/PC_Application/Calibration/calibrationtracedialog.cpp b/Software/PC_Application/Calibration/calibrationtracedialog.cpp index 2ecbcb3..771a56b 100644 --- a/Software/PC_Application/Calibration/calibrationtracedialog.cpp +++ b/Software/PC_Application/Calibration/calibrationtracedialog.cpp @@ -4,7 +4,7 @@ #include #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."); } diff --git a/Software/PC_Application/Calibration/calibrationtracedialog.h b/Software/PC_Application/Calibration/calibrationtracedialog.h index 952e7b0..074aef2 100644 --- a/Software/PC_Application/Calibration/calibrationtracedialog.h +++ b/Software/PC_Application/Calibration/calibrationtracedialog.h @@ -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: diff --git a/Software/PC_Application/Traces/trace.cpp b/Software/PC_Application/Traces/trace.cpp index 73a885f..66eb536 100644 --- a/Software/PC_Application/Traces/trace.cpp +++ b/Software/PC_Application/Traces/trace.cpp @@ -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(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(d.real_S11, d.imag_S11); - S11.addData(td); + S11.addData(td, DataType::Frequency); td.y = complex(d.real_S12, d.imag_S12); - S12.addData(td); + S12.addData(td, DataType::Frequency); td.y = complex(d.real_S21, d.imag_S21); - S21.addData(td); + S21.addData(td, DataType::Frequency); td.y = complex(d.real_S22, d.imag_S22); - S22.addData(td); + S22.addData(td, DataType::Frequency); } } diff --git a/Software/PC_Application/Traces/trace.h b/Software/PC_Application/Traces/trace.h index 700e9db..c47e170 100644 --- a/Software/PC_Application/Traces/trace.h +++ b/Software/PC_Application/Traces/trace.h @@ -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 markers; struct { union { - Protocol::SweepSettings VNA; Protocol::SpectrumAnalyzerSettings SA; }; bool valid; diff --git a/Software/PC_Application/Traces/tracemodel.cpp b/Software/PC_Application/Traces/tracemodel.cpp index e82f67d..048014d 100644 --- a/Software/PC_Application/Traces/tracemodel.cpp +++ b/Software/PC_Application/Traces/tracemodel.cpp @@ -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(d.real_S11, d.imag_S11); break; case Trace::LiveParameter::S12: td.y = complex(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); } } } diff --git a/Software/PC_Application/Traces/tracemodel.h b/Software/PC_Application/Traces/tracemodel.h index 4c41dde..6b57b1c 100644 --- a/Software/PC_Application/Traces/tracemodel.h +++ b/Software/PC_Application/Traces/tracemodel.h @@ -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: diff --git a/Software/PC_Application/Traces/tracesmithchart.cpp b/Software/PC_Application/Traces/tracesmithchart.cpp index 8ebe812..bba5a88 100644 --- a/Software/PC_Application/Traces/tracesmithchart.cpp +++ b/Software/PC_Application/Traces/tracesmithchart.cpp @@ -190,7 +190,7 @@ void TraceSmithChart::draw(QPainter &p) { for(int i=1;isample(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())) { diff --git a/Software/PC_Application/Traces/tracexyplot.cpp b/Software/PC_Application/Traces/tracexyplot.cpp index fd2aeb7..db56790 100644 --- a/Software/PC_Application/Traces/tracexyplot.cpp +++ b/Software/PC_Application/Traces/tracexyplot.cpp @@ -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 ""; } } diff --git a/Software/PC_Application/VNA/vna.cpp b/Software/PC_Application/VNA/vna.cpp index 640013e..57bc908 100644 --- a/Software/PC_Application/VNA/vna.cpp +++ b/Software/PC_Application/VNA/vna.cpp @@ -303,7 +303,8 @@ VNA::VNA(AppWindow *window) sbPowerLow->setSuffix("dbm"); sbPowerLow->setToolTip("Stimulus level"); sbPowerLow->setKeyboardTracking(false); - // TODO connect + connect(sbPowerLow, qOverload(&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(&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(&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 = "" + lo + "";} - if (settings.f_stop > cal.getMaxFreq() ) { hi = "" + hi + "";} + if (settings.Freq.start < cal.getMinFreq() ) { lo = "" + lo + "";} + if (settings.Freq.stop > cal.getMaxFreq() ) { hi = "" + hi + "";} txt = "limits: " + lo + " - " + hi + "
" @@ -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 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 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(settings.f_start)); - s.setValue("SweepStop", static_cast(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(settings.Freq.start)); + s.setValue("SweepFreqStop", static_cast(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(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); diff --git a/Software/PC_Application/VNA/vna.h b/Software/PC_Application/VNA/vna.h index 31a3c35..87dc0ee 100644 --- a/Software/PC_Application/VNA/vna.h +++ b/Software/PC_Application/VNA/vna.h @@ -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); }; diff --git a/Software/PC_Application/preferences.cpp b/Software/PC_Application/preferences.cpp index 2a4b662..9ed5ac0 100644 --- a/Software/PC_Application/preferences.cpp +++ b/Software/PC_Application/preferences.cpp @@ -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); diff --git a/Software/PC_Application/preferences.h b/Software/PC_Application/preferences.h index 68f1d73..7dc920c 100644 --- a/Software/PC_Application/preferences.h +++ b/Software/PC_Application/preferences.h @@ -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 descr = {{ + const std::array 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}, diff --git a/Software/PC_Application/preferencesdialog.ui b/Software/PC_Application/preferencesdialog.ui index ca2bb21..96bf134 100644 --- a/Software/PC_Application/preferencesdialog.ui +++ b/Software/PC_Application/preferencesdialog.ui @@ -6,15 +6,15 @@ 0 0 - 613 - 794 + 919 + 875 Preferences - - + + @@ -73,7 +73,7 @@ - 2 + 0 @@ -145,96 +145,203 @@ Vector Network Analyzer - - - - - Start: - - + + + + + + + Type: + + + + + + + + Frequency Sweep + + + + + Power Sweep + + + + + - - + + + + + + Frequency Sweep: + + + + + + Start: + + + + + + + + + + Stop: + + + + + + + + + + Simulus level: + + + + + + + dbm + + + -42.000000000000000 + + + 0.000000000000000 + + + 0.250000000000000 + + + + + + + + + + Power Sweep: + + + + + + Start: + + + + + + + dbm + + + -42.000000000000000 + + + 0.000000000000000 + + + 0.250000000000000 + + + + + + + Stop: + + + + + + + dbm + + + -42.000000000000000 + + + 0.000000000000000 + + + 0.250000000000000 + + + + + + + Frequency: + + + + + + + + + + - - - - Stop: - - - - - - - - - - Simulus level: - - - - - - - dbm - - - -42.000000000000000 - - - 0.000000000000000 - - - 0.250000000000000 - - - - - - - Points: - - - - - - - 1 - - - 4501 - - - 501 - - - - - - - IF bandwitdh: - - - - - - - - - - Averaging: - - - - - - - 1 - - - 99 - - + + + + + + Points: + + + + + + + 1 + + + 4501 + + + 501 + + + + + + + IF bandwitdh: + + + + + + + + + + Averaging: + + + + + + + 1 + + + 99 + + + + @@ -479,6 +586,16 @@ + + + + <html><head/><body><p>If enabled, the step attenuator setting will be changed during the sweep to keep the selected output power across frequency as accurate as possible.</p></body></html> + + + Adjust power level during sweep + + + @@ -683,7 +800,7 @@ - + Qt::Horizontal diff --git a/Software/PC_Application/unit.cpp b/Software/PC_Application/unit.cpp index bb957ed..08d154a 100644 --- a/Software/PC_Application/unit.cpp +++ b/Software/PC_Application/unit.cpp @@ -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); diff --git a/Software/VNA_embedded/Application/Communication/Protocol.hpp b/Software/VNA_embedded/Application/Communication/Protocol.hpp index 002284c..412b662 100644 --- a/Software/VNA_embedded/Application/Communication/Protocol.hpp +++ b/Software/VNA_embedded/Application/Communication/Protocol.hpp @@ -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; }; diff --git a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp index 2f950fa..bbafe92 100644 --- a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp +++ b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp @@ -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]); diff --git a/Software/VNA_embedded/Application/Generator.cpp b/Software/VNA_embedded/Application/Generator.cpp index 5cd20d4..ee8a2cb 100644 --- a/Software/VNA_embedded/Application/Generator.cpp +++ b/Software/VNA_embedded/Application/Generator.cpp @@ -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; diff --git a/Software/VNA_embedded/Application/VNA.cpp b/Software/VNA_embedded/Application/VNA.cpp index f4dd3cb..ef8374c 100644 --- a/Software/VNA_embedded/Application/VNA.cpp +++ b/Software/VNA_embedded/Application/VNA.cpp @@ -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();