diff --git a/Software/PC_Application/Generator/generator.cpp b/Software/PC_Application/Generator/generator.cpp index b3fc876..04dbc6f 100644 --- a/Software/PC_Application/Generator/generator.cpp +++ b/Software/PC_Application/Generator/generator.cpp @@ -55,12 +55,8 @@ void Generator::updateDevice() void Generator::setupSCPI() { add(new SCPICommand("FREQuency", [=](QStringList params) -> QString { - bool ok; - if(params.size() != 1) { - return "ERROR"; - } - auto newval = params[0].toUInt(&ok); - if(!ok) { + unsigned long newval; + if(!SCPI::paramToULong(params, 0, newval)) { return "ERROR"; } else { central->setFrequency(newval); @@ -70,12 +66,9 @@ void Generator::setupSCPI() return QString::number(central->getDeviceStatus().frequency); })); add(new SCPICommand("LVL", [=](QStringList params) -> QString { - bool ok; - if(params.size() != 1) { - return "ERROR"; - } - auto newval = params[0].toDouble(&ok); - if(!ok) { + double newval; + if(!SCPI::paramToDouble(params, 0, newval)) { + return "ERROR"; } else { central->setLevel(newval); @@ -85,12 +78,8 @@ void Generator::setupSCPI() return QString::number(central->getDeviceStatus().cdbm_level / 100.0); })); add(new SCPICommand("PORT", [=](QStringList params) -> QString { - bool ok; - if(params.size() != 1) { - return "ERROR"; - } - auto newval = params[0].toUInt(&ok); - if(!ok || newval > 2) { + unsigned long newval; + if(!SCPI::paramToULong(params, 0, newval) || newval > 2) { return "ERROR"; } else { central->setPort(newval); diff --git a/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.cpp b/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.cpp index 2b4c4ec..310fd5c 100644 --- a/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.cpp +++ b/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.cpp @@ -658,21 +658,9 @@ void SpectrumAnalyzer::SetupSCPI() { auto scpi_freq = new SCPINode("FREQuency"); SCPINode::add(scpi_freq); - auto toULong = [](QStringList params) { - bool ok; - if(params.size() != 1) { - return std::numeric_limits::max(); - } - auto newval = params[0].toULong(&ok); - if(!ok) { - return std::numeric_limits::max(); - } else { - return newval; - } - }; scpi_freq->add(new SCPICommand("SPAN", [=](QStringList params) -> QString { - auto newval = toULong(params); - if(newval == std::numeric_limits::max()) { + unsigned long newval; + if(!SCPI::paramToULong(params, 0, newval)) { return "ERROR"; } else { SetSpan(newval); @@ -682,8 +670,8 @@ void SpectrumAnalyzer::SetupSCPI() return QString::number(settings.f_stop - settings.f_start); })); scpi_freq->add(new SCPICommand("START", [=](QStringList params) -> QString { - auto newval = toULong(params); - if(newval == std::numeric_limits::max()) { + unsigned long newval; + if(!SCPI::paramToULong(params, 0, newval)) { return "ERROR"; } else { SetStartFreq(newval); @@ -693,8 +681,8 @@ void SpectrumAnalyzer::SetupSCPI() return QString::number(settings.f_start); })); scpi_freq->add(new SCPICommand("CENTer", [=](QStringList params) -> QString { - auto newval = toULong(params); - if(newval == std::numeric_limits::max()) { + unsigned long newval; + if(!SCPI::paramToULong(params, 0, newval)) { return "ERROR"; } else { SetCenterFreq(newval); @@ -704,8 +692,8 @@ void SpectrumAnalyzer::SetupSCPI() return QString::number((settings.f_start + settings.f_stop)/2); })); scpi_freq->add(new SCPICommand("STOP", [=](QStringList params) -> QString { - auto newval = toULong(params); - if(newval == std::numeric_limits::max()) { + unsigned long newval; + if(!SCPI::paramToULong(params, 0, newval)) { return "ERROR"; } else { SetStopFreq(newval); @@ -722,8 +710,8 @@ void SpectrumAnalyzer::SetupSCPI() auto scpi_acq = new SCPINode("ACQuisition"); SCPINode::add(scpi_acq); scpi_acq->add(new SCPICommand("RBW", [=](QStringList params) -> QString { - auto newval = toULong(params); - if(newval == std::numeric_limits::max()) { + unsigned long newval; + if(!SCPI::paramToULong(params, 0, newval)) { return "ERROR"; } else { SetRBW(newval); @@ -786,8 +774,8 @@ void SpectrumAnalyzer::SetupSCPI() } })); scpi_acq->add(new SCPICommand("AVG", [=](QStringList params) -> QString { - auto newval = toULong(params); - if(newval == std::numeric_limits::max()) { + unsigned long newval; + if(!SCPI::paramToULong(params, 0, newval)) { return "ERROR"; } else { SetAveraging(newval); @@ -844,12 +832,9 @@ void SpectrumAnalyzer::SetupSCPI() return settings.trackingGeneratorPort ? "2" : "1"; })); scpi_tg->add(new SCPICommand("LVL", [=](QStringList params) -> QString { - bool ok; - if(params.size() != 1) { - return "ERROR"; - } - auto newval = params[0].toDouble(&ok); - if(!ok) { + double newval; + if(!SCPI::paramToDouble(params, 0, newval)) { + return "ERROR"; } else { SetTGLevel(newval); @@ -859,12 +844,8 @@ void SpectrumAnalyzer::SetupSCPI() return QString::number(settings.trackingPower / 100.0); })); scpi_tg->add(new SCPICommand("OFFset", [=](QStringList params) -> QString { - bool ok; - if(params.size() != 1) { - return "ERROR"; - } - auto newval = params[0].toLong(&ok); - if(!ok) { + long newval; + if(!SCPI::paramToLong(params, 0, newval)) { return "ERROR"; } else { SetTGOffset(newval); @@ -896,12 +877,8 @@ void SpectrumAnalyzer::SetupSCPI() return ""; }, nullptr)); scpi_norm->add(new SCPICommand("LVL", [=](QStringList params) -> QString { - bool ok; - if(params.size() != 1) { - return "ERROR"; - } - auto newval = params[0].toDouble(&ok); - if(!ok) { + double newval; + if(!SCPI::paramToDouble(params, 0, newval)) { return "ERROR"; } else { SetNormalizationLevel(newval); diff --git a/Software/PC_Application/Traces/trace.cpp b/Software/PC_Application/Traces/trace.cpp index 928d8db..0f55b9d 100644 --- a/Software/PC_Application/Traces/trace.cpp +++ b/Software/PC_Application/Traces/trace.cpp @@ -78,6 +78,7 @@ void Trace::addData(const Trace::Data& d) { *lower = d; } break; + default: break; } } else { // insert at this position @@ -512,6 +513,94 @@ std::vector Trace::assembleDatapoints(const Trace &S11, con return ret; } +Trace::LiveParameter Trace::ParameterFromString(QString s) +{ + s = s.toUpper(); + if(s == "S11") { + return LiveParameter::S11; + } else if(s == "S12") { + return LiveParameter::S12; + } else if(s == "S21") { + return LiveParameter::S21; + } else if(s == "S22") { + return LiveParameter::S22; + } else if(s == "PORT1") { + return LiveParameter::Port1; + } else if(s == "PORT2") { + return LiveParameter::Port2; + } else { + return LiveParameter::Invalid; + } +} + +QString Trace::ParameterToString(LiveParameter p) +{ + switch(p) { + case Trace::LiveParameter::S11: return "S11"; + case Trace::LiveParameter::S12: return "S12"; + case Trace::LiveParameter::S21: return "S21"; + case Trace::LiveParameter::S22: return "S22"; + case Trace::LiveParameter::Port1: return "Port1"; + case Trace::LiveParameter::Port2: return "Port2"; + default: return "Invalid"; + } +} + +bool Trace::isVNAParameter(Trace::LiveParameter p) +{ + switch(p) { + case Trace::LiveParameter::S11: + case Trace::LiveParameter::S12: + case Trace::LiveParameter::S21: + case Trace::LiveParameter::S22: + return true; + case Trace::LiveParameter::Port1: + case Trace::LiveParameter::Port2: + default: + return false; + } +} + +bool Trace::isSAParamater(Trace::LiveParameter p) +{ + switch(p) { + case Trace::LiveParameter::S11: + case Trace::LiveParameter::S12: + case Trace::LiveParameter::S21: + case Trace::LiveParameter::S22: + return false; + case Trace::LiveParameter::Port1: + case Trace::LiveParameter::Port2: + return true; + default: + return false; + } +} + +Trace::LivedataType Trace::TypeFromString(QString s) +{ + s = s.toUpper(); + if(s == "OVERWRITE") { + return LivedataType::Overwrite; + } else if(s == "MAXHOLD") { + return LivedataType::MaxHold; + } else if(s == "MINHOLD") { + return LivedataType::MinHold; + } else { + return LivedataType::Invalid; + } +} + +QString Trace::TypeToString(Trace::LivedataType t) +{ + switch(t) { + case Trace::LivedataType::Overwrite: return "Overwrite"; + case Trace::LivedataType::MaxHold: return "MaxHold"; + case Trace::LivedataType::MinHold: return "MinHold"; + default: return "Invalid"; + } +} + void Trace::updateLastMath(vector::reverse_iterator start) { TraceMath *newLast = nullptr; @@ -579,12 +668,18 @@ bool Trace::isVisible() void Trace::pause() { - paused = true; + if(!paused) { + paused = true; + emit pauseChanged(); + } } void Trace::resume() { - paused = false; + if(paused) { + paused = false; + emit pauseChanged(); + } } bool Trace::isPaused() @@ -811,6 +906,12 @@ Trace::Data Trace::sample(unsigned int index, SampleType type) const return data; } +Trace::Data Trace::interpolatedSample(double x) +{ + auto data = lastMath->getInterpolatedSample(x); + return data; +} + QString Trace::getFilename() const { return filename; diff --git a/Software/PC_Application/Traces/trace.h b/Software/PC_Application/Traces/trace.h index 2410682..8f51b31 100644 --- a/Software/PC_Application/Traces/trace.h +++ b/Software/PC_Application/Traces/trace.h @@ -27,6 +27,7 @@ public: S22, Port1, Port2, + Invalid, }; Trace(QString name = QString(), QColor color = Qt::darkYellow, LiveParameter live = LiveParameter::S11); @@ -36,6 +37,7 @@ public: Overwrite, MaxHold, MinHold, + Invalid, }; @@ -79,6 +81,8 @@ public: }; Data sample(unsigned int index, SampleType type = SampleType::Frequency) const; + // returns a (possibly interpolated sample) at a specified frequency/time + Data interpolatedSample(double x); QString getFilename() const; unsigned int getFileParameter() const; /* Returns the noise in dbm/Hz for spectrum analyzer measurements. May return NaN if calculation not possible */ @@ -130,6 +134,14 @@ public: // have the same number of samples and their samples must be at the same frequencies across all traces static std::vector assembleDatapoints(const Trace &S11, const Trace &S12, const Trace &S21, const Trace &S22); + static LiveParameter ParameterFromString(QString s); + static QString ParameterToString(LiveParameter p); + static bool isVNAParameter(LiveParameter p); + static bool isSAParamater(LiveParameter p); + + static LivedataType TypeFromString(QString s); + static QString TypeToString(LivedataType t); + public slots: void setVisible(bool visible); void setColor(QColor color); @@ -143,6 +155,7 @@ signals: void visibilityChanged(Trace *t); void dataChanged(); void nameChanged(); + void pauseChanged(); void colorChanged(Trace *t); void markerAdded(TraceMarker *m); void markerRemoved(TraceMarker *m); diff --git a/Software/PC_Application/Traces/traceeditdialog.cpp b/Software/PC_Application/Traces/traceeditdialog.cpp index bfc697d..a535794 100644 --- a/Software/PC_Application/Traces/traceeditdialog.cpp +++ b/Software/PC_Application/Traces/traceeditdialog.cpp @@ -65,25 +65,18 @@ TraceEditDialog::TraceEditDialog(Trace &t, QWidget *parent) : case Trace::LivedataType::Overwrite: ui->CLiveType->setCurrentIndex(0); break; case Trace::LivedataType::MaxHold: ui->CLiveType->setCurrentIndex(1); break; case Trace::LivedataType::MinHold: ui->CLiveType->setCurrentIndex(2); break; + default: break; } - switch(t.liveParameter()) { - case Trace::LiveParameter::S11: - case Trace::LiveParameter::S12: - case Trace::LiveParameter::S21: - case Trace::LiveParameter::S22: - VNAtrace = true; + VNAtrace = Trace::isVNAParameter(t.liveParameter()); + if(VNAtrace) { ui->CLiveParam->addItem("S11"); ui->CLiveParam->addItem("S12"); ui->CLiveParam->addItem("S21"); ui->CLiveParam->addItem("S22"); - break; - case Trace::LiveParameter::Port1: - case Trace::LiveParameter::Port2: + } else { ui->CLiveParam->addItem("Port 1"); ui->CLiveParam->addItem("Port 2"); - VNAtrace = false; - break; } switch(t.liveParameter()) { @@ -93,6 +86,7 @@ TraceEditDialog::TraceEditDialog(Trace &t, QWidget *parent) : case Trace::LiveParameter::S22: ui->CLiveParam->setCurrentIndex(3); break; case Trace::LiveParameter::Port1: ui->CLiveParam->setCurrentIndex(0); break; case Trace::LiveParameter::Port2: ui->CLiveParam->setCurrentIndex(1); break; + default: break; } connect(ui->GSource, qOverload(&QButtonGroup::buttonClicked), updateFileStatus); diff --git a/Software/PC_Application/Traces/tracemarker.cpp b/Software/PC_Application/Traces/tracemarker.cpp index 1453807..12e807b 100644 --- a/Software/PC_Application/Traces/tracemarker.cpp +++ b/Software/PC_Application/Traces/tracemarker.cpp @@ -396,6 +396,7 @@ std::set TraceMarker::getSupportedTypes() supported.insert(Type::TOI); supported.insert(Type::PhaseNoise); break; + default: break; } } } diff --git a/Software/PC_Application/Traces/tracemodel.cpp b/Software/PC_Application/Traces/tracemodel.cpp index aa231ab..97ecfd4 100644 --- a/Software/PC_Application/Traces/tracemodel.cpp +++ b/Software/PC_Application/Traces/tracemodel.cpp @@ -22,7 +22,11 @@ void TraceModel::addTrace(Trace *t) { beginInsertRows(QModelIndex(), traces.size(), traces.size()); connect(t, &Trace::nameChanged, [=]() { - emit traceNameChanged(t); + emit traceNameChanged(t); + emit dataChanged(createIndex(0, 0), createIndex(traces.size() - 1, ColIndexLast - 1)); + }); + connect(t, &Trace::pauseChanged, [=](){ + emit dataChanged(createIndex(0, 0), createIndex(traces.size() - 1, ColIndexLast - 1)); }); traces.push_back(t); endInsertRows(); diff --git a/Software/PC_Application/Traces/tracewidget.cpp b/Software/PC_Application/Traces/tracewidget.cpp index c065c82..3cd251b 100644 --- a/Software/PC_Application/Traces/tracewidget.cpp +++ b/Software/PC_Application/Traces/tracewidget.cpp @@ -185,4 +185,104 @@ void TraceWidget::SetupSCPI() ret.chop(1); return ret; })); + add(new SCPICommand("AT", nullptr, [=](QStringList params) -> QString { + auto t = findTrace(params); + if(!t) { + return "ERROR"; + } + double x; + if(!SCPI::paramToDouble(params, 1, x)) { + return "ERROR"; + } else { + auto d = t->interpolatedSample(x); + if(std::isnan(d.x)) { + return "NaN,NaN"; + } else { + return QString::number(d.y.real())+","+QString::number(d.y.imag()); + } + } + })); + add(new SCPICommand("NEW", [=](QStringList params) -> QString { + if(params.size() != 1) { + return "ERROR"; + } + createCount++; + auto t = new Trace(params[0], Qt::darkYellow, defaultParameter()); + t->setColor(QColor::fromHsl((createCount * 50) % 360, 250, 128)); + model.addTrace(t); + return ""; + }, nullptr)); + add(new SCPICommand("RENAME", [=](QStringList params) -> QString { + auto t = findTrace(params); + if(!t) { + return "ERROR"; + } + if(params.size() != 2) { + return "ERROR"; + } + t->setName(params[1]); + return ""; + }, nullptr)); + add(new SCPICommand("PAUSE", [=](QStringList params) -> QString { + auto t = findTrace(params); + if(!t) { + return "ERROR"; + } + t->pause(); + return ""; + }, nullptr)); + add(new SCPICommand("RESUME", [=](QStringList params) -> QString { + auto t = findTrace(params); + if(!t) { + return "ERROR"; + } + t->resume(); + return ""; + }, nullptr)); + add(new SCPICommand("PAUSED", nullptr, [=](QStringList params) -> QString { + auto t = findTrace(params); + if(!t) { + return "ERROR"; + } + return t->isPaused() ? "TRUE" : "FALSE"; + })); + add(new SCPICommand("PARAMeter", [=](QStringList params) -> QString { + auto t = findTrace(params); + if(!t || params.size() < 2) { + return "ERROR"; + } + auto newparam = Trace::ParameterFromString(params[1]); + if((Trace::isVNAParameter(t->liveParameter()) && Trace::isVNAParameter(newparam)) + || (Trace::isVNAParameter(t->liveParameter()) && Trace::isVNAParameter(newparam))) { + t->fromLivedata(t->liveType(), newparam); + return ""; + } else { + return "ERROR"; + } + }, [=](QStringList params) -> QString { + auto t = findTrace(params); + if(!t) { + return "ERROR"; + } + return Trace::ParameterToString(t->liveParameter()); + })); + add(new SCPICommand("TYPE", [=](QStringList params) -> QString { + auto t = findTrace(params); + if(!t || params.size() < 2) { + return "ERROR"; + } + auto newtype = Trace::TypeFromString(params[1]); + if(newtype != Trace::LivedataType::Invalid) { + t->fromLivedata(newtype, t->liveParameter()); + return ""; + } else { + return "ERROR"; + } + }, [=](QStringList params) -> QString { + auto t = findTrace(params); + if(!t) { + return "ERROR"; + } + return Trace::TypeToString(t->liveType()); + })); } diff --git a/Software/PC_Application/VNA/vna.cpp b/Software/PC_Application/VNA/vna.cpp index 2badd02..e1a9341 100644 --- a/Software/PC_Application/VNA/vna.cpp +++ b/Software/PC_Application/VNA/vna.cpp @@ -883,21 +883,9 @@ void VNA::SetupSCPI() { auto scpi_freq = new SCPINode("FREQuency"); SCPINode::add(scpi_freq); - auto toULong = [](QStringList params) { - bool ok; - if(params.size() != 1) { - return std::numeric_limits::max(); - } - auto newval = params[0].toULong(&ok); - if(!ok) { - return std::numeric_limits::max(); - } else { - return newval; - } - }; scpi_freq->add(new SCPICommand("SPAN", [=](QStringList params) -> QString { - auto newval = toULong(params); - if(newval == std::numeric_limits::max()) { + unsigned long newval; + if(!SCPI::paramToULong(params, 0, newval)) { return "ERROR"; } else { SetSpan(newval); @@ -907,8 +895,8 @@ void VNA::SetupSCPI() return QString::number(settings.f_stop - settings.f_start); })); scpi_freq->add(new SCPICommand("START", [=](QStringList params) -> QString { - auto newval = toULong(params); - if(newval == std::numeric_limits::max()) { + unsigned long newval; + if(!SCPI::paramToULong(params, 0, newval)) { return "ERROR"; } else { SetStartFreq(newval); @@ -918,8 +906,8 @@ void VNA::SetupSCPI() return QString::number(settings.f_start); })); scpi_freq->add(new SCPICommand("CENTer", [=](QStringList params) -> QString { - auto newval = toULong(params); - if(newval == std::numeric_limits::max()) { + unsigned long newval; + if(!SCPI::paramToULong(params, 0, newval)) { return "ERROR"; } else { SetCenterFreq(newval); @@ -929,8 +917,8 @@ void VNA::SetupSCPI() return QString::number((settings.f_start + settings.f_stop)/2); })); scpi_freq->add(new SCPICommand("STOP", [=](QStringList params) -> QString { - auto newval = toULong(params); - if(newval == std::numeric_limits::max()) { + unsigned long newval; + if(!SCPI::paramToULong(params, 0, newval)) { return "ERROR"; } else { SetStopFreq(newval); @@ -947,8 +935,8 @@ void VNA::SetupSCPI() auto scpi_acq = new SCPINode("ACQuisition"); SCPINode::add(scpi_acq); scpi_acq->add(new SCPICommand("IFBW", [=](QStringList params) -> QString { - auto newval = toULong(params); - if(newval == std::numeric_limits::max()) { + unsigned long newval; + if(!SCPI::paramToULong(params, 0, newval)) { return "ERROR"; } else { SetIFBandwidth(newval); @@ -958,8 +946,8 @@ void VNA::SetupSCPI() return QString::number(settings.if_bandwidth); })); scpi_acq->add(new SCPICommand("POINTS", [=](QStringList params) -> QString { - auto newval = toULong(params); - if(newval == std::numeric_limits::max()) { + unsigned long newval; + if(!SCPI::paramToULong(params, 0, newval)) { return "ERROR"; } else { SetPoints(newval); @@ -969,8 +957,8 @@ void VNA::SetupSCPI() return QString::number(settings.points); })); scpi_acq->add(new SCPICommand("AVG", [=](QStringList params) -> QString { - auto newval = toULong(params); - if(newval == std::numeric_limits::max()) { + unsigned long newval; + if(!SCPI::paramToULong(params, 0, newval)) { return "ERROR"; } else { SetAveraging(newval); @@ -982,12 +970,8 @@ void VNA::SetupSCPI() auto scpi_stim = new SCPINode("STIMulus"); SCPINode::add(scpi_stim); scpi_stim->add(new SCPICommand("LVL", [=](QStringList params) -> QString { - bool ok; - if(params.size() != 1) { - return "ERROR"; - } - auto newval = params[0].toDouble(&ok); - if(!ok) { + double newval; + if(!SCPI::paramToDouble(params, 0, newval)) { return "ERROR"; } else { SetSourceLevel(newval); diff --git a/Software/PC_Application/scpi.cpp b/Software/PC_Application/scpi.cpp index 552de78..592097e 100644 --- a/Software/PC_Application/scpi.cpp +++ b/Software/PC_Application/scpi.cpp @@ -32,6 +32,36 @@ QString SCPI::alternateName(QString name) return name; } +bool SCPI::paramToDouble(QStringList params, int index, double &dest) +{ + if(index >= params.size()) { + return false; + } + bool okay; + dest = params[index].toDouble(&okay); + return okay; +} + +bool SCPI::paramToULong(QStringList params, int index, unsigned long &dest) +{ + if(index >= params.size()) { + return false; + } + bool okay; + dest = params[index].toULong(&okay); + return okay; +} + +bool SCPI::paramToLong(QStringList params, int index, long &dest) +{ + if(index >= params.size()) { + return false; + } + bool okay; + dest = params[index].toLong(&okay); + return okay; +} + void SCPI::input(QString line) { auto cmds = line.split(";"); diff --git a/Software/PC_Application/scpi.h b/Software/PC_Application/scpi.h index a20baa9..3017a1b 100644 --- a/Software/PC_Application/scpi.h +++ b/Software/PC_Application/scpi.h @@ -51,6 +51,10 @@ public: static bool match(QString s1, QString s2); static QString alternateName(QString name); + static bool paramToDouble(QStringList params, int index, double &dest); + static bool paramToULong(QStringList params, int index, unsigned long &dest); + static bool paramToLong(QStringList params, int index, long &dest); + public slots: void input(QString line); signals: