basic working wrapper
This commit is contained in:
parent
a530cea085
commit
90ac9c57e1
@ -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()
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
class Generator : public Mode
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Generator(AppWindow *window, QString name = "Signal Generator");
|
||||
void deactivate() override;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef SIGNALGENERATOR_H
|
||||
#define SIGNALGENERATOR_H
|
||||
|
||||
#include "Device/virtualdevice.h".h"
|
||||
#include "Device/virtualdevice.h"
|
||||
#include "savable.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
@ -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)";
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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()) {
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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";
|
||||
|
Loading…
Reference in New Issue
Block a user