SCPI commands for modifying traces

This commit is contained in:
Jan Käberich 2021-04-13 21:33:51 +02:00
parent e66fc0131a
commit 438b62e06e
11 changed files with 303 additions and 106 deletions

View File

@ -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);

View File

@ -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<unsigned long>::max();
}
auto newval = params[0].toULong(&ok);
if(!ok) {
return std::numeric_limits<unsigned long>::max();
} else {
return newval;
}
};
scpi_freq->add(new SCPICommand("SPAN", [=](QStringList params) -> QString {
auto newval = toULong(params);
if(newval == std::numeric_limits<unsigned long>::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<unsigned long>::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<unsigned long>::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<unsigned long>::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<unsigned long>::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<unsigned long>::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);

View File

@ -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<Protocol::Datapoint> 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<MathInfo>::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;

View File

@ -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<Protocol::Datapoint> 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);

View File

@ -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<int>(&QButtonGroup::buttonClicked), updateFileStatus);

View File

@ -396,6 +396,7 @@ std::set<TraceMarker::Type> TraceMarker::getSupportedTypes()
supported.insert(Type::TOI);
supported.insert(Type::PhaseNoise);
break;
default: break;
}
}
}

View File

@ -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();

View File

@ -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());
}));
}

View File

@ -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<unsigned long>::max();
}
auto newval = params[0].toULong(&ok);
if(!ok) {
return std::numeric_limits<unsigned long>::max();
} else {
return newval;
}
};
scpi_freq->add(new SCPICommand("SPAN", [=](QStringList params) -> QString {
auto newval = toULong(params);
if(newval == std::numeric_limits<unsigned long>::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<unsigned long>::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<unsigned long>::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<unsigned long>::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<unsigned long>::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<unsigned long>::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<unsigned long>::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);

View File

@ -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(";");

View File

@ -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: