basic working wrapper

This commit is contained in:
Jan Käberich 2022-08-05 12:20:41 +02:00
parent a530cea085
commit 90ac9c57e1
25 changed files with 260 additions and 214 deletions

View File

@ -211,6 +211,7 @@ Device::Device(QString serial)
transmissionActive = false;
// got a new connection, request info
SendCommandWithoutPayload(Protocol::PacketType::RequestDeviceInfo);
SendCommandWithoutPayload(Protocol::PacketType::RequestDeviceStatus);
}
Device::~Device()

View File

@ -12,13 +12,13 @@
#include <QQueue>
#include <QTimer>
Q_DECLARE_METATYPE(Protocol::Datapoint);
Q_DECLARE_METATYPE(Protocol::ManualStatusV1);
Q_DECLARE_METATYPE(Protocol::SpectrumAnalyzerResult);
Q_DECLARE_METATYPE(Protocol::AmplitudeCorrectionPoint);
Q_DECLARE_METATYPE(Protocol::Datapoint)
Q_DECLARE_METATYPE(Protocol::ManualStatusV1)
Q_DECLARE_METATYPE(Protocol::SpectrumAnalyzerResult)
Q_DECLARE_METATYPE(Protocol::AmplitudeCorrectionPoint)
class USBInBuffer : public QObject {
Q_OBJECT;
Q_OBJECT
public:
USBInBuffer(libusb_device_handle *handle, unsigned char endpoint, int buffer_size);
~USBInBuffer();

View File

@ -108,6 +108,7 @@ static constexpr VirtualDevice::Info defaultInfo = {
.supportsVNAmode = true,
.supportsSAmode = true,
.supportsSGmode = true,
.supportsExtRef = true,
.Limits = {
.minFreq = 0,
.maxFreq = 6000000000,
@ -127,22 +128,24 @@ static const VirtualDevice::Status defaultStatus = {
.overload = false,
.unlocked = false,
.unlevel = false,
.extRef = false,
};
VirtualDevice::VirtualDevice(QString serial)
: QObject(),
info{}
info{},
status{}
{
isCompound = false;
zerospan = false;
auto dev = new Device(serial);
devices.push_back(dev);
if(!isCompoundDevice()) {
if(!isCompoundDevice()) {
// just acting as a wrapper for device, pass on signals
connect(dev, &Device::ConnectionLost, this, &VirtualDevice::ConnectionLost);
connect(dev, &Device::DeviceInfoUpdated, [&](){
auto i = dev->Info();
auto i = devices[0]->Info();
info.ProtocolVersion = i.ProtocolVersion;
info.FW_major = i.FW_major;
info.FW_minor = i.FW_minor;
@ -153,11 +156,12 @@ VirtualDevice::VirtualDevice(QString serial)
info.supportsVNAmode = true;
info.supportsSAmode = true;
info.supportsSGmode = true;
info.supportsExtRef = true;
info.Limits.minFreq = i.limits_minFreq;
info.Limits.maxFreq = i.limits_maxFreq;
info.Limits.maxFreqHarmonic = i.limits_maxFreqHarmonic;
info.Limits.minIFBW = i.limits_minIFBW;
info.Limits.maxIFBW = i.limits_minIFBW;
info.Limits.maxIFBW = i.limits_maxIFBW;
info.Limits.maxPoints = i.limits_maxPoints;
info.Limits.mindBm = (double) i.limits_cdbm_min / 100;
info.Limits.maxdBm = (double) i.limits_cdbm_max / 100;
@ -167,10 +171,11 @@ VirtualDevice::VirtualDevice(QString serial)
});
connect(dev, &Device::LogLineReceived, this, &VirtualDevice::LogLineReceived);
connect(dev, &Device::DeviceStatusUpdated, [&](){
status.statusString = dev->getLastDeviceInfoString();
status.overload = dev->StatusV1().ADC_overload;
status.unlevel = dev->StatusV1().unlevel;
status.unlocked = !dev->StatusV1().LO1_locked || !dev->StatusV1().source_locked;
status.statusString = devices[0]->getLastDeviceInfoString();
status.overload = devices[0]->StatusV1().ADC_overload;
status.unlevel = devices[0]->StatusV1().unlevel;
status.unlocked = !devices[0]->StatusV1().LO1_locked || !devices[0]->StatusV1().source_locked;
status.extRef = devices[0]->StatusV1().extRefInUse;
emit StatusUpdated(status);
});
connect(dev, &Device::NeedsFirmwareUpdate, this, &VirtualDevice::NeedsFirmwareUpdate);
@ -217,6 +222,13 @@ VirtualDevice::~VirtualDevice()
}
}
void VirtualDevice::RegisterTypes()
{
qRegisterMetaType<VirtualDevice::Status>("Status");
qRegisterMetaType<VirtualDevice::VNAMeasurement>("VNAMeasurement");
qRegisterMetaType<VirtualDevice::SAMeasurement>("SAMeasurement");
}
bool VirtualDevice::isCompoundDevice() const
{
return isCompound;
@ -267,8 +279,8 @@ const VirtualDevice::Status &VirtualDevice::getStatus(VirtualDevice *vdev)
QStringList VirtualDevice::availableVNAMeasurements()
{
QStringList ret;
for(int i=1;i<info.ports;i++) {
for(int j=1;j<info.ports;i++) {
for(int i=1;i<=info.ports;i++) {
for(int j=1;j<=info.ports;j++) {
ret.push_back("S"+QString::number(i)+QString::number(j));
}
}
@ -280,6 +292,9 @@ bool VirtualDevice::setVNA(const VirtualDevice::VNASettings &s, std::function<vo
if(!info.supportsVNAmode) {
return false;
}
if(s.excitedPorts.size() == 0) {
return setIdle(cb);
}
zerospan = (s.freqStart == s.freqStop) && (s.dBmStart == s.dBmStop);
auto pref = Preferences::getInstance();
if(!isCompoundDevice()) {
@ -293,7 +308,7 @@ bool VirtualDevice::setVNA(const VirtualDevice::VNASettings &s, std::function<vo
sd.excitePort1 = find(s.excitedPorts.begin(), s.excitedPorts.end(), 1) != s.excitedPorts.end() ? 1 : 0;
sd.excitePort2 = find(s.excitedPorts.begin(), s.excitedPorts.end(), 2) != s.excitedPorts.end() ? 1 : 0;
sd.suppressPeaks = pref.Acquisition.suppressPeaks ? 1 : 0;
sd.fixedPowerSetting = pref.Acquisition.adjustPowerLevel ? 0 : 1;
sd.fixedPowerSetting = pref.Acquisition.adjustPowerLevel || s.dBmStart != s.dBmStop ? 0 : 1;
sd.logSweep = s.logSweep ? 1 : 0;
return devices[0]->Configure(sd, [=](Device::TransmissionResult r){
if(cb) {
@ -303,7 +318,7 @@ bool VirtualDevice::setVNA(const VirtualDevice::VNASettings &s, std::function<vo
} else {
// TODO
return false;
}
}
}
QString VirtualDevice::serial()
@ -319,7 +334,7 @@ QString VirtualDevice::serial()
QStringList VirtualDevice::availableSAMeasurements()
{
QStringList ret;
for(int i=1;i<info.ports;i++) {
for(int i=1;i<=info.ports;i++) {
ret.push_back("PORT"+QString::number(i));
}
return ret;
@ -394,9 +409,10 @@ bool VirtualDevice::setSG(const SGSettings &s)
bool VirtualDevice::setIdle(std::function<void (bool)> cb)
{
auto success = true;
results.clear();
for(auto dev : devices) {
dev->SetIdle([&](Device::TransmissionResult r){
success &= dev->SetIdle([=](Device::TransmissionResult r){
if(cb) {
results[dev] = r;
if(results.size() == devices.size()) {
@ -413,6 +429,7 @@ bool VirtualDevice::setIdle(std::function<void (bool)> cb)
}
});
}
return success;
}
QStringList VirtualDevice::availableExtRefInSettings()
@ -451,6 +468,7 @@ bool VirtualDevice::setExtRef(QString option_in, QString option_out)
p.type = Protocol::PacketType::Reference;
switch(refIn) {
case Reference::TypeIn::Internal:
case Reference::TypeIn::None:
p.reference.UseExternalRef = 0;
p.reference.AutomaticSwitch = 0;
break;
@ -464,6 +482,7 @@ bool VirtualDevice::setExtRef(QString option_in, QString option_out)
break;
}
switch(refOut) {
case Reference::OutFreq::None:
case Reference::OutFreq::Off: p.reference.ExtRefOuputFreq = 0; break;
case Reference::OutFreq::MHZ10: p.reference.ExtRefOuputFreq = 10000000; break;
case Reference::OutFreq::MHZ100: p.reference.ExtRefOuputFreq = 100000000; break;

View File

@ -32,7 +32,7 @@ public:
struct {
double minFreq, maxFreq, maxFreqHarmonic;
double minIFBW, maxIFBW;
int maxPoints;
unsigned int maxPoints;
double mindBm;
double maxdBm;
double minRBW, maxRBW;
@ -45,8 +45,11 @@ public:
bool overload;
bool unlocked;
bool unlevel;
bool extRef;
};
static void RegisterTypes();
bool isCompoundDevice() const;
Device *getDevice();
std::vector<Device*> getDevices();
@ -66,7 +69,7 @@ public:
};
class VNAMeasurement {
public:
int pointNum;
unsigned int pointNum;
double Z0;
union {
struct {
@ -160,11 +163,11 @@ public:
static VirtualDevice* getConnected();
signals:
void VNAmeasurementReceived(const VNAMeasurement &m);
void SAmeasurementReceived(const SAMeasurement &m);
void VNAmeasurementReceived(VNAMeasurement m);
void SAmeasurementReceived(SAMeasurement m);
void ConnectionLost();
void InfoUpdated();
void StatusUpdated(const Status &status);
void StatusUpdated(Status status);
void LogLineReceived(QString line);
void NeedsFirmwareUpdate(int usedProtocol, int requiredProtocol);
private:
@ -178,4 +181,8 @@ private:
std::map<Device*, Device::TransmissionResult> results;
};
Q_DECLARE_METATYPE(VirtualDevice::Status)
Q_DECLARE_METATYPE(VirtualDevice::VNAMeasurement)
Q_DECLARE_METATYPE(VirtualDevice::SAMeasurement)
#endif // VIRTUALDEVICE_H

View File

@ -7,6 +7,7 @@
class Generator : public Mode
{
Q_OBJECT
public:
Generator(AppWindow *window, QString name = "Signal Generator");
void deactivate() override;

View File

@ -1,7 +1,7 @@
#ifndef SIGNALGENERATOR_H
#define SIGNALGENERATOR_H
#include "Device/virtualdevice.h".h"
#include "Device/virtualdevice.h"
#include "savable.h"
#include <QWidget>

View File

@ -14,7 +14,7 @@
#include "Tools/impedancematchdialog.h"
#include "Calibration/calibrationtracedialog.h"
#include "ui_main.h"
#include "Device/virtualdevice.h".h"
#include "Device/virtualdevice.h"
#include "preferences.h"
#include "Generator/signalgenwidget.h"
@ -438,7 +438,7 @@ void SpectrumAnalyzer::fromJSON(nlohmann::json j)
using namespace std;
void SpectrumAnalyzer::NewDatapoint(const VirtualDevice::SAMeasurement &m)
void SpectrumAnalyzer::NewDatapoint(VirtualDevice::SAMeasurement m)
{
if(isActive != true) {
return;
@ -511,7 +511,7 @@ void SpectrumAnalyzer::NewDatapoint(const VirtualDevice::SAMeasurement &m)
UpdateAverageCount();
markerModel->updateMarkers();
}
static unsigned int lastPoint = 0;
static int lastPoint = 0;
if(m_avg.pointNum > 0 && m_avg.pointNum != lastPoint + 1) {
qWarning() << "Got point" << m_avg.pointNum << "but last received point was" << lastPoint << "("<<(m_avg.pointNum-lastPoint-1)<<"missed points)";
}

View File

@ -39,7 +39,7 @@ private:
static VirtualDevice::SASettings::Detector DetectorFromString(QString s);
private slots:
void NewDatapoint(const VirtualDevice::SAMeasurement &m);
void NewDatapoint(VirtualDevice::SAMeasurement m);
// Sweep control
void SetStartFreq(double freq);
void SetStopFreq(double freq);

View File

@ -81,7 +81,7 @@ void Trace::addData(const Trace::Data& d, DataType domain, double reference_impe
}
if(index >= 0) {
// index position specified
if(data.size() <= index) {
if(data.size() <= (unsigned int) index) {
data.resize(index + 1);
}
data[index] = d;
@ -189,7 +189,6 @@ QString Trace::fillFromCSV(CSV &csv, unsigned int parameter)
int traceNum = -1;
unsigned int i=1;
QString lastTraceName = "";
bool hasImagValues;
std::map<YAxis::Type, int> columnMapping;
for(;i<csv.columns();i++) {
auto header = csv.getHeader(i);
@ -202,13 +201,13 @@ QString Trace::fillFromCSV(CSV &csv, unsigned int parameter)
auto yaxistype = header.right(header.size() - splitIndex - 1);
if(traceName != lastTraceName) {
traceNum++;
if(traceNum > parameter) {
if(traceNum > (int) parameter) {
// got all columns for the trace we are interested in
break;
}
lastTraceName = traceName;
}
if(traceNum == parameter) {
if(traceNum == (int) parameter) {
// this is the trace we are looking for, get axistype and add to mapping
// handle legacy column naming, translate to new naming
@ -221,7 +220,7 @@ QString Trace::fillFromCSV(CSV &csv, unsigned int parameter)
columnMapping[YAxis::TypeFromName(yaxistype)] = i;
}
}
if(traceNum < parameter) {
if(traceNum < (int) parameter) {
throw runtime_error("Not enough traces in CSV file");
}
if(columnMapping.size() == 0) {
@ -330,6 +329,7 @@ void Trace::removeMarker(Marker *m)
void Trace::markerVisibilityChanged(Marker *m)
{
Q_UNUSED(m);
// trigger replot by pretending that trace visibility also changed
emit visibilityChanged(this);
}
@ -711,6 +711,11 @@ nlohmann::json Trace::toJSON()
j["sources"] = jsources;
}
break;
case Source::Calibration:
// Skip for now, TODO?
break;
case Source::Last:
break;
}
j["velocityFactor"] = vFactor;
j["reflection"] = reflection;

View File

@ -31,6 +31,7 @@ TraceCSVExport::TraceCSVExport(TraceModel &traceModel, QWidget *parent) :
auto domain = t->outputType();
auto Xaxis = XAxis::Type::Last;
switch(domain) {
case Trace::DataType::Invalid:
case Trace::DataType::Frequency: Xaxis = XAxis::Type::Frequency; break;
case Trace::DataType::Power: Xaxis = XAxis::Type::Power; break;
case Trace::DataType::Time: Xaxis = XAxis::Type::Time; break;
@ -109,7 +110,7 @@ void TraceCSVExport::on_buttonBox_accepted()
std::vector<YAxis::Type> TraceCSVExport::getSelectedYAxisTypes()
{
std::vector<YAxis::Type> ret;
for(unsigned int i=0;i<ui->listColumns->count();i++) {
for(int i=0;i<ui->listColumns->count();i++) {
auto item = ui->listColumns->item(i);
if(item->checkState() == Qt::Checked) {
auto type = YAxis::TypeFromName(item->text());

View File

@ -107,7 +107,6 @@ TraceEditDialog::TraceEditDialog(Trace &t, QWidget *parent) :
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
} else {
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
auto touchstone = ui->touchstoneImport->getTouchstone();
}
if(!(ui->touchstoneImport->getFilename().endsWith(".csv"))) {
// switch to touchstone import dialog
@ -125,6 +124,7 @@ TraceEditDialog::TraceEditDialog(Trace &t, QWidget *parent) :
VNAtrace = Trace::isVNAParameter(t.liveParameter());
if(VirtualDevice::getConnected()) {
qDebug() << VirtualDevice::getConnected();
if(VNAtrace) {
ui->CLiveParam->addItems(VirtualDevice::getConnected()->availableVNAMeasurements());
} else {
@ -132,6 +132,9 @@ TraceEditDialog::TraceEditDialog(Trace &t, QWidget *parent) :
}
}
if(ui->CLiveParam->findText(t.liveParameter()) < 0) {
ui->CLiveParam->addItem(t.liveParameter());
}
ui->CLiveParam->setCurrentText(t.liveParameter());
connect(ui->touchstoneImport, &TouchstoneImport::statusChanged, updateTouchstoneFileStatus);

View File

@ -70,7 +70,7 @@ void TraceModel::togglePause(unsigned int index)
traces[index]->pause();
}
emit dataChanged(createIndex(index, ColIndexPlayPause), createIndex(index, ColIndexPlayPause));
emit requiredExcitation(PortExcitationRequired(1), PortExcitationRequired(2));
emit requiredExcitation();
}
}
@ -252,7 +252,7 @@ void TraceModel::addSAData(const VirtualDevice::SAMeasurement& d, const VirtualD
if (t->getSource() == Trace::Source::Live && !t->isPaused()) {
int index = -1;
Trace::Data td;
if(settings.f_start == settings.f_stop) {
if(settings.freqStart == settings.freqStop) {
// in zerospan mode, insert data by index
index = d.pointNum;
td.x = (double) d.us / 1000000.0;

View File

@ -59,7 +59,7 @@ signals:
void SpanChanged(double fmin, double fmax);
void traceAdded(Trace *t);
void traceRemoved(Trace *t);
void requiredExcitation(bool excitePort1, bool excitePort2);
void requiredExcitation();
void traceNameChanged(Trace *t);
public slots:

View File

@ -133,18 +133,12 @@ bool TraceWaterfall::configureForTrace(Trace *t)
xAxis.set(XAxis::Type::Frequency, false, true, 0, 1, 0.1);
yAxis.set(YAxis::Type::Magnitude, false, true, 0, 1, 1.0);
break;
// case Trace::DataType::Time:
// xAxis.set(XAxis::Type::Time, false, true, 0, 1, 0.1);
// yAxis.set(YAxis::Type::ImpulseMag, false, true, 0, 1, 1.0);
// break;
case Trace::DataType::Power:
xAxis.set(XAxis::Type::Power, false, true, 0, 1, 0.1);
yAxis.set(YAxis::Type::Magnitude, false, true, 0, 1, 1.0);
break;
// case Trace::DataType::TimeZeroSpan:
// xAxis.set(XAxis::Type::Power, false, true, 0, 1, 0.1);
// yAxis.set(YAxis::Type::Magnitude, false, true, 0, 1, 1.0);
// break;
case Trace::DataType::Time:
case Trace::DataType::TimeZeroSpan:
case Trace::DataType::Invalid:
// unable to add
return false;

View File

@ -211,6 +211,7 @@ void TraceWidget::SetupSCPI()
auto d = t->sample(i);
int precision = 0;
switch(t->outputType()) {
case Trace::DataType::Invalid:
case Trace::DataType::Frequency: precision = 0; break;
case Trace::DataType::Time: precision = 12; break;
case Trace::DataType::Power: precision = 3; break;

View File

@ -72,16 +72,16 @@ VNA::VNA(AppWindow *window, QString name)
// Create default traces
auto tS11 = new Trace("S11", Qt::yellow);
tS11->fromLivedata(Trace::LivedataType::Overwrite, Trace::LiveParameter::S11);
tS11->fromLivedata(Trace::LivedataType::Overwrite, "S11");
traceModel.addTrace(tS11);
auto tS12 = new Trace("S12", Qt::blue);
tS12->fromLivedata(Trace::LivedataType::Overwrite, Trace::LiveParameter::S12);
tS12->fromLivedata(Trace::LivedataType::Overwrite, "S12");
traceModel.addTrace(tS12);
auto tS21 = new Trace("S21", Qt::green);
tS21->fromLivedata(Trace::LivedataType::Overwrite, Trace::LiveParameter::S21);
tS21->fromLivedata(Trace::LivedataType::Overwrite, "S21");
traceModel.addTrace(tS21);
auto tS22 = new Trace("S22", Qt::red);
tS22->fromLivedata(Trace::LivedataType::Overwrite, Trace::LiveParameter::S22);
tS22->fromLivedata(Trace::LivedataType::Overwrite, "S22");
traceModel.addTrace(tS22);
auto tracesmith1 = new TraceSmithChart(traceModel);
@ -675,7 +675,7 @@ void VNA::deactivate()
void VNA::initializeDevice()
{
defaultCalMenu->setEnabled(true);
connect(window->getDevice(), &Device::DatapointReceived, this, &VNA::NewDatapoint, Qt::UniqueConnection);
connect(window->getDevice(), &VirtualDevice::VNAmeasurementReceived, this, &VNA::NewDatapoint, Qt::UniqueConnection);
// Check if default calibration exists and attempt to load it
QSettings s;
auto key = "DefaultCalibration"+window->getDevice()->serial();
@ -799,7 +799,7 @@ void VNA::fromJSON(nlohmann::json j)
using namespace std;
void VNA::NewDatapoint(Protocol::Datapoint d)
void VNA::NewDatapoint(VirtualDevice::VNAMeasurement m)
{
if(isActive != true) {
// ignore
@ -814,54 +814,54 @@ void VNA::NewDatapoint(Protocol::Datapoint d)
if(singleSweep && average.getLevel() == averages) {
changingSettings = true;
// single sweep finished
window->getDevice()->SetIdle([=](Device::TransmissionResult){
window->getDevice()->setIdle([=](bool){
changingSettings = false;
});
}
auto m_avg = m;
bool needsSegmentUpdate = false;
if (settings.segments > 1) {
// using multiple segments, adjust pointNum
auto pointsPerSegment = ceil((double) settings.npoints / settings.segments);
if (d.pointNum == pointsPerSegment - 1) {
if (m_avg.pointNum == pointsPerSegment - 1) {
needsSegmentUpdate = true;
}
d.pointNum += pointsPerSegment * settings.activeSegment;
if(d.pointNum == settings.npoints - 1) {
m_avg.pointNum += pointsPerSegment * settings.activeSegment;
if(m_avg.pointNum == settings.npoints - 1) {
needsSegmentUpdate = true;
}
}
if(d.pointNum >= settings.npoints) {
qWarning() << "Ignoring point with too large point number (" << d.pointNum << ")";
if(m_avg.pointNum >= settings.npoints) {
qWarning() << "Ignoring point with too large point number (" << m.pointNum << ")";
return;
}
auto vd = VNAData(d);
vd = average.process(vd);
m_avg = average.process(m_avg);
if(calMeasuring) {
if(average.currentSweep() == averages) {
// this is the last averaging sweep, use values for calibration
if(!calWaitFirst || vd.pointNum == 0) {
if(!calWaitFirst || m_avg.pointNum == 0) {
calWaitFirst = false;
cal.addMeasurements(calMeasurements, vd);
if(vd.pointNum == settings.npoints - 1) {
cal.addMeasurements(calMeasurements, m_avg);
if(m_avg.pointNum == settings.npoints - 1) {
calMeasuring = false;
emit CalibrationMeasurementsComplete(calMeasurements);
}
}
}
int percentage = (((average.currentSweep() - 1) * 100) + (vd.pointNum + 1) * 100 / settings.npoints) / averages;
int percentage = (((average.currentSweep() - 1) * 100) + (m_avg.pointNum + 1) * 100 / settings.npoints) / averages;
calDialog.setValue(percentage);
}
if(calValid) {
cal.correctMeasurement(vd);
cal.correctMeasurement(m_avg);
}
if(deembedding_active) {
deembedding.Deembed(vd);
deembedding.Deembed(m_avg);
}
TraceMath::DataType type;
@ -869,11 +869,11 @@ void VNA::NewDatapoint(Protocol::Datapoint d)
type = TraceMath::DataType::TimeZeroSpan;
// keep track of first point time
if(vd.pointNum == 0) {
settings.firstPointTime = vd.time;
vd.time = 0;
if(m_avg.pointNum == 0) {
settings.firstPointTime = m_avg.us;
m_avg.us = 0;
} else {
vd.time -= settings.firstPointTime;
m_avg.us -= settings.firstPointTime;
}
} else {
switch(settings.sweepType) {
@ -887,17 +887,17 @@ void VNA::NewDatapoint(Protocol::Datapoint d)
}
}
traceModel.addVNAData(vd, type);
traceModel.addVNAData(m_avg, type);
emit dataChanged();
if(vd.pointNum == settings.npoints - 1) {
if(m_avg.pointNum == settings.npoints - 1) {
UpdateAverageCount();
markerModel->updateMarkers();
}
static unsigned int lastPoint = 0;
if(vd.pointNum > 0 && vd.pointNum != lastPoint + 1) {
qWarning() << "Got point" << vd.pointNum << "but last received point was" << lastPoint << "("<<(vd.pointNum-lastPoint-1)<<"missed points)";
if(m_avg.pointNum > 0 && m_avg.pointNum != lastPoint + 1) {
qWarning() << "Got point" << m_avg.pointNum << "but last received point was" << lastPoint << "("<<(m_avg.pointNum-lastPoint-1)<<"missed points)";
}
lastPoint = vd.pointNum;
lastPoint = m_avg.pointNum;
if (needsSegmentUpdate) {
changingSettings = true;
@ -915,24 +915,26 @@ void VNA::UpdateAverageCount()
lAverages->setText(QString::number(average.getLevel()) + "/");
}
void VNA::SettingsChanged(bool resetTraces, std::function<void (Device::TransmissionResult)> cb)
void VNA::SettingsChanged(bool resetTraces, std::function<void (bool)> cb)
{
if (resetTraces) {
settings.activeSegment = 0;
}
changingSettings = true;
// assemble VNA protocol settings
Protocol::SweepSettings s = {};
s.suppressPeaks = Preferences::getInstance().Acquisition.suppressPeaks ? 1 : 0;
VirtualDevice::VNASettings s = {};
s.IFBW = settings.bandwidth;
if(Preferences::getInstance().Acquisition.alwaysExciteBothPorts) {
s.excitePort1 = 1;
s.excitePort2 = 1;
for(int i=1;i<=VirtualDevice::getInfo(window->getDevice()).ports;i++) {
s.excitedPorts.push_back(i);
}
} else {
s.excitePort1 = traceModel.PortExcitationRequired(1);
s.excitePort2 = traceModel.PortExcitationRequired(2);
for(int i=1;i<=VirtualDevice::getInfo(window->getDevice()).ports;i++) {
if(traceModel.PortExcitationRequired(i))
s.excitedPorts.push_back(i);
}
}
settings.excitingPort1 = s.excitePort1;
settings.excitingPort2 = s.excitePort2;
settings.excitedPorts = s.excitedPorts;
double start = settings.sweepType == SweepType::Frequency ? settings.Freq.start : settings.Power.start;
double stop = settings.sweepType == SweepType::Frequency ? settings.Freq.stop : settings.Power.stop;
@ -941,8 +943,8 @@ void VNA::SettingsChanged(bool resetTraces, std::function<void (Device::Transmis
if (settings.segments > 1) {
// more than one segment, adjust start/stop
npoints = ceil((double) settings.npoints / settings.segments);
int segmentStartPoint = npoints * settings.activeSegment;
int segmentStopPoint = segmentStartPoint + npoints - 1;
unsigned int segmentStartPoint = npoints * settings.activeSegment;
unsigned int segmentStopPoint = segmentStartPoint + npoints - 1;
if(segmentStopPoint >= settings.npoints) {
segmentStopPoint = settings.npoints - 1;
npoints = settings.npoints - segmentStartPoint;
@ -954,44 +956,34 @@ void VNA::SettingsChanged(bool resetTraces, std::function<void (Device::Transmis
}
if(settings.sweepType == SweepType::Frequency) {
s.fixedPowerSetting = Preferences::getInstance().Acquisition.adjustPowerLevel ? 0 : 1;
s.f_start = start;
s.f_stop = stop;
s.freqStart = start;
s.freqStop = stop;
s.points = npoints;
s.if_bandwidth = settings.bandwidth;
s.cdbm_excitation_start = settings.Freq.excitation_power * 100;
s.cdbm_excitation_stop = settings.Freq.excitation_power * 100;
s.dBmStart = settings.Freq.excitation_power;
s.dBmStop = settings.Freq.excitation_power;
s.logSweep = settings.Freq.logSweep;
} else if(settings.sweepType == SweepType::Power) {
s.fixedPowerSetting = 0;
s.f_start = settings.Power.frequency;
s.f_stop = settings.Power.frequency;
s.freqStart = settings.Power.frequency;
s.freqStop = settings.Power.frequency;
s.points = npoints;
s.if_bandwidth = settings.bandwidth;
s.cdbm_excitation_start = start * 100;
s.cdbm_excitation_stop = stop * 100;
s.dBmStart = start;
s.dBmStop = stop;
s.logSweep = false;
}
if(window->getDevice() && isActive) {
if(s.excitePort1 == 0 && s.excitePort2 == 0) {
// no signal at either port, just set the device to idle
window->getDevice()->SetIdle();
window->getDevice()->setVNA(s, [=](bool res){
// device received command, reset traces now
if (resetTraces) {
average.reset(settings.npoints);
traceModel.clearLiveData();
UpdateAverageCount();
UpdateCalWidget();
}
if(cb) {
cb(res);
}
changingSettings = false;
} else {
window->getDevice()->Configure(s, [=](Device::TransmissionResult res){
// device received command, reset traces now
if (resetTraces) {
average.reset(settings.npoints);
traceModel.clearLiveData();
UpdateAverageCount();
UpdateCalWidget();
}
if(cb) {
cb(res);
}
changingSettings = false;
});
}
});
}
}
@ -1034,14 +1026,14 @@ void VNA::SetStopFreq(double freq)
void VNA::SetCenterFreq(double freq)
{
auto old_span = settings.Freq.stop - settings.Freq.start;
if (freq - old_span / 2 <= Device::Info(window->getDevice()).limits_minFreq) {
if (freq - old_span / 2 <= VirtualDevice::getInfo(window->getDevice()).Limits.minFreq) {
// would shift start frequency below minimum
settings.Freq.start = 0;
settings.Freq.stop = 2 * freq;
} else if(freq + old_span / 2 >= Device::Info(window->getDevice()).limits_maxFreq) {
} else if(freq + old_span / 2 >= VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq) {
// would shift stop frequency above maximum
settings.Freq.start = 2 * freq - Device::Info(window->getDevice()).limits_maxFreq;
settings.Freq.stop = Device::Info(window->getDevice()).limits_maxFreq;
settings.Freq.start = 2 * freq - VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
settings.Freq.stop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
} else {
settings.Freq.start = freq - old_span / 2;
settings.Freq.stop = freq + old_span / 2;
@ -1051,12 +1043,12 @@ void VNA::SetCenterFreq(double freq)
void VNA::SetSpan(double span)
{
auto maxFreq = Preferences::getInstance().Acquisition.harmonicMixing ? Device::Info(window->getDevice()).limits_maxFreqHarmonic : Device::Info(window->getDevice()).limits_maxFreq;
auto maxFreq = Preferences::getInstance().Acquisition.harmonicMixing ? VirtualDevice::getInfo(window->getDevice()).Limits.maxFreqHarmonic : VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
auto old_center = (settings.Freq.start + settings.Freq.stop) / 2;
if(old_center < Device::Info(window->getDevice()).limits_minFreq + span / 2) {
if(old_center < VirtualDevice::getInfo(window->getDevice()).Limits.minFreq + span / 2) {
// would shift start frequency below minimum
settings.Freq.start = Device::Info(window->getDevice()).limits_minFreq;
settings.Freq.stop = Device::Info(window->getDevice()).limits_minFreq + span;
settings.Freq.start = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
settings.Freq.stop = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq + span;
} else if(old_center > maxFreq - span / 2) {
// would shift stop frequency above maximum
settings.Freq.start = maxFreq - span;
@ -1070,8 +1062,8 @@ void VNA::SetSpan(double span)
void VNA::SetFullSpan()
{
settings.Freq.start = Device::Info(window->getDevice()).limits_minFreq;
settings.Freq.stop = Device::Info(window->getDevice()).limits_maxFreq;
settings.Freq.start = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
settings.Freq.stop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
ConstrainAndUpdateFrequencies();
}
@ -1116,10 +1108,10 @@ void VNA::SetLogSweep(bool log)
void VNA::SetSourceLevel(double level)
{
if(level > Device::Info(window->getDevice()).limits_cdbm_max / 100.0) {
level = Device::Info(window->getDevice()).limits_cdbm_max / 100.0;
} else if(level < Device::Info(window->getDevice()).limits_cdbm_min / 100.0) {
level = Device::Info(window->getDevice()).limits_cdbm_min / 100.0;
if(level > VirtualDevice::getInfo(window->getDevice()).Limits.maxdBm) {
level = VirtualDevice::getInfo(window->getDevice()).Limits.maxdBm;
} else if(level < VirtualDevice::getInfo(window->getDevice()).Limits.mindBm) {
level = VirtualDevice::getInfo(window->getDevice()).Limits.mindBm;
}
emit sourceLevelChanged(level);
settings.Freq.excitation_power = level;
@ -1149,15 +1141,15 @@ void VNA::SetPowerSweepFrequency(double freq)
void VNA::SetPoints(unsigned int points)
{
unsigned int maxPoints = Preferences::getInstance().Acquisition.allowSegmentedSweep ? UINT16_MAX : Device::Info(window->getDevice()).limits_maxPoints;
unsigned int maxPoints = Preferences::getInstance().Acquisition.allowSegmentedSweep ? UINT16_MAX : VirtualDevice::getInfo(window->getDevice()).Limits.maxPoints;
if(points > maxPoints) {
points = maxPoints;
} else if (points < 2) {
points = 2;
}
if (points > Device::Info(window->getDevice()).limits_maxPoints) {
if (points > VirtualDevice::getInfo(window->getDevice()).Limits.maxPoints) {
// needs segmented sweep
settings.segments = ceil((double) points / Device::Info(window->getDevice()).limits_maxPoints);
settings.segments = ceil((double) points / VirtualDevice::getInfo(window->getDevice()).Limits.maxPoints);
settings.activeSegment = 0;
} else {
// can fit all points into one segment
@ -1171,10 +1163,10 @@ void VNA::SetPoints(unsigned int points)
void VNA::SetIFBandwidth(double bandwidth)
{
if(bandwidth > Device::Info(window->getDevice()).limits_maxIFBW) {
bandwidth = Device::Info(window->getDevice()).limits_maxIFBW;
} else if(bandwidth < Device::Info(window->getDevice()).limits_minIFBW) {
bandwidth = Device::Info(window->getDevice()).limits_minIFBW;
if(bandwidth > VirtualDevice::getInfo(window->getDevice()).Limits.maxIFBW) {
bandwidth = VirtualDevice::getInfo(window->getDevice()).Limits.maxIFBW;
} else if(bandwidth < VirtualDevice::getInfo(window->getDevice()).Limits.minIFBW) {
bandwidth = VirtualDevice::getInfo(window->getDevice()).Limits.minIFBW;
}
settings.bandwidth = bandwidth;
emit IFBandwidthChanged(settings.bandwidth);
@ -1189,18 +1181,18 @@ void VNA::SetAveraging(unsigned int averages)
SettingsChanged();
}
void VNA::ExcitationRequired(bool port1, bool port2)
void VNA::ExcitationRequired()
{
if(Preferences::getInstance().Acquisition.alwaysExciteBothPorts) {
port1 = true;
port2 = true;
}
// check if settings actually changed
if(settings.excitingPort1 != port1
|| settings.excitingPort2 != port2) {
settings.excitingPort1 = port1;
settings.excitingPort2 = port2;
SettingsChanged();
if(!Preferences::getInstance().Acquisition.alwaysExciteBothPorts) {
for(int i=1;i<VirtualDevice::getInfo(window->getDevice()).ports;i++) {
auto required = traceModel.PortExcitationRequired(i);
auto set = find(settings.excitedPorts.begin(), settings.excitedPorts.end(), i) != settings.excitedPorts.end();
if(required != set) {
// Required port excitation changed
SettingsChanged();
break;
}
}
}
}
@ -1274,7 +1266,7 @@ void VNA::StartCalibrationMeasurements(std::set<Calibration::Measurement> m)
cal.clearMeasurements(calMeasurements);
});
// Trigger sweep to start from beginning
SettingsChanged(true, [=](Device::TransmissionResult){
SettingsChanged(true, [=](bool){
// enable calibration measurement only in transmission callback (prevents accidental sampling of data which was still being processed)
calMeasuring = true;
});
@ -1541,9 +1533,9 @@ void VNA::ConstrainAndUpdateFrequencies()
auto pref = Preferences::getInstance();
double maxFreq;
if(pref.Acquisition.harmonicMixing) {
maxFreq = Device::Info(window->getDevice()).limits_maxFreqHarmonic;
maxFreq = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreqHarmonic;
} else {
maxFreq = Device::Info(window->getDevice()).limits_maxFreq;
maxFreq = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
}
if(settings.Freq.stop > maxFreq) {
settings.Freq.stop = maxFreq;
@ -1551,8 +1543,8 @@ void VNA::ConstrainAndUpdateFrequencies()
if(settings.Freq.start > settings.Freq.stop) {
settings.Freq.start = settings.Freq.stop;
}
if(settings.Freq.start < Device::Info(window->getDevice()).limits_minFreq) {
settings.Freq.start = Device::Info(window->getDevice()).limits_minFreq;
if(settings.Freq.start < VirtualDevice::getInfo(window->getDevice()).Limits.minFreq) {
settings.Freq.start = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
}
settings.zerospan = (settings.sweepType == SweepType::Frequency && settings.Freq.start == settings.Freq.stop)
|| (settings.sweepType == SweepType::Power && settings.Power.start == settings.Power.stop);
@ -1607,7 +1599,7 @@ void VNA::StoreSweepSettings()
void VNA::StopSweep()
{
if(window->getDevice()) {
window->getDevice()->SetIdle();
window->getDevice()->setIdle();
}
}

View File

@ -48,7 +48,7 @@ public:
: sweepType(SweepType::Frequency)
, Freq({.start=1000000, .stop=6000000000, .excitation_power=-10, .logSweep=false})
, Power({.start=-40, .stop=-10, .frequency=1000000000})
, npoints(501), bandwidth(1000), excitingPort1(true), excitingPort2(true)
, npoints(501), bandwidth(1000)
, segments(1), activeSegment(0){}
SweepType sweepType;
struct {
@ -62,10 +62,9 @@ public:
double stop;
double frequency;
} Power;
int npoints;
unsigned int npoints;
double bandwidth;
bool excitingPort1;
bool excitingPort2;
std::vector<int> excitedPorts;
// if the number of points is higher than supported by the hardware, the sweep has to be segmented into multiple parts
int segments;
int activeSegment;
@ -77,7 +76,7 @@ public slots:
bool LoadCalibration(QString filename);
private slots:
void NewDatapoint(Protocol::Datapoint d);
void NewDatapoint(VirtualDevice::VNAMeasurement m);
void StartImpedanceMatching();
// Sweep control
void SetSweepType(SweepType sw);
@ -101,7 +100,7 @@ private slots:
void SetPoints(unsigned int points);
void SetIFBandwidth(double bandwidth);
void SetAveraging(unsigned int averages);
void ExcitationRequired(bool port1, bool port2);
void ExcitationRequired();
// Calibration
void DisableCalibration(bool force = false);
void ApplyCalibration(Calibration::Type type);
@ -115,7 +114,7 @@ private:
bool CalibrationMeasurementActive() { return calWaitFirst || calMeasuring; }
void SetupSCPI();
void UpdateAverageCount();
void SettingsChanged(bool resetTraces = true, std::function<void (Device::TransmissionResult)> cb = nullptr);
void SettingsChanged(bool resetTraces = true, std::function<void(bool)> cb = nullptr);
void ConstrainAndUpdateFrequencies();
void LoadSweepSettings();
void StoreSweepSettings();

View File

@ -325,6 +325,7 @@ bool AppWindow::ConnectToDevice(QString serial)
qDebug() << "Attempting to connect to device...";
vdevice = new VirtualDevice(serial);
UpdateStatusBar(AppWindow::DeviceStatusBar::Connected);
connect(vdevice, &VirtualDevice::InfoUpdated, this, &AppWindow::DeviceInfoUpdated);
connect(vdevice, &VirtualDevice::LogLineReceived, &deviceLog, &DeviceLog::addLine);
connect(vdevice, &VirtualDevice::ConnectionLost, this, &AppWindow::DeviceConnectionLost);
connect(vdevice, &VirtualDevice::StatusUpdated, this, &AppWindow::DeviceStatusUpdated);
@ -339,11 +340,6 @@ bool AppWindow::ConnectToDevice(QString serial)
}
UpdateAcquisitionFrequencies();
if (modeHandler->getActiveMode()) {
modeHandler->getActiveMode()->initializeDevice();
}
UpdateReferenceToolbar();
UpdateReference();
for(auto d : deviceActionGroup->actions()) {
if(d->text() == vdevice->serial()) {
@ -453,49 +449,59 @@ void AppWindow::SetupSCPI()
if(params.size() != 1) {
return SCPI::getResultName(SCPI::Result::Error);
} else if(params[0] == "0" || params[0] == "OFF") {
int index = toolbars.reference.outFreq->findData((int)Reference::OutFreq::Off);
toolbars.reference.outFreq->setCurrentIndex(index);
} else if(params[0] == "10") {
int index = toolbars.reference.outFreq->findData((int)Reference::OutFreq::MHZ10);
toolbars.reference.outFreq->setCurrentIndex(index);
} else if(params[0] == "100") {
int index = toolbars.reference.outFreq->findData((int)Reference::OutFreq::MHZ100);
toolbars.reference.outFreq->setCurrentIndex(index);
int index = toolbars.reference.outFreq->findText("Off");
if(index >= 0) {
toolbars.reference.outFreq->setCurrentIndex(index);
} else {
return SCPI::getResultName(SCPI::Result::Error);
}
} else {
return SCPI::getResultName(SCPI::Result::Error);
bool isInt;
params[0].toInt(&isInt);
if(isInt) {
params[0].append(" MHz");
int index = toolbars.reference.outFreq->findText(params[0]);
if(index >= 0) {
toolbars.reference.outFreq->setCurrentIndex(index);
} else {
return SCPI::getResultName(SCPI::Result::Error);
}
} else {
return SCPI::getResultName(SCPI::Result::Error);
}
}
return SCPI::getResultName(SCPI::Result::Empty);
}, [=](QStringList) -> QString {
Reference::OutFreq f = static_cast<Reference::OutFreq>(toolbars.reference.outFreq->currentData().toInt());
switch(f) {
case Reference::OutFreq::Off: return "OFF";
case Reference::OutFreq::MHZ10: return "10";
case Reference::OutFreq::MHZ100: return "100";
default: return SCPI::getResultName(SCPI::Result::Error);
auto fOutString = toolbars.reference.outFreq->currentText().toUpper();
if(fOutString.endsWith(" MHZ")) {
fOutString.chop(4);
}
if(fOutString.isEmpty()) {
return SCPI::getResultName(SCPI::Result::Error);
} else {
return fOutString;
}
}));
scpi_ref->add(new SCPICommand("IN", [=](QStringList params) -> QString {
if(params.size() != 1) {
// reference settings translation
map<QString, QString> translation {
make_pair("INT", "Internal"),
make_pair("EXT", "External"),
make_pair("AUTO", "Auto"),
};
if(params.size() != 1 || translation.count(params[0]) == 0) {
return SCPI::getResultName(SCPI::Result::Error);
} else if(params[0] == "INT") {
int index = toolbars.reference.type->findData((int)Reference::TypeIn::Internal);
toolbars.reference.type->setCurrentIndex(index);
} else if(params[0] == "EXT") {
int index = toolbars.reference.type->findData((int)Reference::TypeIn::External);
toolbars.reference.type->setCurrentIndex(index);
} else if(params[0] == "AUTO") {
int index = toolbars.reference.type->findData((int)Reference::TypeIn::Auto);
toolbars.reference.type->setCurrentIndex(index);
} else {
return SCPI::getResultName(SCPI::Result::Error);
int index = toolbars.reference.type->findText(translation[params[0]]);
if(index >= 0) {
toolbars.reference.type->setCurrentIndex(index);
} else {
return SCPI::getResultName(SCPI::Result::Error);
}
}
return SCPI::getResultName(SCPI::Result::Empty);
}, [=](QStringList) -> QString {
switch(Device::StatusV1(getDevice()).extRefInUse) {
case 0: return "INT";
case 1: return "EXT";
default: return SCPI::getResultName(SCPI::Result::Error);
}
return VirtualDevice::getStatus(getDevice()).extRef ? "EXT" : "INT";
}));
scpi_dev->add(new SCPICommand("MODE", [=](QStringList params) -> QString {
if (params.size() != 1) {
@ -525,6 +531,7 @@ void AppWindow::SetupSCPI()
case Mode::Type::VNA: return "VNA";
case Mode::Type::SG: return "SG";
case Mode::Type::SA: return "SA";
case Mode::Type::Last: return SCPI::getResultName(SCPI::Result::Error);
}
}
return SCPI::getResultName(SCPI::Result::Error);
@ -903,6 +910,9 @@ void AppWindow::UpdateReferenceToolbar()
if(!vdevice || !vdevice->getInfo().supportsExtRef) {
toolbars.reference.type->setEnabled(false);
toolbars.reference.outFreq->setEnabled(false);
} else {
toolbars.reference.type->setEnabled(true);
toolbars.reference.outFreq->setEnabled(true);
}
// save current setting
auto refInBuf = toolbars.reference.type->currentText();
@ -913,7 +923,7 @@ void AppWindow::UpdateReferenceToolbar()
}
toolbars.reference.outFreq->clear();
for(auto out : vdevice->availableExtRefOutSettings()) {
toolbars.reference.outFreq->addItem(in);
toolbars.reference.outFreq->addItem(out);
}
// restore previous setting if still available
if(toolbars.reference.type->findText(refInBuf) >= 0) {
@ -982,7 +992,7 @@ void AppWindow::DeviceNeedsUpdate(int reported, int expected)
}
}
void AppWindow::DeviceStatusUpdated(VirtualDevice::Status &status)
void AppWindow::DeviceStatusUpdated(VirtualDevice::Status status)
{
lDeviceInfo.setText(status.statusString);
lADCOverload.setVisible(status.overload);
@ -990,6 +1000,15 @@ void AppWindow::DeviceStatusUpdated(VirtualDevice::Status &status)
lUnlock.setVisible(status.unlocked);
}
void AppWindow::DeviceInfoUpdated()
{
if (modeHandler->getActiveMode()) {
modeHandler->getActiveMode()->initializeDevice();
}
UpdateReferenceToolbar();
UpdateReference();
}
void AppWindow::SourceCalibrationDialog()
{
if(!vdevice || vdevice->isCompoundDevice()) {

View File

@ -1,7 +1,7 @@
#ifndef APPWINDOW_H
#define APPWINDOW_H
#include "Device/virtualdevice.h".h"
#include "Device/virtualdevice.h"
#include "Traces/traceplot.h"
#include "Calibration/calibration.h"
#include "Traces/tracemodel.h"
@ -67,7 +67,8 @@ private slots:
void UpdateAcquisitionFrequencies();
void StartFirmwareUpdateDialog();
void DeviceNeedsUpdate(int reported, int expected);
void DeviceStatusUpdated(VirtualDevice::Status &status);
void DeviceStatusUpdated(VirtualDevice::Status status);
void DeviceInfoUpdated();
void SourceCalibrationDialog();
void ReceiverCalibrationDialog();
void FrequencyCalibrationDialog();

View File

@ -88,7 +88,7 @@ void Averaging::setMode(const Mode &value)
mode = value;
}
void Averaging::process(int pointNum, std::vector<std::complex<double>> &data)
void Averaging::process(unsigned int pointNum, std::vector<std::complex<double>> &data)
{
if(data.size() != numMeasurements) {
numMeasurements = data.size();
@ -119,12 +119,12 @@ void Averaging::process(int pointNum, std::vector<std::complex<double>> &data)
// calculate average
complex<double> sum[numMeasurements];
for(auto s : *deque) {
for(int i=0;i<numMeasurements;i++) {
for(unsigned int i=0;i<numMeasurements;i++) {
sum[i] += s[i];
}
}
for(auto s : sum) {
averagedResults.push_back(abs(s / (double) (deque->size())));
averagedResults.push_back(s / (double) (deque->size()));
}
}
break;

View File

@ -30,11 +30,11 @@ public:
void setMode(const Mode &value);
private:
void process(int pointNum, std::vector<std::complex<double> > &data);
void process(unsigned int pointNum, std::vector<std::complex<double> > &data);
std::vector<std::deque<std::vector<std::complex<double>>>> avg;
int maxPoints;
int numMeasurements;
unsigned int numMeasurements;
unsigned int averages;
Mode mode;
};

View File

@ -1,6 +1,7 @@
#include "appwindow.h"
#include "appwindow.h"
#include <QtWidgets/QApplication>
#include "Device/device.h"
#include "Device/virtualdevice.h"
#ifdef Q_OS_UNIX
#include <signal.h>
#endif
@ -20,6 +21,9 @@ int main(int argc, char *argv[]) {
qSetMessagePattern("%{time process}: [%{type}] %{message}");
Device::RegisterTypes();
VirtualDevice::RegisterTypes();
app = new QApplication(argc, argv);
QCoreApplication::setOrganizationName("LibreVNA");
QCoreApplication::setApplicationName("LibreVNA-GUI");
@ -27,8 +31,6 @@ int main(int argc, char *argv[]) {
QCoreApplication::setApplicationVersion(window->getAppVersion() + "-" +
window->getAppGitHash().left(9));
Device::RegisterTypes();
#ifdef Q_OS_UNIX
signal(SIGINT, tryExitGracefully);
#endif

View File

@ -18,8 +18,8 @@
Mode::Mode(AppWindow *window, QString name, QString SCPIname)
: QObject(window),
SCPINode(SCPIname),
window(window),
isActive(false),
window(window),
name(name),
central(nullptr)
{

View File

@ -28,7 +28,7 @@ public:
Mode(AppWindow *window, QString name, QString SCPIname);
~Mode();
virtual void shutdown(){}; // called when the application is about to exit
virtual void shutdown(){} // called when the application is about to exit
QString getName() const;
void setName(const QString &value);
void updateGraphColors();
@ -37,7 +37,7 @@ public:
virtual Type getType() = 0;
virtual void initializeDevice() = 0;
virtual void deviceDisconnected(){};
virtual void deviceDisconnected(){}
virtual void saveSreenshot();

View File

@ -85,6 +85,7 @@ QString SCPI::getResultName(SCPI::Result r)
case Result::Empty:
return "";
case Result::Error:
default:
return "ERROR";
case Result::False:
return "FALSE";