Partial virtual device wrapper
This commit is contained in:
parent
181ba1d6bd
commit
f0a40417e4
488
Software/PC_Application/Device/virtualdevice.cpp
Normal file
488
Software/PC_Application/Device/virtualdevice.cpp
Normal file
@ -0,0 +1,488 @@
|
||||
#include "virtualdevice.h"
|
||||
|
||||
#include "preferences.h"
|
||||
#include "../VNA_embedded/Application/Communication/Protocol.hpp"
|
||||
|
||||
static VirtualDevice *connected = nullptr;
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Reference
|
||||
{
|
||||
public:
|
||||
enum class TypeIn {
|
||||
Internal,
|
||||
External,
|
||||
Auto,
|
||||
None
|
||||
};
|
||||
enum class OutFreq {
|
||||
MHZ10,
|
||||
MHZ100,
|
||||
Off,
|
||||
None
|
||||
};
|
||||
|
||||
static QString OutFreqToLabel(Reference::OutFreq t)
|
||||
{
|
||||
switch(t) {
|
||||
case OutFreq::MHZ10: return "10 MHz";
|
||||
case OutFreq::MHZ100: return "100 MHz";
|
||||
case OutFreq::Off: return "Off";
|
||||
default: return "Invalid";
|
||||
}
|
||||
}
|
||||
|
||||
static QString OutFreqToKey(Reference::OutFreq f)
|
||||
{
|
||||
switch(f) {
|
||||
case OutFreq::MHZ10: return "10 MHz";
|
||||
case OutFreq::MHZ100: return "100 MHz";
|
||||
case OutFreq::Off: return "Off";
|
||||
default: return "Invalid";
|
||||
}
|
||||
}
|
||||
|
||||
static Reference::OutFreq KeyToOutFreq(QString key)
|
||||
{
|
||||
for (auto r: Reference::getOutFrequencies()) {
|
||||
if(OutFreqToKey(r) == key|| OutFreqToLabel(r) == key) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
// not found
|
||||
return Reference::OutFreq::None;
|
||||
}
|
||||
|
||||
|
||||
static QString TypeToLabel(TypeIn t)
|
||||
{
|
||||
switch(t) {
|
||||
case TypeIn::Internal: return "Internal";
|
||||
case TypeIn::External: return "External";
|
||||
case TypeIn::Auto: return "Auto";
|
||||
default: return "Invalid";
|
||||
}
|
||||
}
|
||||
|
||||
static const QString TypeToKey(TypeIn t)
|
||||
{
|
||||
switch(t) {
|
||||
case TypeIn::Internal: return "Int";
|
||||
case TypeIn::External: return "Ext";
|
||||
case TypeIn::Auto: return "Auto";
|
||||
default: return "Invalid";
|
||||
}
|
||||
}
|
||||
|
||||
static TypeIn KeyToType(QString key)
|
||||
{
|
||||
for (auto r: Reference::getReferencesIn()) {
|
||||
if(TypeToKey(r) == key || TypeToLabel(r) == key) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
// not found
|
||||
return TypeIn::None;
|
||||
}
|
||||
|
||||
static std::vector<Reference::TypeIn> getReferencesIn()
|
||||
{
|
||||
return {TypeIn::Internal, TypeIn::External, TypeIn::Auto};
|
||||
}
|
||||
|
||||
static std::vector<Reference::OutFreq> getOutFrequencies()
|
||||
{
|
||||
return {OutFreq::Off, OutFreq::MHZ10, OutFreq::MHZ100};
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr VirtualDevice::Info defaultInfo = {
|
||||
.ProtocolVersion = Protocol::Version,
|
||||
.FW_major = 0,
|
||||
.FW_minor = 0,
|
||||
.FW_patch = 0,
|
||||
.hardware_version = 1,
|
||||
.HW_Revision = '0',
|
||||
.ports = 2,
|
||||
.supportsVNAmode = true,
|
||||
.supportsSAmode = true,
|
||||
.supportsSGmode = true,
|
||||
.Limits = {
|
||||
.minFreq = 0,
|
||||
.maxFreq = 6000000000,
|
||||
.maxFreqHarmonic = 18000000000,
|
||||
.minIFBW = 10,
|
||||
.maxIFBW = 1000000,
|
||||
.maxPoints = 10000,
|
||||
.mindBm = -100,
|
||||
.maxdBm = 100,
|
||||
.minRBW = 1,
|
||||
.maxRBW = 1000000,
|
||||
}
|
||||
};
|
||||
|
||||
static const VirtualDevice::Status defaultStatus = {
|
||||
.statusString = "",
|
||||
.overload = false,
|
||||
.unlocked = false,
|
||||
.unlevel = false,
|
||||
};
|
||||
|
||||
VirtualDevice::VirtualDevice(QString serial)
|
||||
: QObject(),
|
||||
info{}
|
||||
{
|
||||
isCompound = false;
|
||||
zerospan = false;
|
||||
auto dev = new Device(serial);
|
||||
devices.push_back(dev);
|
||||
|
||||
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();
|
||||
info.ProtocolVersion = i.ProtocolVersion;
|
||||
info.FW_major = i.FW_major;
|
||||
info.FW_minor = i.FW_minor;
|
||||
info.FW_patch = i.FW_patch;
|
||||
info.hardware_version = i.hardware_version;
|
||||
info.HW_Revision = i.HW_Revision;
|
||||
info.ports = 2;
|
||||
info.supportsVNAmode = true;
|
||||
info.supportsSAmode = true;
|
||||
info.supportsSGmode = 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.maxPoints = i.limits_maxPoints;
|
||||
info.Limits.mindBm = (double) i.limits_cdbm_min / 100;
|
||||
info.Limits.maxdBm = (double) i.limits_cdbm_max / 100;
|
||||
info.Limits.minRBW = i.limits_minRBW;
|
||||
info.Limits.maxRBW = i.limits_minRBW;
|
||||
emit InfoUpdated();
|
||||
});
|
||||
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;
|
||||
emit StatusUpdated(status);
|
||||
});
|
||||
connect(dev, &Device::NeedsFirmwareUpdate, this, &VirtualDevice::NeedsFirmwareUpdate);
|
||||
|
||||
connect(dev, &Device::SpectrumResultReceived, [&](Protocol::SpectrumAnalyzerResult res){
|
||||
SAMeasurement m;
|
||||
m.pointNum = res.pointNum;
|
||||
if(zerospan) {
|
||||
m.us = res.us;
|
||||
} else {
|
||||
m.frequency = res.frequency;
|
||||
}
|
||||
m.measurements["PORT1"] = res.port1;
|
||||
m.measurements["PORT2"] = res.port2;
|
||||
emit SAmeasurementReceived(m);
|
||||
});
|
||||
connect(dev, &Device::DatapointReceived, [&](Protocol::Datapoint res){
|
||||
VNAMeasurement m;
|
||||
m.pointNum = res.pointNum;
|
||||
if(zerospan) {
|
||||
m.us = res.us;
|
||||
} else {
|
||||
m.frequency = res.frequency;
|
||||
m.dBm = (double) res.cdbm / 100;
|
||||
}
|
||||
m.measurements["S11"] = complex<double>(res.real_S11, res.imag_S11);
|
||||
m.measurements["S21"] = complex<double>(res.real_S21, res.imag_S21);
|
||||
m.measurements["S12"] = complex<double>(res.real_S12, res.imag_S12);
|
||||
m.measurements["S22"] = complex<double>(res.real_S22, res.imag_S22);
|
||||
emit VNAmeasurementReceived(m);
|
||||
});
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
connected = this;
|
||||
}
|
||||
|
||||
VirtualDevice::~VirtualDevice()
|
||||
{
|
||||
connected = nullptr;
|
||||
for(auto dev : devices) {
|
||||
delete dev;
|
||||
}
|
||||
}
|
||||
|
||||
bool VirtualDevice::isCompoundDevice() const
|
||||
{
|
||||
return isCompound;
|
||||
}
|
||||
|
||||
Device *VirtualDevice::getDevice()
|
||||
{
|
||||
if(isCompound || devices.size() < 1) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return devices[0];
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Device *> VirtualDevice::getDevices()
|
||||
{
|
||||
return devices;
|
||||
}
|
||||
|
||||
const VirtualDevice::Info &VirtualDevice::getInfo() const
|
||||
{
|
||||
return info;
|
||||
}
|
||||
|
||||
const VirtualDevice::Info &VirtualDevice::getInfo(VirtualDevice *vdev)
|
||||
{
|
||||
if(vdev) {
|
||||
return vdev->info;
|
||||
} else {
|
||||
return defaultInfo;
|
||||
}
|
||||
}
|
||||
|
||||
const VirtualDevice::Status &VirtualDevice::getStatus() const
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
const VirtualDevice::Status &VirtualDevice::getStatus(VirtualDevice *vdev)
|
||||
{
|
||||
if(vdev) {
|
||||
return vdev->status;
|
||||
} else {
|
||||
return defaultStatus;
|
||||
}
|
||||
}
|
||||
|
||||
QStringList VirtualDevice::availableVNAMeasurements()
|
||||
{
|
||||
QStringList ret;
|
||||
for(int i=1;i<info.ports;i++) {
|
||||
for(int j=1;j<info.ports;i++) {
|
||||
ret.push_back("S"+QString::number(i)+QString::number(j));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool VirtualDevice::setVNA(const VirtualDevice::VNASettings &s, std::function<void (bool)> cb)
|
||||
{
|
||||
if(!info.supportsVNAmode) {
|
||||
return false;
|
||||
}
|
||||
zerospan = (s.freqStart == s.freqStop) && (s.dBmStart == s.dBmStop);
|
||||
auto pref = Preferences::getInstance();
|
||||
if(!isCompoundDevice()) {
|
||||
Protocol::SweepSettings sd;
|
||||
sd.f_start = s.freqStart;
|
||||
sd.f_stop = s.freqStop;
|
||||
sd.points = s.points;
|
||||
sd.if_bandwidth = s.IFBW;
|
||||
sd.cdbm_excitation_start = s.dBmStart * 100;
|
||||
sd.cdbm_excitation_stop = s.dBmStop * 100;
|
||||
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.logSweep = s.logSweep ? 1 : 0;
|
||||
return devices[0]->Configure(sd, [=](Device::TransmissionResult r){
|
||||
if(cb) {
|
||||
cb(r == Device::TransmissionResult::Ack);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QString VirtualDevice::serial()
|
||||
{
|
||||
if(!isCompoundDevice()) {
|
||||
return devices[0]->serial();
|
||||
} else {
|
||||
// TODO
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
QStringList VirtualDevice::availableSAMeasurements()
|
||||
{
|
||||
QStringList ret;
|
||||
for(int i=1;i<info.ports;i++) {
|
||||
ret.push_back("PORT"+QString::number(i));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool VirtualDevice::setSA(const VirtualDevice::SASettings &s, std::function<void (bool)> cb)
|
||||
{
|
||||
if(!info.supportsSAmode) {
|
||||
return false;
|
||||
}
|
||||
zerospan = s.freqStart == s.freqStop;
|
||||
auto pref = Preferences::getInstance();
|
||||
if(!isCompoundDevice()) {
|
||||
Protocol::SpectrumAnalyzerSettings sd;
|
||||
sd.f_start = s.freqStart;
|
||||
sd.f_stop = s.freqStop;
|
||||
sd.pointNum = s.points;
|
||||
sd.RBW = s.RBW;
|
||||
sd.WindowType = (int) s.window;
|
||||
sd.SignalID = s.signalID ? 1 : 0;
|
||||
sd.Detector = (int) s.detector;
|
||||
sd.UseDFT = 0;
|
||||
if(!s.trackingGenerator && pref.Acquisition.useDFTinSAmode && s.RBW <= pref.Acquisition.RBWLimitForDFT) {
|
||||
sd.UseDFT = 1;
|
||||
}
|
||||
sd.applyReceiverCorrection = 1;
|
||||
sd.trackingGenerator = s.trackingGenerator ? 1 : 0;
|
||||
sd.applySourceCorrection = 1;
|
||||
sd.trackingGeneratorPort = s.trackingPort;
|
||||
sd.trackingGeneratorOffset = s.trackingOffset;
|
||||
sd.trackingPower = s.trackingPower;
|
||||
return devices[0]->Configure(sd, [=](Device::TransmissionResult r){
|
||||
if(cb) {
|
||||
cb(r == Device::TransmissionResult::Ack);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QStringList VirtualDevice::availableSGPorts()
|
||||
{
|
||||
QStringList ret;
|
||||
for(int i=1;i<info.ports;i++) {
|
||||
ret.push_back("PORT"+QString::number(i));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool VirtualDevice::setSG(const SGSettings &s)
|
||||
{
|
||||
if(!info.supportsSGmode) {
|
||||
return false;
|
||||
}
|
||||
auto pref = Preferences::getInstance();
|
||||
if(!isCompoundDevice()) {
|
||||
Protocol::PacketInfo packet;
|
||||
packet.type = Protocol::PacketType::Generator;
|
||||
Protocol::GeneratorSettings &sd = packet.generator;
|
||||
sd.frequency = s.freq;
|
||||
sd.cdbm_level = s.dBm * 100;
|
||||
sd.activePort = s.port;
|
||||
sd.applyAmplitudeCorrection = 1;
|
||||
return devices[0]->SendPacket(packet);
|
||||
} else {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool VirtualDevice::setIdle(std::function<void (bool)> cb)
|
||||
{
|
||||
results.clear();
|
||||
for(auto dev : devices) {
|
||||
dev->SetIdle([&](Device::TransmissionResult r){
|
||||
if(cb) {
|
||||
results[dev] = r;
|
||||
if(results.size() == devices.size()) {
|
||||
// got all responses
|
||||
bool success = true;
|
||||
for(auto res : results) {
|
||||
if(res.second != Device::TransmissionResult::Ack) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cb(success);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
QStringList VirtualDevice::availableExtRefInSettings()
|
||||
{
|
||||
QStringList ret;
|
||||
for(auto r : Reference::getReferencesIn()) {
|
||||
ret.push_back(Reference::TypeToLabel(r));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QStringList VirtualDevice::availableExtRefOutSettings()
|
||||
{
|
||||
QStringList ret;
|
||||
for(auto r : Reference::getOutFrequencies()) {
|
||||
ret.push_back(Reference::OutFreqToLabel(r));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool VirtualDevice::setExtRef(QString option_in, QString option_out)
|
||||
{
|
||||
if(!info.supportsExtRef) {
|
||||
return false;
|
||||
}
|
||||
auto refIn = Reference::KeyToType(option_in);
|
||||
if(refIn == Reference::TypeIn::None) {
|
||||
refIn = Reference::TypeIn::Internal;
|
||||
}
|
||||
auto refOut = Reference::KeyToOutFreq(option_out);
|
||||
if(refOut == Reference::OutFreq::None) {
|
||||
refOut = Reference::OutFreq::Off;
|
||||
}
|
||||
|
||||
Protocol::PacketInfo p;
|
||||
p.type = Protocol::PacketType::Reference;
|
||||
switch(refIn) {
|
||||
case Reference::TypeIn::Internal:
|
||||
p.reference.UseExternalRef = 0;
|
||||
p.reference.AutomaticSwitch = 0;
|
||||
break;
|
||||
case Reference::TypeIn::Auto:
|
||||
p.reference.UseExternalRef = 0;
|
||||
p.reference.AutomaticSwitch = 1;
|
||||
break;
|
||||
case Reference::TypeIn::External:
|
||||
p.reference.UseExternalRef = 1;
|
||||
p.reference.AutomaticSwitch = 0;
|
||||
break;
|
||||
}
|
||||
switch(refOut) {
|
||||
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;
|
||||
}
|
||||
|
||||
bool success = true;
|
||||
for(auto dev : devices) {
|
||||
success &= dev->SendPacket(p);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
std::set<QString> VirtualDevice::GetDevices()
|
||||
{
|
||||
auto ret = Device::GetDevices();
|
||||
// TODO check if compound devices are configured and add them if all sub-devices are available
|
||||
return ret;
|
||||
}
|
||||
|
||||
VirtualDevice *VirtualDevice::getConnected()
|
||||
{
|
||||
return connected;
|
||||
}
|
175
Software/PC_Application/Device/virtualdevice.h
Normal file
175
Software/PC_Application/Device/virtualdevice.h
Normal file
@ -0,0 +1,175 @@
|
||||
#ifndef VIRTUALDEVICE_H
|
||||
#define VIRTUALDEVICE_H
|
||||
|
||||
#include "device.h"
|
||||
|
||||
#include <set>
|
||||
#include <complex>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class VirtualDevice : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VirtualDevice(QString serial = "");
|
||||
~VirtualDevice();
|
||||
|
||||
class Info {
|
||||
public:
|
||||
uint16_t ProtocolVersion;
|
||||
uint8_t FW_major;
|
||||
uint8_t FW_minor;
|
||||
uint8_t FW_patch;
|
||||
uint8_t hardware_version;
|
||||
char HW_Revision;
|
||||
int ports;
|
||||
bool supportsVNAmode;
|
||||
bool supportsSAmode;
|
||||
bool supportsSGmode;
|
||||
bool supportsExtRef;
|
||||
struct {
|
||||
double minFreq, maxFreq, maxFreqHarmonic;
|
||||
double minIFBW, maxIFBW;
|
||||
int maxPoints;
|
||||
double mindBm;
|
||||
double maxdBm;
|
||||
double minRBW, maxRBW;
|
||||
} Limits;
|
||||
};
|
||||
|
||||
class Status {
|
||||
public:
|
||||
QString statusString;
|
||||
bool overload;
|
||||
bool unlocked;
|
||||
bool unlevel;
|
||||
};
|
||||
|
||||
bool isCompoundDevice() const;
|
||||
Device *getDevice();
|
||||
std::vector<Device*> getDevices();
|
||||
const Info& getInfo() const;
|
||||
static const VirtualDevice::Info &getInfo(VirtualDevice *vdev);
|
||||
const Status &getStatus() const;
|
||||
static const VirtualDevice::Status &getStatus(VirtualDevice *vdev);
|
||||
|
||||
class VNASettings {
|
||||
public:
|
||||
double freqStart, freqStop;
|
||||
double dBmStart, dBmStop;
|
||||
double IFBW;
|
||||
int points;
|
||||
bool logSweep;
|
||||
std::vector<int> excitedPorts;
|
||||
};
|
||||
class VNAMeasurement {
|
||||
public:
|
||||
int pointNum;
|
||||
union {
|
||||
struct {
|
||||
// for non-zero span
|
||||
double frequency;
|
||||
double dBm;
|
||||
};
|
||||
struct {
|
||||
// for zero span
|
||||
double us; // time in us since first datapoint
|
||||
};
|
||||
};
|
||||
std::map<QString, std::complex<double>> measurements;
|
||||
};
|
||||
|
||||
QStringList availableVNAMeasurements();
|
||||
bool setVNA(const VNASettings &s, std::function<void(bool)> cb = nullptr);
|
||||
QString serial();
|
||||
|
||||
class SASettings {
|
||||
public:
|
||||
enum class Window {
|
||||
None = 0,
|
||||
Kaiser = 1,
|
||||
Hann = 2,
|
||||
FlatTop = 3,
|
||||
Last
|
||||
};
|
||||
enum class Detector {
|
||||
PPeak = 0,
|
||||
NPeak = 1,
|
||||
Sample = 2,
|
||||
Normal = 3,
|
||||
Average = 4,
|
||||
Last
|
||||
};
|
||||
|
||||
double freqStart, freqStop;
|
||||
double RBW;
|
||||
int points;
|
||||
Window window;
|
||||
Detector detector;
|
||||
bool signalID;
|
||||
bool trackingGenerator;
|
||||
int trackingPort;
|
||||
double trackingOffset;
|
||||
double trackingPower;
|
||||
};
|
||||
class SAMeasurement {
|
||||
public:
|
||||
int pointNum;
|
||||
union {
|
||||
struct {
|
||||
// for non-zero span
|
||||
double frequency;
|
||||
double cdbm;
|
||||
};
|
||||
struct {
|
||||
// for zero span
|
||||
double us; // time in us since first datapoint
|
||||
};
|
||||
};
|
||||
std::map<QString, double> measurements;
|
||||
};
|
||||
|
||||
QStringList availableSAMeasurements();
|
||||
bool setSA(const SASettings &s, std::function<void(bool)> cb = nullptr);
|
||||
|
||||
class SGSettings {
|
||||
public:
|
||||
double freq;
|
||||
double dBm;
|
||||
int port;
|
||||
};
|
||||
|
||||
QStringList availableSGPorts();
|
||||
bool setSG(const SGSettings &s);
|
||||
|
||||
bool setIdle(std::function<void(bool)> cb = nullptr);
|
||||
|
||||
QStringList availableExtRefInSettings();
|
||||
QStringList availableExtRefOutSettings();
|
||||
|
||||
bool setExtRef(QString option_in, QString option_out);
|
||||
|
||||
static std::set<QString> GetDevices();
|
||||
static VirtualDevice* getConnected();
|
||||
|
||||
signals:
|
||||
void VNAmeasurementReceived(const VNAMeasurement &m);
|
||||
void SAmeasurementReceived(const SAMeasurement &m);
|
||||
void ConnectionLost();
|
||||
void InfoUpdated();
|
||||
void StatusUpdated(const Status &status);
|
||||
void LogLineReceived(QString line);
|
||||
void NeedsFirmwareUpdate(int usedProtocol, int requiredProtocol);
|
||||
private:
|
||||
Info info;
|
||||
Status status;
|
||||
bool isCompound;
|
||||
std::vector<Device*> devices;
|
||||
std::vector<int> portMapping;
|
||||
bool zerospan;
|
||||
|
||||
std::map<Device*, Device::TransmissionResult> results;
|
||||
};
|
||||
|
||||
#endif // VIRTUALDEVICE_H
|
@ -30,8 +30,8 @@ void Generator::deactivate()
|
||||
// store current settings
|
||||
QSettings s;
|
||||
auto settings = central->getDeviceStatus();
|
||||
s.setValue("GeneratorFrequency", static_cast<unsigned long long>(settings.frequency));
|
||||
s.setValue("GeneratorLevel", static_cast<unsigned long long>((double) settings.cdbm_level / 100.0));
|
||||
s.setValue("GeneratorFrequency", static_cast<unsigned long long>(settings.freq));
|
||||
s.setValue("GeneratorLevel", static_cast<unsigned long long>((double) settings.dBm));
|
||||
Mode::deactivate();
|
||||
}
|
||||
|
||||
@ -59,10 +59,7 @@ void Generator::updateDevice()
|
||||
// can't update if not connected
|
||||
return;
|
||||
}
|
||||
Protocol::PacketInfo p;
|
||||
p.type = Protocol::PacketType::Generator;
|
||||
p.generator = central->getDeviceStatus();
|
||||
window->getDevice()->SendPacket(p);
|
||||
window->getDevice()->setSG(central->getDeviceStatus());
|
||||
}
|
||||
|
||||
void Generator::setupSCPI()
|
||||
@ -76,7 +73,7 @@ void Generator::setupSCPI()
|
||||
return SCPI::getResultName(SCPI::Result::Empty);
|
||||
}
|
||||
}, [=](QStringList) -> QString {
|
||||
return QString::number(central->getDeviceStatus().frequency);
|
||||
return QString::number(central->getDeviceStatus().freq);
|
||||
}));
|
||||
add(new SCPICommand("LVL", [=](QStringList params) -> QString {
|
||||
double newval;
|
||||
@ -88,7 +85,7 @@ void Generator::setupSCPI()
|
||||
return SCPI::getResultName(SCPI::Result::Empty);
|
||||
}
|
||||
}, [=](QStringList) -> QString {
|
||||
return QString::number(central->getDeviceStatus().cdbm_level / 100.0);
|
||||
return QString::number(central->getDeviceStatus().dBm);
|
||||
}));
|
||||
add(new SCPICommand("PORT", [=](QStringList params) -> QString {
|
||||
unsigned long long newval;
|
||||
@ -99,6 +96,6 @@ void Generator::setupSCPI()
|
||||
return SCPI::getResultName(SCPI::Result::Empty);
|
||||
}
|
||||
}, [=](QStringList) -> QString {
|
||||
return QString::number(central->getDeviceStatus().activePort);
|
||||
return QString::number(central->getDeviceStatus().port);
|
||||
}));
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include "ui_signalgenwidget.h"
|
||||
|
||||
SignalgeneratorWidget::SignalgeneratorWidget(Device *&dev, QWidget *parent) :
|
||||
SignalgeneratorWidget::SignalgeneratorWidget(VirtualDevice *dev, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::SignalgeneratorWidget),
|
||||
dev(dev)
|
||||
@ -32,16 +32,16 @@ SignalgeneratorWidget::SignalgeneratorWidget(Device *&dev, QWidget *parent) :
|
||||
ui->steps->setPrecision(0);
|
||||
|
||||
connect(ui->frequency, &SIUnitEdit::valueChanged, [=](double newval) {
|
||||
if(newval < Device::Info(dev).limits_minFreq) {
|
||||
newval = Device::Info(dev).limits_minFreq;
|
||||
} else if (newval > Device::Info(dev).limits_maxFreq) {
|
||||
newval = Device::Info(dev).limits_maxFreq;
|
||||
if(newval < VirtualDevice::getInfo(dev).Limits.minFreq) {
|
||||
newval = VirtualDevice::getInfo(dev).Limits.minFreq;
|
||||
} else if (newval > VirtualDevice::getInfo(dev).Limits.maxFreq) {
|
||||
newval = VirtualDevice::getInfo(dev).Limits.maxFreq;
|
||||
}
|
||||
ui->frequency->setValueQuiet(newval);
|
||||
if (newval < ui->span->value()/2)
|
||||
ui->span->setValueQuiet(newval/2);
|
||||
if (newval + ui->span->value()/2 > Device::Info(dev).limits_maxFreq)
|
||||
ui->span->setValueQuiet((Device::Info(dev).limits_maxFreq - newval)*2);
|
||||
if (newval + ui->span->value()/2 > VirtualDevice::getInfo(dev).Limits.maxFreq)
|
||||
ui->span->setValueQuiet((VirtualDevice::getInfo(dev).Limits.maxFreq - newval)*2);
|
||||
newval = ui->frequency->value() - ui->span->value()/2;
|
||||
ui->current->setValueQuiet(newval);
|
||||
emit SettingsChanged();
|
||||
@ -50,8 +50,8 @@ SignalgeneratorWidget::SignalgeneratorWidget(Device *&dev, QWidget *parent) :
|
||||
connect(ui->span, &SIUnitEdit::valueChanged, [=](double newval) {
|
||||
if(newval < 0 ) {
|
||||
newval = 0;
|
||||
} else if (newval > Device::Info(dev).limits_maxFreq - Device::Info(dev).limits_minFreq) {
|
||||
newval = Device::Info(dev).limits_maxFreq - Device::Info(dev).limits_minFreq;
|
||||
} else if (newval > VirtualDevice::getInfo(dev).Limits.maxFreq - VirtualDevice::getInfo(dev).Limits.minFreq) {
|
||||
newval = VirtualDevice::getInfo(dev).Limits.maxFreq - VirtualDevice::getInfo(dev).Limits.minFreq;
|
||||
}
|
||||
ui->span->setValueQuiet(newval);
|
||||
|
||||
@ -60,8 +60,8 @@ SignalgeneratorWidget::SignalgeneratorWidget(Device *&dev, QWidget *parent) :
|
||||
ui->frequency->setValueQuiet(ui->span->value()/2);
|
||||
}
|
||||
newF = ui->frequency->value() + ui->span->value()/2;
|
||||
if (newF > Device::Info(dev).limits_maxFreq) {
|
||||
ui->frequency->setValueQuiet(Device::Info(dev).limits_maxFreq - ui->span->value()/2);
|
||||
if (newF > VirtualDevice::getInfo(dev).Limits.maxFreq) {
|
||||
ui->frequency->setValueQuiet(VirtualDevice::getInfo(dev).Limits.maxFreq - ui->span->value()/2);
|
||||
}
|
||||
|
||||
newval = ui->frequency->value() - ui->span->value()/2;
|
||||
@ -72,8 +72,8 @@ SignalgeneratorWidget::SignalgeneratorWidget(Device *&dev, QWidget *parent) :
|
||||
connect(ui->current, &SIUnitEdit::valueChanged, [=](double newval) {
|
||||
if(newval < 0 ) {
|
||||
newval = 0;
|
||||
} else if (newval > Device::Info(dev).limits_maxFreq - Device::Info(dev).limits_minFreq) {
|
||||
newval = Device::Info(dev).limits_maxFreq - Device::Info(dev).limits_minFreq;
|
||||
} else if (newval > VirtualDevice::getInfo(dev).Limits.maxFreq - VirtualDevice::getInfo(dev).Limits.minFreq) {
|
||||
newval = VirtualDevice::getInfo(dev).Limits.maxFreq - VirtualDevice::getInfo(dev).Limits.minFreq;
|
||||
}
|
||||
ui->current->setValueQuiet(newval);
|
||||
emit SettingsChanged();
|
||||
@ -140,22 +140,21 @@ void SignalgeneratorWidget::timerEvent(QTimerEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
Protocol::GeneratorSettings SignalgeneratorWidget::getDeviceStatus()
|
||||
VirtualDevice::SGSettings SignalgeneratorWidget::getDeviceStatus()
|
||||
{
|
||||
Protocol::GeneratorSettings s = {};
|
||||
VirtualDevice::SGSettings s = {};
|
||||
if (ui->EnabledSweep->isChecked())
|
||||
s.frequency = ui->current->value();
|
||||
s.freq = ui->current->value();
|
||||
else
|
||||
s.frequency = ui->frequency->value();
|
||||
s.cdbm_level = ui->levelSpin->value() * 100.0;
|
||||
s.freq = ui->frequency->value();
|
||||
s.dBm = ui->levelSpin->value();
|
||||
if(ui->EnablePort1->isChecked()) {
|
||||
s.activePort = 1;
|
||||
s.port = 1;
|
||||
} else if(ui->EnablePort2->isChecked()) {
|
||||
s.activePort = 2;
|
||||
s.port = 2;
|
||||
} else {
|
||||
s.activePort = 0;
|
||||
s.port = 0;
|
||||
}
|
||||
s.applyAmplitudeCorrection = 1;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef SIGNALGENERATOR_H
|
||||
#define SIGNALGENERATOR_H
|
||||
|
||||
#include "Device/device.h"
|
||||
#include "Device/virtualdevice.h".h"
|
||||
#include "savable.h"
|
||||
|
||||
#include <QWidget>
|
||||
@ -15,10 +15,10 @@ class SignalgeneratorWidget : public QWidget, public Savable
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SignalgeneratorWidget(Device*&dev, QWidget *parent = nullptr);
|
||||
explicit SignalgeneratorWidget(VirtualDevice *dev, QWidget *parent = nullptr);
|
||||
~SignalgeneratorWidget();
|
||||
|
||||
Protocol::GeneratorSettings getDeviceStatus();
|
||||
VirtualDevice::SGSettings getDeviceStatus();
|
||||
virtual nlohmann::json toJSON() override;
|
||||
virtual void fromJSON(nlohmann::json j) override;
|
||||
|
||||
@ -36,7 +36,7 @@ protected:
|
||||
private:
|
||||
Ui::SignalgeneratorWidget *ui;
|
||||
int m_timerId;
|
||||
Device*&dev;
|
||||
VirtualDevice *dev;
|
||||
};
|
||||
|
||||
#endif // SIGNALGENERATOR_H
|
||||
|
@ -22,6 +22,7 @@ HEADERS += \
|
||||
Device/devicelog.h \
|
||||
Device/firmwareupdatedialog.h \
|
||||
Device/manualcontroldialog.h \
|
||||
Device/virtualdevice.h \
|
||||
Generator/generator.h \
|
||||
Generator/signalgenwidget.h \
|
||||
SpectrumAnalyzer/spectrumanalyzer.h \
|
||||
@ -157,6 +158,7 @@ SOURCES += \
|
||||
Device/devicelog.cpp \
|
||||
Device/firmwareupdatedialog.cpp \
|
||||
Device/manualcontroldialog.cpp \
|
||||
Device/virtualdevice.cpp \
|
||||
Generator/generator.cpp \
|
||||
Generator/signalgenwidget.cpp \
|
||||
SpectrumAnalyzer/spectrumanalyzer.cpp \
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "Tools/impedancematchdialog.h"
|
||||
#include "Calibration/calibrationtracedialog.h"
|
||||
#include "ui_main.h"
|
||||
#include "Device/firmwareupdatedialog.h"
|
||||
#include "Device/virtualdevice.h".h"
|
||||
#include "preferences.h"
|
||||
#include "Generator/signalgenwidget.h"
|
||||
|
||||
@ -164,7 +164,7 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
|
||||
cbWindowType->addItem("Flat Top");
|
||||
cbWindowType->setCurrentIndex(1);
|
||||
connect(cbWindowType, qOverload<int>(&QComboBox::currentIndexChanged), [=](int index) {
|
||||
SetWindow((Window) index);
|
||||
SetWindow((VirtualDevice::SASettings::Window) index);
|
||||
});
|
||||
tb_acq->addWidget(cbWindowType);
|
||||
|
||||
@ -177,7 +177,7 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
|
||||
cbDetector->addItem("Average");
|
||||
cbDetector->setCurrentIndex(0);
|
||||
connect(cbDetector, qOverload<int>(&QComboBox::currentIndexChanged), [=](int index) {
|
||||
SetDetector((Detector) index);
|
||||
SetDetector((VirtualDevice::SASettings::Detector) index);
|
||||
});
|
||||
tb_acq->addWidget(cbDetector);
|
||||
|
||||
@ -286,14 +286,14 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
|
||||
if(pref.Startup.RememberSweepSettings) {
|
||||
LoadSweepSettings();
|
||||
} else {
|
||||
settings.f_start = pref.Startup.SA.start;
|
||||
settings.f_stop = pref.Startup.SA.stop;
|
||||
settings.freqStart = pref.Startup.SA.start;
|
||||
settings.freqStop = pref.Startup.SA.stop;
|
||||
ConstrainAndUpdateFrequencies();
|
||||
SetRBW(pref.Startup.SA.RBW);
|
||||
SetAveraging(pref.Startup.SA.averaging);
|
||||
settings.pointNum = 1001;
|
||||
SetWindow((Window) pref.Startup.SA.window);
|
||||
SetDetector((Detector) pref.Startup.SA.detector);
|
||||
settings.points = 1001;
|
||||
SetWindow((VirtualDevice::SASettings::Window) pref.Startup.SA.window);
|
||||
SetDetector((VirtualDevice::SASettings::Detector) pref.Startup.SA.detector);
|
||||
SetSignalID(pref.Startup.SA.signalID);
|
||||
}
|
||||
|
||||
@ -308,7 +308,7 @@ void SpectrumAnalyzer::deactivate()
|
||||
|
||||
void SpectrumAnalyzer::initializeDevice()
|
||||
{
|
||||
connect(window->getDevice(), &Device::SpectrumResultReceived, this, &SpectrumAnalyzer::NewDatapoint, Qt::UniqueConnection);
|
||||
connect(window->getDevice(), &VirtualDevice::SAmeasurementReceived, this, &SpectrumAnalyzer::NewDatapoint, Qt::UniqueConnection);
|
||||
|
||||
// Configure initial state of device
|
||||
SettingsChanged();
|
||||
@ -320,20 +320,20 @@ nlohmann::json SpectrumAnalyzer::toJSON()
|
||||
// save current sweep/acquisition settings
|
||||
nlohmann::json sweep;
|
||||
nlohmann::json freq;
|
||||
freq["start"] = settings.f_start;
|
||||
freq["stop"] = settings.f_stop;
|
||||
freq["start"] = settings.freqStart;
|
||||
freq["stop"] = settings.freqStop;
|
||||
sweep["frequency"] = freq;
|
||||
sweep["single"] = singleSweep;
|
||||
nlohmann::json acq;
|
||||
acq["RBW"] = settings.RBW;
|
||||
acq["window"] = WindowToString((Window) settings.WindowType).toStdString();
|
||||
acq["detector"] = DetectorToString((Detector) settings.Detector).toStdString();
|
||||
acq["signal ID"] = settings.SignalID ? true : false;
|
||||
acq["window"] = WindowToString((VirtualDevice::SASettings::Window) settings.window).toStdString();
|
||||
acq["detector"] = DetectorToString((VirtualDevice::SASettings::Detector) settings.detector).toStdString();
|
||||
acq["signal ID"] = settings.signalID ? true : false;
|
||||
sweep["acquisition"] = acq;
|
||||
nlohmann::json tracking;
|
||||
tracking["enabled"] = settings.trackingGenerator ? true : false;
|
||||
tracking["port"] = settings.trackingGeneratorPort ? 2 : 1;
|
||||
tracking["offset"] = settings.trackingGeneratorOffset;
|
||||
tracking["port"] = settings.trackingPort ? 2 : 1;
|
||||
tracking["offset"] = settings.trackingOffset;
|
||||
tracking["power"] = (double) settings.trackingPower / 100.0; // convert to dBm
|
||||
sweep["trackingGenerator"] = tracking;
|
||||
|
||||
@ -343,8 +343,11 @@ nlohmann::json SpectrumAnalyzer::toJSON()
|
||||
norm["stop"] = normalize.f_stop;
|
||||
norm["points"] = normalize.points;
|
||||
norm["level"] = normalize.Level->value();
|
||||
norm["port1"] = normalize.port1Correction;
|
||||
norm["port2"] = normalize.port2Correction;
|
||||
nlohmann::json jCorr;
|
||||
for(auto m : normalize.portCorrection) {
|
||||
jCorr[m.first.toStdString()] = m.second;
|
||||
}
|
||||
norm["corrections"] = jCorr;
|
||||
sweep["normalization"] = norm;
|
||||
}
|
||||
j["sweep"] = sweep;
|
||||
@ -374,25 +377,25 @@ void SpectrumAnalyzer::fromJSON(nlohmann::json j)
|
||||
auto sweep = j["sweep"];
|
||||
if(sweep.contains("frequency")) {
|
||||
auto freq = sweep["frequency"];
|
||||
SetStartFreq(freq.value("start", settings.f_start));
|
||||
SetStopFreq(freq.value("stop", settings.f_start));
|
||||
SetStartFreq(freq.value("start", settings.freqStart));
|
||||
SetStopFreq(freq.value("stop", settings.freqStop));
|
||||
}
|
||||
if(sweep.contains("acquisition")) {
|
||||
auto acq = sweep["acquisition"];
|
||||
SetRBW(acq.value("RBW", settings.RBW));
|
||||
auto w = WindowFromString(QString::fromStdString(acq.value("window", "")));
|
||||
if(w == Window::Last) {
|
||||
if(w == VirtualDevice::SASettings::Window::Last) {
|
||||
// invalid, keep current value
|
||||
w = (Window) settings.WindowType;
|
||||
w = (VirtualDevice::SASettings::Window) settings.window;
|
||||
}
|
||||
SetWindow(w);
|
||||
auto d = DetectorFromString(QString::fromStdString(acq.value("detector", "")));
|
||||
if(d == Detector::Last) {
|
||||
if(d == VirtualDevice::SASettings::Detector::Last) {
|
||||
// invalid, keep current value
|
||||
d = (Detector) settings.Detector;
|
||||
d = (VirtualDevice::SASettings::Detector) settings.detector;
|
||||
}
|
||||
SetDetector(d);
|
||||
SetSignalID(acq.value("signal ID", settings.SignalID ? true : false));
|
||||
SetSignalID(acq.value("signal ID", settings.signalID ? true : false));
|
||||
}
|
||||
if(sweep.contains("trackingGenerator")) {
|
||||
auto tracking = sweep["trackingGenerator"];
|
||||
@ -401,29 +404,33 @@ void SpectrumAnalyzer::fromJSON(nlohmann::json j)
|
||||
// Function expects 0 for port1, 1 for port2
|
||||
SetTGPort(port - 1);
|
||||
SetTGLevel(tracking.value("power", settings.trackingPower));
|
||||
SetTGOffset(tracking.value("offset", settings.trackingGeneratorOffset));
|
||||
SetTGOffset(tracking.value("offset", settings.trackingOffset));
|
||||
}
|
||||
if(sweep.contains("normalization")) {
|
||||
auto norm = sweep["normalization"];
|
||||
// restore normalization data
|
||||
normalize.port1Correction.clear();
|
||||
for(double p1 : norm["port1"]) {
|
||||
normalize.port1Correction.push_back(p1);
|
||||
}
|
||||
normalize.port2Correction.clear();
|
||||
for(double p2 : norm["port2"]) {
|
||||
normalize.port2Correction.push_back(p2);
|
||||
normalize.portCorrection.clear();
|
||||
if(norm.contains("corrections")) {
|
||||
for(auto& el : norm["corrections"].items()) {
|
||||
normalize.portCorrection[QString::fromStdString(el.key())] = {};
|
||||
for(auto p : el.value()) {
|
||||
normalize.portCorrection[QString::fromStdString(el.key())].push_back(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
normalize.f_start = norm.value("start", normalize.f_start);
|
||||
normalize.f_stop = norm.value("stop", normalize.f_stop);
|
||||
normalize.points = norm.value("points", normalize.points);
|
||||
normalize.Level->setValue(norm.value("level", normalize.Level->value()));
|
||||
if((normalize.port1Correction.size() == normalize.points) && (normalize.port1Correction.size() == normalize.points)) {
|
||||
// got the correct number of points
|
||||
EnableNormalization(true);
|
||||
} else {
|
||||
EnableNormalization(false);
|
||||
// check correction vector size
|
||||
bool correctSize = true;
|
||||
for(auto c : normalize.portCorrection) {
|
||||
if(c.second.size() != normalize.points) {
|
||||
correctSize = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
EnableNormalization(correctSize);
|
||||
}
|
||||
SetSingleSweep(sweep.value("single", singleSweep));
|
||||
}
|
||||
@ -431,7 +438,7 @@ void SpectrumAnalyzer::fromJSON(nlohmann::json j)
|
||||
|
||||
using namespace std;
|
||||
|
||||
void SpectrumAnalyzer::NewDatapoint(Protocol::SpectrumAnalyzerResult d)
|
||||
void SpectrumAnalyzer::NewDatapoint(const VirtualDevice::SAMeasurement &m)
|
||||
{
|
||||
if(isActive != true) {
|
||||
return;
|
||||
@ -445,115 +452,100 @@ void SpectrumAnalyzer::NewDatapoint(Protocol::SpectrumAnalyzerResult d)
|
||||
if(singleSweep && average.getLevel() == averages) {
|
||||
changingSettings = true;
|
||||
// single sweep finished
|
||||
window->getDevice()->SetIdle([=](Device::TransmissionResult){
|
||||
window->getDevice()->setIdle([=](bool){
|
||||
changingSettings = false;
|
||||
});
|
||||
}
|
||||
|
||||
if(d.pointNum >= settings.pointNum) {
|
||||
qWarning() << "Ignoring point with too large point number (" << d.pointNum << ")";
|
||||
if(m.pointNum >= settings.points) {
|
||||
qWarning() << "Ignoring point with too large point number (" << m.pointNum << ")";
|
||||
return;
|
||||
}
|
||||
|
||||
d = average.process(d);
|
||||
auto m_avg = average.process(m);
|
||||
|
||||
if(settings.f_start == settings.f_stop) {
|
||||
if(settings.freqStart == settings.freqStop) {
|
||||
// keep track of first point time
|
||||
if(d.pointNum == 0) {
|
||||
firstPointTime = d.us;
|
||||
d.us = 0;
|
||||
if(m_avg.pointNum == 0) {
|
||||
firstPointTime = m_avg.us;
|
||||
m_avg.us = 0;
|
||||
} else {
|
||||
d.us -= firstPointTime;
|
||||
m_avg.us -= firstPointTime;
|
||||
}
|
||||
}
|
||||
|
||||
if(normalize.measuring) {
|
||||
if(average.currentSweep() == averages) {
|
||||
// this is the last averaging sweep, use values for normalization
|
||||
if(normalize.port1Correction.size() > 0 || d.pointNum == 0) {
|
||||
if(normalize.portCorrection[0].size() > 0 || m_avg.pointNum == 0) {
|
||||
// add measurement
|
||||
normalize.port1Correction.push_back(d.port1);
|
||||
normalize.port2Correction.push_back(d.port2);
|
||||
if(d.pointNum == settings.pointNum - 1) {
|
||||
for(auto m : m_avg.measurements) {
|
||||
normalize.portCorrection[m.first].push_back(m.second);
|
||||
}
|
||||
if(m_avg.pointNum == settings.points - 1) {
|
||||
// this was the last point
|
||||
normalize.measuring = false;
|
||||
normalize.f_start = settings.f_start;
|
||||
normalize.f_stop = settings.f_stop;
|
||||
normalize.points = settings.pointNum;
|
||||
normalize.f_start = settings.freqStart;
|
||||
normalize.f_stop = settings.freqStop;
|
||||
normalize.points = settings.points;
|
||||
EnableNormalization(true);
|
||||
qDebug() << "Normalization measurement complete";
|
||||
}
|
||||
}
|
||||
}
|
||||
int percentage = (((average.currentSweep() - 1) * 100) + (d.pointNum + 1) * 100 / settings.pointNum) / averages;
|
||||
int percentage = (((average.currentSweep() - 1) * 100) + (m_avg.pointNum + 1) * 100 / settings.points) / averages;
|
||||
normalize.dialog.setValue(percentage);
|
||||
}
|
||||
|
||||
if(normalize.active) {
|
||||
d.port1 /= normalize.port1Correction[d.pointNum];
|
||||
d.port2 /= normalize.port2Correction[d.pointNum];
|
||||
double corr = pow(10.0, normalize.Level->value() / 20.0);
|
||||
d.port1 *= corr;
|
||||
d.port2 *= corr;
|
||||
for(auto &m : m_avg.measurements) {
|
||||
m.second /= normalize.portCorrection[m.first][m_avg.pointNum];
|
||||
m.second *= corr;
|
||||
}
|
||||
}
|
||||
|
||||
traceModel.addSAData(d, settings);
|
||||
traceModel.addSAData(m_avg, settings);
|
||||
emit dataChanged();
|
||||
if(d.pointNum == settings.pointNum - 1) {
|
||||
if(m_avg.pointNum == settings.points - 1) {
|
||||
UpdateAverageCount();
|
||||
markerModel->updateMarkers();
|
||||
}
|
||||
static unsigned int lastPoint = 0;
|
||||
if(d.pointNum > 0 && d.pointNum != lastPoint + 1) {
|
||||
qWarning() << "Got point" << d.pointNum << "but last received point was" << lastPoint << "("<<(d.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 = d.pointNum;
|
||||
lastPoint = m_avg.pointNum;
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::SettingsChanged()
|
||||
{
|
||||
changingSettings = true;
|
||||
if(settings.f_stop - settings.f_start >= 1000 || settings.f_stop - settings.f_start <= 0) {
|
||||
settings.pointNum = 1001;
|
||||
if(settings.freqStop - settings.freqStart >= 1000 || settings.freqStop - settings.freqStart <= 0) {
|
||||
settings.points = 1001;
|
||||
} else {
|
||||
settings.pointNum = settings.f_stop - settings.f_start + 1;
|
||||
}
|
||||
settings.applyReceiverCorrection = 1;
|
||||
settings.applySourceCorrection = 1;
|
||||
|
||||
auto pref = Preferences::getInstance();
|
||||
if(settings.f_stop > settings.f_start) {
|
||||
// non-zerospan, check usability of DFT
|
||||
if(!settings.trackingGenerator && pref.Acquisition.useDFTinSAmode && settings.RBW <= pref.Acquisition.RBWLimitForDFT) {
|
||||
// Enable DFT if below RBW threshold and TG is not enabled
|
||||
settings.UseDFT = 1;
|
||||
} else {
|
||||
settings.UseDFT = 0;
|
||||
}
|
||||
} else {
|
||||
// zerospan, DFT not usable
|
||||
settings.UseDFT = 0;
|
||||
settings.points = settings.freqStop - settings.freqStart + 1;
|
||||
}
|
||||
|
||||
if(settings.trackingGenerator && settings.f_stop >= 25000000) {
|
||||
if(settings.trackingGenerator && settings.freqStop >= 25000000) {
|
||||
// Check point spacing.
|
||||
// The highband PLL used as the tracking generator is not able to reach every frequency exactly. This
|
||||
// could lead to sharp drops in the spectrum at certain frequencies. If the span is wide enough with
|
||||
// respect to the point number, it is ensured that every displayed point has at least one sample with
|
||||
// a reachable PLL frequency in it. Display a warning message if this is not the case with the current
|
||||
// settings.
|
||||
auto pointSpacing = (settings.f_stop - settings.f_start) / (settings.pointNum - 1);
|
||||
auto pointSpacing = (settings.freqStop - settings.freqStart) / (settings.points - 1);
|
||||
// The frequency resolution of the PLL is frequency dependent (due to PLL divider).
|
||||
// This code assumes some knowledge of the actual hardware and probably should be moved
|
||||
// onto the device at some point
|
||||
double minSpacing = 25000;
|
||||
auto stop = settings.f_stop;
|
||||
auto stop = settings.freqStop;
|
||||
while(stop <= 3000000000) {
|
||||
minSpacing /= 2;
|
||||
stop *= 2;
|
||||
}
|
||||
if(pointSpacing < minSpacing) {
|
||||
auto requiredMinSpan = minSpacing * (settings.pointNum - 1);
|
||||
auto requiredMinSpan = minSpacing * (settings.points - 1);
|
||||
auto message = QString() + "Due to PLL limitations, the tracking generator can not reach every frequency exactly. "
|
||||
"With your current span, this could result in the signal not being detected at some bands. A minimum"
|
||||
" span of " + Unit::ToString(requiredMinSpan, "Hz", " kMG") + " is recommended at this stop frequency.";
|
||||
@ -563,7 +555,7 @@ void SpectrumAnalyzer::SettingsChanged()
|
||||
|
||||
if(normalize.active) {
|
||||
// check if normalization is still valid
|
||||
if(normalize.f_start != settings.f_start || normalize.f_stop != settings.f_stop || normalize.points != settings.pointNum) {
|
||||
if(normalize.f_start != settings.freqStart || normalize.f_stop != settings.freqStop || normalize.points != settings.points) {
|
||||
// normalization was taken at different settings, disable
|
||||
EnableNormalization(false);
|
||||
InformationBox::ShowMessage("Information", "Normalization was disabled because the span has been changed");
|
||||
@ -571,104 +563,104 @@ void SpectrumAnalyzer::SettingsChanged()
|
||||
}
|
||||
|
||||
if(window->getDevice() && isActive) {
|
||||
window->getDevice()->Configure(settings, [=](Device::TransmissionResult res){
|
||||
window->getDevice()->setSA(settings, [=](bool){
|
||||
// device received command
|
||||
changingSettings = false;
|
||||
});
|
||||
}
|
||||
average.reset(settings.pointNum);
|
||||
average.reset(settings.points);
|
||||
UpdateAverageCount();
|
||||
traceModel.clearLiveData();
|
||||
emit traceModel.SpanChanged(settings.f_start, settings.f_stop);
|
||||
emit traceModel.SpanChanged(settings.freqStart, settings.freqStop);
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::SetStartFreq(double freq)
|
||||
{
|
||||
settings.f_start = freq;
|
||||
if(settings.f_stop < freq) {
|
||||
settings.f_stop = freq;
|
||||
settings.freqStart = freq;
|
||||
if(settings.freqStop < freq) {
|
||||
settings.freqStop = freq;
|
||||
}
|
||||
ConstrainAndUpdateFrequencies();
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::SetStopFreq(double freq)
|
||||
{
|
||||
settings.f_stop = freq;
|
||||
if(settings.f_start > freq) {
|
||||
settings.f_start = freq;
|
||||
settings.freqStop = freq;
|
||||
if(settings.freqStart > freq) {
|
||||
settings.freqStart = freq;
|
||||
}
|
||||
ConstrainAndUpdateFrequencies();
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::SetCenterFreq(double freq)
|
||||
{
|
||||
auto old_span = settings.f_stop - settings.f_start;
|
||||
if (freq - old_span / 2 <= Device::Info(window->getDevice()).limits_minFreq) {
|
||||
auto old_span = settings.freqStop - settings.freqStart;
|
||||
if (freq - old_span / 2 <= VirtualDevice::getInfo(window->getDevice()).Limits.minFreq) {
|
||||
// would shift start frequency below minimum
|
||||
settings.f_start = 0;
|
||||
settings.f_stop = 2 * freq;
|
||||
} else if(freq + old_span / 2 >= Device::Info(window->getDevice()).limits_maxFreq) {
|
||||
settings.freqStart = 0;
|
||||
settings.freqStop = 2 * freq;
|
||||
} else if(freq + old_span / 2 >= VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq) {
|
||||
// would shift stop frequency above maximum
|
||||
settings.f_start = 2 * freq - Device::Info(window->getDevice()).limits_maxFreq;
|
||||
settings.f_stop = Device::Info(window->getDevice()).limits_maxFreq;
|
||||
settings.freqStart = 2 * freq - VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
|
||||
settings.freqStop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
|
||||
} else {
|
||||
settings.f_start = freq - old_span / 2;
|
||||
settings.f_stop = freq + old_span / 2;
|
||||
settings.freqStart = freq - old_span / 2;
|
||||
settings.freqStop = freq + old_span / 2;
|
||||
}
|
||||
ConstrainAndUpdateFrequencies();
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::SetSpan(double span)
|
||||
{
|
||||
auto old_center = (settings.f_start + settings.f_stop) / 2;
|
||||
if(old_center < Device::Info(window->getDevice()).limits_minFreq + span / 2) {
|
||||
auto old_center = (settings.freqStart + settings.freqStop) / 2;
|
||||
if(old_center < VirtualDevice::getInfo(window->getDevice()).Limits.minFreq + span / 2) {
|
||||
// would shift start frequency below minimum
|
||||
settings.f_start = Device::Info(window->getDevice()).limits_minFreq;
|
||||
settings.f_stop = Device::Info(window->getDevice()).limits_minFreq + span;
|
||||
} else if(old_center > Device::Info(window->getDevice()).limits_maxFreq - span / 2) {
|
||||
settings.freqStart = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
|
||||
settings.freqStop = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq + span;
|
||||
} else if(old_center > VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - span / 2) {
|
||||
// would shift stop frequency above maximum
|
||||
settings.f_start = Device::Info(window->getDevice()).limits_maxFreq - span;
|
||||
settings.f_stop = Device::Info(window->getDevice()).limits_maxFreq;
|
||||
settings.freqStart = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - span;
|
||||
settings.freqStop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
|
||||
} else {
|
||||
settings.f_start = old_center - span / 2;
|
||||
settings.f_stop = settings.f_start + span;
|
||||
settings.freqStart = old_center - span / 2;
|
||||
settings.freqStop = settings.freqStart + span;
|
||||
}
|
||||
ConstrainAndUpdateFrequencies();
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::SetFullSpan()
|
||||
{
|
||||
settings.f_start = Device::Info(window->getDevice()).limits_minFreq;
|
||||
settings.f_stop = Device::Info(window->getDevice()).limits_maxFreq;
|
||||
settings.freqStart = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
|
||||
settings.freqStop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
|
||||
ConstrainAndUpdateFrequencies();
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::SetZeroSpan()
|
||||
{
|
||||
auto center = (settings.f_start + settings.f_stop) / 2;
|
||||
auto center = (settings.freqStart + settings.freqStop) / 2;
|
||||
SetStartFreq(center);
|
||||
SetStopFreq(center);
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::SpanZoomIn()
|
||||
{
|
||||
auto center = (settings.f_start + settings.f_stop) / 2;
|
||||
auto old_span = settings.f_stop - settings.f_start;
|
||||
settings.f_start = center - old_span / 4;
|
||||
settings.f_stop = center + old_span / 4;
|
||||
auto center = (settings.freqStart + settings.freqStop) / 2;
|
||||
auto old_span = settings.freqStop - settings.freqStart;
|
||||
settings.freqStart = center - old_span / 4;
|
||||
settings.freqStop = center + old_span / 4;
|
||||
ConstrainAndUpdateFrequencies();
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::SpanZoomOut()
|
||||
{
|
||||
auto center = (settings.f_start + settings.f_stop) / 2;
|
||||
auto old_span = settings.f_stop - settings.f_start;
|
||||
auto center = (settings.freqStart + settings.freqStop) / 2;
|
||||
auto old_span = settings.freqStop - settings.freqStart;
|
||||
if(center > old_span) {
|
||||
settings.f_start = center - old_span;
|
||||
settings.freqStart = center - old_span;
|
||||
} else {
|
||||
settings.f_start = 0;
|
||||
settings.freqStart = 0;
|
||||
}
|
||||
settings.f_stop = center + old_span;
|
||||
settings.freqStop = center + old_span;
|
||||
ConstrainAndUpdateFrequencies();
|
||||
}
|
||||
|
||||
@ -683,26 +675,26 @@ void SpectrumAnalyzer::SetSingleSweep(bool single)
|
||||
|
||||
void SpectrumAnalyzer::SetRBW(double bandwidth)
|
||||
{
|
||||
if(bandwidth > Device::Info(window->getDevice()).limits_maxRBW) {
|
||||
bandwidth = Device::Info(window->getDevice()).limits_maxRBW;
|
||||
} else if(bandwidth < Device::Info(window->getDevice()).limits_minRBW) {
|
||||
bandwidth = Device::Info(window->getDevice()).limits_minRBW;
|
||||
if(bandwidth > VirtualDevice::getInfo(window->getDevice()).Limits.maxRBW) {
|
||||
bandwidth = VirtualDevice::getInfo(window->getDevice()).Limits.maxRBW;
|
||||
} else if(bandwidth < VirtualDevice::getInfo(window->getDevice()).Limits.minRBW) {
|
||||
bandwidth = VirtualDevice::getInfo(window->getDevice()).Limits.minRBW;
|
||||
}
|
||||
settings.RBW = bandwidth;
|
||||
emit RBWChanged(settings.RBW);
|
||||
SettingsChanged();
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::SetWindow(SpectrumAnalyzer::Window w)
|
||||
void SpectrumAnalyzer::SetWindow(VirtualDevice::SASettings::Window w)
|
||||
{
|
||||
settings.WindowType = (int) w;
|
||||
settings.window = w;
|
||||
cbWindowType->setCurrentIndex((int) w);
|
||||
SettingsChanged();
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::SetDetector(SpectrumAnalyzer::Detector d)
|
||||
void SpectrumAnalyzer::SetDetector(VirtualDevice::SASettings::Detector d)
|
||||
{
|
||||
settings.Detector = (int) d;
|
||||
settings.detector = d;
|
||||
cbDetector->setCurrentIndex((int) d);
|
||||
SettingsChanged();
|
||||
}
|
||||
@ -717,7 +709,7 @@ void SpectrumAnalyzer::SetAveraging(unsigned int averages)
|
||||
|
||||
void SpectrumAnalyzer::SetSignalID(bool enabled)
|
||||
{
|
||||
settings.SignalID = enabled ? 1 : 0;
|
||||
settings.signalID = enabled ? 1 : 0;
|
||||
cbSignalID->setChecked(enabled);
|
||||
SettingsChanged();
|
||||
}
|
||||
@ -743,8 +735,8 @@ void SpectrumAnalyzer::SetTGPort(int port)
|
||||
if(port < 0 || port > 1) {
|
||||
return;
|
||||
}
|
||||
if(port != settings.trackingGeneratorPort) {
|
||||
settings.trackingGeneratorPort = port;
|
||||
if(port != settings.trackingPort) {
|
||||
settings.trackingPort = port;
|
||||
emit TGPortChanged(port);
|
||||
if(settings.trackingGenerator) {
|
||||
SettingsChanged();
|
||||
@ -754,10 +746,10 @@ void SpectrumAnalyzer::SetTGPort(int port)
|
||||
|
||||
void SpectrumAnalyzer::SetTGLevel(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 / 100.0) {
|
||||
level = VirtualDevice::getInfo(window->getDevice()).Limits.maxdBm / 100.0;
|
||||
} else if(level < VirtualDevice::getInfo(window->getDevice()).Limits.mindBm / 100.0) {
|
||||
level = VirtualDevice::getInfo(window->getDevice()).Limits.mindBm / 100.0;
|
||||
}
|
||||
emit TGLevelChanged(level);
|
||||
settings.trackingPower = level * 100;
|
||||
@ -768,7 +760,7 @@ void SpectrumAnalyzer::SetTGLevel(double level)
|
||||
|
||||
void SpectrumAnalyzer::SetTGOffset(double offset)
|
||||
{
|
||||
settings.trackingGeneratorOffset = offset;
|
||||
settings.trackingOffset = offset;
|
||||
|
||||
ConstrainAndUpdateFrequencies();
|
||||
if(settings.trackingGenerator) {
|
||||
@ -778,9 +770,14 @@ void SpectrumAnalyzer::SetTGOffset(double offset)
|
||||
|
||||
void SpectrumAnalyzer::MeasureNormalization()
|
||||
{
|
||||
if(!window->getDevice()) {
|
||||
return;
|
||||
}
|
||||
normalize.active = false;
|
||||
normalize.port1Correction.clear();
|
||||
normalize.port2Correction.clear();
|
||||
normalize.portCorrection.clear();
|
||||
for(auto m : window->getDevice()->availableSAMeasurements()) {
|
||||
normalize.portCorrection[m] = {};
|
||||
}
|
||||
normalize.measuring = true;
|
||||
normalize.dialog.setLabelText("Taking normalization measurement...");
|
||||
normalize.dialog.setCancelButtonText("Abort");
|
||||
@ -807,7 +804,7 @@ void SpectrumAnalyzer::EnableNormalization(bool enabled)
|
||||
if(enabled != normalize.active) {
|
||||
if(enabled) {
|
||||
// check if measurements already taken
|
||||
if(normalize.f_start == settings.f_start && normalize.f_stop == settings.f_stop && normalize.points == settings.pointNum) {
|
||||
if(normalize.f_start == settings.freqStart && normalize.f_stop == settings.freqStop && normalize.points == settings.points) {
|
||||
// same settings as with normalization measurement, can enable
|
||||
normalize.active = true;
|
||||
} else {
|
||||
@ -843,7 +840,7 @@ void SpectrumAnalyzer::SetupSCPI()
|
||||
return SCPI::getResultName(SCPI::Result::Empty);
|
||||
}
|
||||
}, [=](QStringList) -> QString {
|
||||
return QString::number(settings.f_stop - settings.f_start, 'f', 0);
|
||||
return QString::number(settings.freqStop - settings.freqStart, 'f', 0);
|
||||
}));
|
||||
scpi_freq->add(new SCPICommand("START", [=](QStringList params) -> QString {
|
||||
unsigned long long newval;
|
||||
@ -854,7 +851,7 @@ void SpectrumAnalyzer::SetupSCPI()
|
||||
return SCPI::getResultName(SCPI::Result::Empty);
|
||||
}
|
||||
}, [=](QStringList) -> QString {
|
||||
return QString::number(settings.f_start, 'f', 0);
|
||||
return QString::number(settings.freqStart, 'f', 0);
|
||||
}));
|
||||
scpi_freq->add(new SCPICommand("CENTer", [=](QStringList params) -> QString {
|
||||
unsigned long long newval;
|
||||
@ -865,7 +862,7 @@ void SpectrumAnalyzer::SetupSCPI()
|
||||
return SCPI::getResultName(SCPI::Result::Empty);
|
||||
}
|
||||
}, [=](QStringList) -> QString {
|
||||
return QString::number((settings.f_start + settings.f_stop)/2, 'f', 0);
|
||||
return QString::number((settings.freqStart + settings.freqStop)/2, 'f', 0);
|
||||
}));
|
||||
scpi_freq->add(new SCPICommand("STOP", [=](QStringList params) -> QString {
|
||||
unsigned long long newval;
|
||||
@ -876,7 +873,7 @@ void SpectrumAnalyzer::SetupSCPI()
|
||||
return SCPI::getResultName(SCPI::Result::Empty);
|
||||
}
|
||||
}, [=](QStringList) -> QString {
|
||||
return QString::number(settings.f_stop, 'f', 0);
|
||||
return QString::number(settings.freqStop, 'f', 0);
|
||||
}));
|
||||
scpi_freq->add(new SCPICommand("FULL", [=](QStringList params) -> QString {
|
||||
Q_UNUSED(params)
|
||||
@ -906,23 +903,23 @@ void SpectrumAnalyzer::SetupSCPI()
|
||||
return SCPI::getResultName(SCPI::Result::Error);
|
||||
}
|
||||
if (params[0] == "NONE") {
|
||||
SetWindow(Window::None);
|
||||
SetWindow(VirtualDevice::SASettings::Window::None);
|
||||
} else if(params[0] == "KAISER") {
|
||||
SetWindow(Window::Kaiser);
|
||||
SetWindow(VirtualDevice::SASettings::Window::Kaiser);
|
||||
} else if(params[0] == "HANN") {
|
||||
SetWindow(Window::Hann);
|
||||
SetWindow(VirtualDevice::SASettings::Window::Hann);
|
||||
} else if(params[0] == "FLATTOP") {
|
||||
SetWindow(Window::FlatTop);
|
||||
SetWindow(VirtualDevice::SASettings::Window::FlatTop);
|
||||
} else {
|
||||
return "INVALID WINDOW";
|
||||
}
|
||||
return SCPI::getResultName(SCPI::Result::Empty);
|
||||
}, [=](QStringList) -> QString {
|
||||
switch((Window) settings.WindowType) {
|
||||
case Window::None: return "NONE";
|
||||
case Window::Kaiser: return "KAISER";
|
||||
case Window::Hann: return "HANN";
|
||||
case Window::FlatTop: return "FLATTOP";
|
||||
switch((VirtualDevice::SASettings::Window) settings.window) {
|
||||
case VirtualDevice::SASettings::Window::None: return "NONE";
|
||||
case VirtualDevice::SASettings::Window::Kaiser: return "KAISER";
|
||||
case VirtualDevice::SASettings::Window::Hann: return "HANN";
|
||||
case VirtualDevice::SASettings::Window::FlatTop: return "FLATTOP";
|
||||
default: return SCPI::getResultName(SCPI::Result::Error);
|
||||
}
|
||||
}));
|
||||
@ -931,26 +928,26 @@ void SpectrumAnalyzer::SetupSCPI()
|
||||
return SCPI::getResultName(SCPI::Result::Error);
|
||||
}
|
||||
if (params[0] == "+PEAK") {
|
||||
SetDetector(Detector::PPeak);
|
||||
SetDetector(VirtualDevice::SASettings::Detector::PPeak);
|
||||
} else if(params[0] == "-PEAK") {
|
||||
SetDetector(Detector::NPeak);
|
||||
SetDetector(VirtualDevice::SASettings::Detector::NPeak);
|
||||
} else if(params[0] == "NORMAL") {
|
||||
SetDetector(Detector::Normal);
|
||||
SetDetector(VirtualDevice::SASettings::Detector::Normal);
|
||||
} else if(params[0] == "SAMPLE") {
|
||||
SetDetector(Detector::Sample);
|
||||
SetDetector(VirtualDevice::SASettings::Detector::Sample);
|
||||
} else if(params[0] == "AVERAGE") {
|
||||
SetDetector(Detector::Average);
|
||||
SetDetector(VirtualDevice::SASettings::Detector::Average);
|
||||
} else {
|
||||
return "INVALID MDOE";
|
||||
}
|
||||
return SCPI::getResultName(SCPI::Result::Empty);
|
||||
}, [=](QStringList) -> QString {
|
||||
switch((Detector) settings.Detector) {
|
||||
case Detector::PPeak: return "+PEAK";
|
||||
case Detector::NPeak: return "-PEAK";
|
||||
case Detector::Normal: return "NORMAL";
|
||||
case Detector::Sample: return "SAMPLE";
|
||||
case Detector::Average: return "AVERAGE";
|
||||
switch((VirtualDevice::SASettings::Detector) settings.detector) {
|
||||
case VirtualDevice::SASettings::Detector::PPeak: return "+PEAK";
|
||||
case VirtualDevice::SASettings::Detector::NPeak: return "-PEAK";
|
||||
case VirtualDevice::SASettings::Detector::Normal: return "NORMAL";
|
||||
case VirtualDevice::SASettings::Detector::Sample: return "SAMPLE";
|
||||
case VirtualDevice::SASettings::Detector::Average: return "AVERAGE";
|
||||
default: return SCPI::getResultName(SCPI::Result::Error);
|
||||
}
|
||||
}));
|
||||
@ -987,7 +984,7 @@ void SpectrumAnalyzer::SetupSCPI()
|
||||
}
|
||||
return SCPI::getResultName(SCPI::Result::Empty);
|
||||
}, [=](QStringList) -> QString {
|
||||
return settings.SignalID ? SCPI::getResultName(SCPI::Result::True) : SCPI::getResultName(SCPI::Result::False);
|
||||
return settings.signalID ? SCPI::getResultName(SCPI::Result::True) : SCPI::getResultName(SCPI::Result::False);
|
||||
}));
|
||||
scpi_acq->add(new SCPICommand("SINGLE", [=](QStringList params) -> QString {
|
||||
bool single;
|
||||
@ -1030,7 +1027,7 @@ void SpectrumAnalyzer::SetupSCPI()
|
||||
}
|
||||
return SCPI::getResultName(SCPI::Result::Empty);
|
||||
}, [=](QStringList) -> QString {
|
||||
return settings.trackingGeneratorPort ? "2" : "1";
|
||||
return QString::number(settings.trackingPort);
|
||||
}));
|
||||
scpi_tg->add(new SCPICommand("LVL", [=](QStringList params) -> QString {
|
||||
double newval;
|
||||
@ -1053,7 +1050,7 @@ void SpectrumAnalyzer::SetupSCPI()
|
||||
return SCPI::getResultName(SCPI::Result::Empty);
|
||||
}
|
||||
}, [=](QStringList) -> QString {
|
||||
return QString::number(settings.trackingGeneratorOffset);
|
||||
return QString::number(settings.trackingOffset);
|
||||
}));
|
||||
auto scpi_norm = new SCPINode("NORMalize");
|
||||
scpi_tg->add(scpi_norm);
|
||||
@ -1098,34 +1095,34 @@ void SpectrumAnalyzer::UpdateAverageCount()
|
||||
|
||||
void SpectrumAnalyzer::ConstrainAndUpdateFrequencies()
|
||||
{
|
||||
if(settings.f_stop > Device::Info(window->getDevice()).limits_maxFreq) {
|
||||
settings.f_stop = Device::Info(window->getDevice()).limits_maxFreq;
|
||||
if(settings.freqStop > VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq) {
|
||||
settings.freqStop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
|
||||
}
|
||||
if(settings.f_start > settings.f_stop) {
|
||||
settings.f_start = settings.f_stop;
|
||||
if(settings.freqStart > settings.freqStop) {
|
||||
settings.freqStart = settings.freqStop;
|
||||
}
|
||||
if(settings.f_start < Device::Info(window->getDevice()).limits_minFreq) {
|
||||
settings.f_start = Device::Info(window->getDevice()).limits_minFreq;
|
||||
if(settings.freqStart < VirtualDevice::getInfo(window->getDevice()).Limits.minFreq) {
|
||||
settings.freqStart = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
|
||||
}
|
||||
|
||||
bool trackingOffset_limited = false;
|
||||
if(settings.f_stop + settings.trackingGeneratorOffset > Device::Info(window->getDevice()).limits_maxFreq) {
|
||||
if(settings.freqStop + settings.trackingOffset > VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq) {
|
||||
trackingOffset_limited = true;
|
||||
settings.trackingGeneratorOffset = Device::Info(window->getDevice()).limits_maxFreq - settings.f_stop;
|
||||
settings.trackingOffset = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - settings.freqStop;
|
||||
}
|
||||
if(settings.f_start + settings.trackingGeneratorOffset < Device::Info(window->getDevice()).limits_minFreq) {
|
||||
if(settings.freqStart + settings.trackingOffset < VirtualDevice::getInfo(window->getDevice()).Limits.minFreq) {
|
||||
trackingOffset_limited = true;
|
||||
settings.trackingGeneratorOffset = Device::Info(window->getDevice()).limits_minFreq - settings.f_start;
|
||||
settings.trackingOffset = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq - settings.freqStart;
|
||||
}
|
||||
if(trackingOffset_limited) {
|
||||
InformationBox::ShowMessage("Warning", "The selected tracking generator offset is not reachable for all frequencies with the current span. "
|
||||
"The tracking generator offset has been constrained according to the selected start and stop frequencies");
|
||||
}
|
||||
emit startFreqChanged(settings.f_start);
|
||||
emit stopFreqChanged(settings.f_stop);
|
||||
emit spanChanged(settings.f_stop - settings.f_start);
|
||||
emit centerFreqChanged((settings.f_stop + settings.f_start)/2);
|
||||
emit TGOffsetChanged(settings.trackingGeneratorOffset);
|
||||
emit startFreqChanged(settings.freqStart);
|
||||
emit stopFreqChanged(settings.freqStop);
|
||||
emit spanChanged(settings.freqStop - settings.freqStart);
|
||||
emit centerFreqChanged((settings.freqStop + settings.freqStart)/2);
|
||||
emit TGOffsetChanged(settings.trackingOffset);
|
||||
SettingsChanged();
|
||||
}
|
||||
|
||||
@ -1133,13 +1130,13 @@ void SpectrumAnalyzer::LoadSweepSettings()
|
||||
{
|
||||
QSettings s;
|
||||
auto pref = Preferences::getInstance();
|
||||
settings.f_start = s.value("SAStart", pref.Startup.SA.start).toULongLong();
|
||||
settings.f_stop = s.value("SAStop", pref.Startup.SA.stop).toULongLong();
|
||||
settings.freqStart = s.value("SAStart", pref.Startup.SA.start).toULongLong();
|
||||
settings.freqStop = s.value("SAStop", pref.Startup.SA.stop).toULongLong();
|
||||
ConstrainAndUpdateFrequencies();
|
||||
SetRBW(s.value("SARBW", pref.Startup.SA.RBW).toUInt());
|
||||
settings.pointNum = 1001;
|
||||
SetWindow((Window) s.value("SAWindow", pref.Startup.SA.window).toInt());
|
||||
SetDetector((Detector) s.value("SADetector", pref.Startup.SA.detector).toInt());
|
||||
settings.points = 1001;
|
||||
SetWindow((VirtualDevice::SASettings::Window) s.value("SAWindow", pref.Startup.SA.window).toInt());
|
||||
SetDetector((VirtualDevice::SASettings::Detector) s.value("SADetector", pref.Startup.SA.detector).toInt());
|
||||
SetSignalID(s.value("SASignalID", pref.Startup.SA.signalID).toBool());
|
||||
SetAveraging(s.value("SAAveraging", pref.Startup.SA.averaging).toInt());
|
||||
}
|
||||
@ -1147,13 +1144,13 @@ void SpectrumAnalyzer::LoadSweepSettings()
|
||||
void SpectrumAnalyzer::StoreSweepSettings()
|
||||
{
|
||||
QSettings s;
|
||||
s.setValue("SAStart", static_cast<unsigned long long>(settings.f_start));
|
||||
s.setValue("SAStop", static_cast<unsigned long long>(settings.f_stop));
|
||||
s.setValue("SAStart", static_cast<unsigned long long>(settings.freqStart));
|
||||
s.setValue("SAStop", static_cast<unsigned long long>(settings.freqStop));
|
||||
s.setValue("SARBW", settings.RBW);
|
||||
s.setValue("SAWindow", settings.WindowType);
|
||||
s.setValue("SADetector", settings.Detector);
|
||||
s.setValue("SAWindow", (int) settings.window);
|
||||
s.setValue("SADetector", (int) settings.detector);
|
||||
s.setValue("SAAveraging", averages);
|
||||
s.setValue("SASignalID", static_cast<bool>(settings.SignalID));
|
||||
s.setValue("SASignalID", static_cast<bool>(settings.signalID));
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::setAveragingMode(Averaging::Mode mode)
|
||||
@ -1161,47 +1158,47 @@ void SpectrumAnalyzer::setAveragingMode(Averaging::Mode mode)
|
||||
average.setMode(mode);
|
||||
}
|
||||
|
||||
QString SpectrumAnalyzer::WindowToString(SpectrumAnalyzer::Window w)
|
||||
QString SpectrumAnalyzer::WindowToString(VirtualDevice::SASettings::Window w)
|
||||
{
|
||||
switch(w) {
|
||||
case Window::None: return "None";
|
||||
case Window::Kaiser: return "Kaiser";
|
||||
case Window::Hann: return "Hann";
|
||||
case Window::FlatTop: return "FlatTop";
|
||||
case VirtualDevice::SASettings::Window::None: return "None";
|
||||
case VirtualDevice::SASettings::Window::Kaiser: return "Kaiser";
|
||||
case VirtualDevice::SASettings::Window::Hann: return "Hann";
|
||||
case VirtualDevice::SASettings::Window::FlatTop: return "FlatTop";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
SpectrumAnalyzer::Window SpectrumAnalyzer::WindowFromString(QString s)
|
||||
VirtualDevice::SASettings::Window SpectrumAnalyzer::WindowFromString(QString s)
|
||||
{
|
||||
for(int i=0;i<(int)Window::Last;i++) {
|
||||
if(WindowToString((Window) i) == s) {
|
||||
return (Window) i;
|
||||
for(int i=0;i<(int)VirtualDevice::SASettings::Window::Last;i++) {
|
||||
if(WindowToString((VirtualDevice::SASettings::Window) i) == s) {
|
||||
return (VirtualDevice::SASettings::Window) i;
|
||||
}
|
||||
}
|
||||
// not found
|
||||
return Window::Last;
|
||||
return VirtualDevice::SASettings::Window::Last;
|
||||
}
|
||||
|
||||
QString SpectrumAnalyzer::DetectorToString(SpectrumAnalyzer::Detector d)
|
||||
QString SpectrumAnalyzer::DetectorToString(VirtualDevice::SASettings::Detector d)
|
||||
{
|
||||
switch(d) {
|
||||
case Detector::PPeak: return "+Peak";
|
||||
case Detector::NPeak: return "-Peak";
|
||||
case Detector::Sample: return "Sample";
|
||||
case Detector::Normal: return "Normal";
|
||||
case Detector::Average: return "Average";
|
||||
case VirtualDevice::SASettings::Detector::PPeak: return "+Peak";
|
||||
case VirtualDevice::SASettings::Detector::NPeak: return "-Peak";
|
||||
case VirtualDevice::SASettings::Detector::Sample: return "Sample";
|
||||
case VirtualDevice::SASettings::Detector::Normal: return "Normal";
|
||||
case VirtualDevice::SASettings::Detector::Average: return "Average";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
SpectrumAnalyzer::Detector SpectrumAnalyzer::DetectorFromString(QString s)
|
||||
VirtualDevice::SASettings::Detector SpectrumAnalyzer::DetectorFromString(QString s)
|
||||
{
|
||||
for(int i=0;i<(int)Detector::Last;i++) {
|
||||
if(DetectorToString((Detector) i) == s) {
|
||||
return (Detector) i;
|
||||
for(int i=0;i<(int)VirtualDevice::SASettings::Detector::Last;i++) {
|
||||
if(DetectorToString((VirtualDevice::SASettings::Detector) i) == s) {
|
||||
return (VirtualDevice::SASettings::Detector) i;
|
||||
}
|
||||
}
|
||||
// not found
|
||||
return Detector::Last;
|
||||
return VirtualDevice::SASettings::Detector::Last;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "CustomWidgets/tilewidget.h"
|
||||
#include "scpi.h"
|
||||
#include "Traces/tracewidget.h"
|
||||
#include "Device/virtualdevice.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
@ -32,29 +33,13 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
enum class Window {
|
||||
None = 0,
|
||||
Kaiser = 1,
|
||||
Hann = 2,
|
||||
FlatTop = 3,
|
||||
Last
|
||||
};
|
||||
enum class Detector {
|
||||
PPeak = 0,
|
||||
NPeak = 1,
|
||||
Sample = 2,
|
||||
Normal = 3,
|
||||
Average = 4,
|
||||
Last
|
||||
};
|
||||
|
||||
static QString WindowToString(Window w);
|
||||
static Window WindowFromString(QString s);
|
||||
static QString DetectorToString(Detector d);
|
||||
static Detector DetectorFromString(QString s);
|
||||
static QString WindowToString(VirtualDevice::SASettings::Window w);
|
||||
static VirtualDevice::SASettings::Window WindowFromString(QString s);
|
||||
static QString DetectorToString(VirtualDevice::SASettings::Detector d);
|
||||
static VirtualDevice::SASettings::Detector DetectorFromString(QString s);
|
||||
|
||||
private slots:
|
||||
void NewDatapoint(Protocol::SpectrumAnalyzerResult d);
|
||||
void NewDatapoint(const VirtualDevice::SAMeasurement &m);
|
||||
// Sweep control
|
||||
void SetStartFreq(double freq);
|
||||
void SetStopFreq(double freq);
|
||||
@ -67,8 +52,8 @@ private slots:
|
||||
void SetSingleSweep(bool single);
|
||||
// Acquisition control
|
||||
void SetRBW(double bandwidth);
|
||||
void SetWindow(Window w);
|
||||
void SetDetector(Detector d);
|
||||
void SetWindow(VirtualDevice::SASettings::Window w);
|
||||
void SetDetector(VirtualDevice::SASettings::Detector d);
|
||||
void SetAveraging(unsigned int averages);
|
||||
void SetSignalID(bool enabled);
|
||||
// TG control
|
||||
@ -89,7 +74,7 @@ private:
|
||||
void LoadSweepSettings();
|
||||
void StoreSweepSettings();
|
||||
|
||||
Protocol::SpectrumAnalyzerSettings settings;
|
||||
VirtualDevice::SASettings settings;
|
||||
bool changingSettings;
|
||||
unsigned int averages;
|
||||
bool singleSweep;
|
||||
@ -110,8 +95,7 @@ private:
|
||||
// settings when normalize was measured
|
||||
double f_start, f_stop, points;
|
||||
// correction values to get the ports to 0dBm
|
||||
std::vector<double> port1Correction;
|
||||
std::vector<double> port2Correction;
|
||||
std::map<QString, std::vector<double>> portCorrection;
|
||||
// level to normalize to (additional correction factor)
|
||||
SIUnitEdit *Level;
|
||||
|
||||
|
@ -68,99 +68,6 @@ static const QString APP_GIT_HASH = QString(GITHASH);
|
||||
|
||||
static bool noGUIset = false;
|
||||
|
||||
|
||||
class Reference
|
||||
{
|
||||
public:
|
||||
|
||||
enum class TypeIn {
|
||||
Internal,
|
||||
External,
|
||||
Auto,
|
||||
None
|
||||
};
|
||||
|
||||
enum class OutFreq {
|
||||
MHZ10,
|
||||
MHZ100,
|
||||
Off,
|
||||
None
|
||||
};
|
||||
|
||||
static QString OutFreqToLabel(Reference::OutFreq t)
|
||||
{
|
||||
switch(t) {
|
||||
case OutFreq::MHZ10: return "10 MHz";
|
||||
case OutFreq::MHZ100: return "100 MHz";
|
||||
case OutFreq::Off: return "Off";
|
||||
default: return "Invalid";
|
||||
}
|
||||
}
|
||||
|
||||
static QString OutFreqToKey(Reference::OutFreq f)
|
||||
{
|
||||
switch(f) {
|
||||
case OutFreq::MHZ10: return "10 MHz";
|
||||
case OutFreq::MHZ100: return "100 MHz";
|
||||
case OutFreq::Off: return "Off";
|
||||
default: return "Invalid";
|
||||
}
|
||||
}
|
||||
|
||||
static Reference::OutFreq KeyToOutFreq(QString key)
|
||||
{
|
||||
for (auto r: Reference::getOutFrequencies()) {
|
||||
if(OutFreqToKey((Reference::OutFreq) r) == key) {
|
||||
return (Reference::OutFreq) r;
|
||||
}
|
||||
}
|
||||
// not found
|
||||
return Reference::OutFreq::None;
|
||||
}
|
||||
|
||||
|
||||
static QString TypeToLabel(TypeIn t)
|
||||
{
|
||||
switch(t) {
|
||||
case TypeIn::Internal: return "Internal";
|
||||
case TypeIn::External: return "External";
|
||||
case TypeIn::Auto: return "Auto";
|
||||
default: return "Invalid";
|
||||
}
|
||||
}
|
||||
|
||||
static const QString TypeToKey(TypeIn t)
|
||||
{
|
||||
switch(t) {
|
||||
case TypeIn::Internal: return "Int";
|
||||
case TypeIn::External: return "Ext";
|
||||
case TypeIn::Auto: return "Auto";
|
||||
default: return "Invalid";
|
||||
}
|
||||
}
|
||||
|
||||
static TypeIn KeyToType(QString key)
|
||||
{
|
||||
for (auto r: Reference::getReferencesIn()) {
|
||||
if(TypeToKey((TypeIn) r) == key) {
|
||||
return (TypeIn) r;
|
||||
}
|
||||
}
|
||||
// not found
|
||||
return TypeIn::None;
|
||||
}
|
||||
|
||||
static std::vector<Reference::TypeIn> getReferencesIn()
|
||||
{
|
||||
return {TypeIn::Internal, TypeIn::External, TypeIn::Auto};
|
||||
}
|
||||
|
||||
static std::vector<Reference::OutFreq> getOutFrequencies()
|
||||
{
|
||||
return {OutFreq::Off, OutFreq::MHZ10, OutFreq::MHZ100};
|
||||
}
|
||||
};
|
||||
|
||||
AppWindow::AppWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, deviceActionGroup(new QActionGroup(this))
|
||||
@ -193,7 +100,7 @@ AppWindow::AppWindow(QWidget *parent)
|
||||
} else {
|
||||
Preferences::getInstance().load();
|
||||
}
|
||||
device = nullptr;
|
||||
vdevice = nullptr;
|
||||
modeHandler = nullptr;
|
||||
|
||||
if(parser.isSet("port")) {
|
||||
@ -370,7 +277,7 @@ void AppWindow::SetupMenu()
|
||||
{
|
||||
active->updateGraphColors();
|
||||
|
||||
if(device) {
|
||||
if(vdevice) {
|
||||
active->initializeDevice();
|
||||
}
|
||||
}
|
||||
@ -396,7 +303,7 @@ void AppWindow::closeEvent(QCloseEvent *event)
|
||||
if(modeHandler->getActiveMode()) {
|
||||
modeHandler->deactivate(modeHandler->getActiveMode());
|
||||
}
|
||||
delete device;
|
||||
delete vdevice;
|
||||
delete modeHandler;
|
||||
modeHandler = nullptr;
|
||||
pref.store();
|
||||
@ -410,33 +317,36 @@ bool AppWindow::ConnectToDevice(QString serial)
|
||||
} else {
|
||||
qDebug() << "Trying to connect to" << serial;
|
||||
}
|
||||
if(device) {
|
||||
if(vdevice) {
|
||||
qDebug() << "Already connected to a device, disconnecting first...";
|
||||
DisconnectDevice();
|
||||
}
|
||||
try {
|
||||
qDebug() << "Attempting to connect to device...";
|
||||
device = new Device(serial);
|
||||
vdevice = new VirtualDevice(serial);
|
||||
UpdateStatusBar(AppWindow::DeviceStatusBar::Connected);
|
||||
connect(device, &Device::LogLineReceived, &deviceLog, &DeviceLog::addLine);
|
||||
connect(device, &Device::ConnectionLost, this, &AppWindow::DeviceConnectionLost);
|
||||
connect(device, &Device::DeviceStatusUpdated, this, &AppWindow::DeviceStatusUpdated);
|
||||
connect(device, &Device::NeedsFirmwareUpdate, this, &AppWindow::DeviceNeedsUpdate);
|
||||
connect(vdevice, &VirtualDevice::LogLineReceived, &deviceLog, &DeviceLog::addLine);
|
||||
connect(vdevice, &VirtualDevice::ConnectionLost, this, &AppWindow::DeviceConnectionLost);
|
||||
connect(vdevice, &VirtualDevice::StatusUpdated, this, &AppWindow::DeviceStatusUpdated);
|
||||
connect(vdevice, &VirtualDevice::NeedsFirmwareUpdate, this, &AppWindow::DeviceNeedsUpdate);
|
||||
ui->actionDisconnect->setEnabled(true);
|
||||
ui->actionManual_Control->setEnabled(true);
|
||||
ui->actionFirmware_Update->setEnabled(true);
|
||||
ui->actionSource_Calibration->setEnabled(true);
|
||||
ui->actionReceiver_Calibration->setEnabled(true);
|
||||
ui->actionFrequency_Calibration->setEnabled(true);
|
||||
if(!vdevice->isCompoundDevice()) {
|
||||
ui->actionManual_Control->setEnabled(true);
|
||||
ui->actionFirmware_Update->setEnabled(true);
|
||||
ui->actionSource_Calibration->setEnabled(true);
|
||||
ui->actionReceiver_Calibration->setEnabled(true);
|
||||
ui->actionFrequency_Calibration->setEnabled(true);
|
||||
}
|
||||
|
||||
UpdateAcquisitionFrequencies();
|
||||
if (modeHandler->getActiveMode()) {
|
||||
modeHandler->getActiveMode()->initializeDevice();
|
||||
}
|
||||
UpdateReferenceToolbar();
|
||||
UpdateReference();
|
||||
|
||||
for(auto d : deviceActionGroup->actions()) {
|
||||
if(d->text() == device->serial()) {
|
||||
if(d->text() == vdevice->serial()) {
|
||||
d->blockSignals(true);
|
||||
d->setChecked(true);
|
||||
d->blockSignals(false);
|
||||
@ -454,8 +364,8 @@ bool AppWindow::ConnectToDevice(QString serial)
|
||||
|
||||
void AppWindow::DisconnectDevice()
|
||||
{
|
||||
delete device;
|
||||
device = nullptr;
|
||||
delete vdevice;
|
||||
vdevice = nullptr;
|
||||
ui->actionDisconnect->setEnabled(false);
|
||||
ui->actionManual_Control->setEnabled(false);
|
||||
ui->actionFirmware_Update->setEnabled(false);
|
||||
@ -488,17 +398,10 @@ void AppWindow::CreateToolbars()
|
||||
auto tb_reference = new QToolBar("Reference", this);
|
||||
tb_reference->addWidget(new QLabel("Ref in:"));
|
||||
toolbars.reference.type = new QComboBox();
|
||||
for (auto r: Reference::getReferencesIn()) {
|
||||
toolbars.reference.type->addItem(Reference::TypeToLabel(r), (int)r);
|
||||
}
|
||||
tb_reference->addWidget(toolbars.reference.type);
|
||||
tb_reference->addSeparator();
|
||||
tb_reference->addWidget(new QLabel("Ref out:"));
|
||||
toolbars.reference.outFreq = new QComboBox();
|
||||
for (auto f: Reference::getOutFrequencies()) {
|
||||
|
||||
toolbars.reference.outFreq->addItem(Reference::OutFreqToLabel(f), (int)f);
|
||||
}
|
||||
tb_reference->addWidget(toolbars.reference.outFreq);
|
||||
connect(toolbars.reference.type, qOverload<int>(&QComboBox::currentIndexChanged), this, &AppWindow::UpdateReference);
|
||||
connect(toolbars.reference.outFreq, qOverload<int>(&QComboBox::currentIndexChanged), this, &AppWindow::UpdateReference);
|
||||
@ -529,8 +432,8 @@ void AppWindow::SetupSCPI()
|
||||
return SCPI::getResultName(SCPI::Result::Empty);
|
||||
}
|
||||
}, [=](QStringList) -> QString {
|
||||
if(device) {
|
||||
return device->serial();
|
||||
if(vdevice) {
|
||||
return vdevice->serial();
|
||||
} else {
|
||||
return "Not connected";
|
||||
}
|
||||
@ -629,57 +532,64 @@ void AppWindow::SetupSCPI()
|
||||
auto scpi_status = new SCPINode("STAtus");
|
||||
scpi_dev->add(scpi_status);
|
||||
scpi_status->add(new SCPICommand("UNLOcked", nullptr, [=](QStringList){
|
||||
bool locked = Device::StatusV1(getDevice()).source_locked && Device::StatusV1(getDevice()).LO1_locked;
|
||||
return locked ? "FALSE" : "TRUE";
|
||||
return VirtualDevice::getStatus(getDevice()).unlocked ? "TRUE" : "FALSE";
|
||||
}));
|
||||
scpi_status->add(new SCPICommand("ADCOVERload", nullptr, [=](QStringList){
|
||||
return Device::StatusV1(getDevice()).ADC_overload ? "TRUE" : "FALSE";
|
||||
return VirtualDevice::getStatus(getDevice()).overload ? "TRUE" : "FALSE";
|
||||
}));
|
||||
scpi_status->add(new SCPICommand("UNLEVel", nullptr, [=](QStringList){
|
||||
return Device::StatusV1(getDevice()).unlevel ? "TRUE" : "FALSE";
|
||||
return VirtualDevice::getStatus(getDevice()).unlevel ? "TRUE" : "FALSE";
|
||||
}));
|
||||
auto scpi_info = new SCPINode("INFo");
|
||||
scpi_dev->add(scpi_info);
|
||||
scpi_info->add(new SCPICommand("FWREVision", nullptr, [=](QStringList){
|
||||
return QString::number(Device::Info(getDevice()).FW_major)+"."+QString::number(Device::Info(getDevice()).FW_minor)+"."+QString::number(Device::Info(getDevice()).FW_patch);
|
||||
return QString::number(VirtualDevice::getInfo(getDevice()).FW_major)+"."+QString::number(VirtualDevice::getInfo(getDevice()).FW_minor)+"."+QString::number(VirtualDevice::getInfo(getDevice()).FW_patch);
|
||||
}));
|
||||
scpi_info->add(new SCPICommand("HWREVision", nullptr, [=](QStringList){
|
||||
return QString(Device::Info(getDevice()).HW_Revision);
|
||||
return QString(VirtualDevice::getInfo(getDevice()).HW_Revision);
|
||||
}));
|
||||
scpi_info->add(new SCPICommand("TEMPeratures", nullptr, [=](QStringList){
|
||||
return QString::number(Device::StatusV1(getDevice()).temp_source)+"/"+QString::number(Device::StatusV1(getDevice()).temp_LO1)+"/"+QString::number(Device::StatusV1(getDevice()).temp_MCU);
|
||||
if(!vdevice) {
|
||||
return QString("0/0/0");
|
||||
} else if(vdevice->isCompoundDevice()) {
|
||||
// TODO
|
||||
return QString();
|
||||
} else {
|
||||
auto dev = vdevice->getDevice();
|
||||
return QString::number(dev->StatusV1().temp_source)+"/"+QString::number(dev->StatusV1().temp_LO1)+"/"+QString::number(dev->StatusV1().temp_MCU);
|
||||
}
|
||||
}));
|
||||
auto scpi_limits = new SCPINode("LIMits");
|
||||
scpi_info->add(scpi_limits);
|
||||
scpi_limits->add(new SCPICommand("MINFrequency", nullptr, [=](QStringList){
|
||||
return QString::number(Device::Info(getDevice()).limits_minFreq);
|
||||
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.minFreq);
|
||||
}));
|
||||
scpi_limits->add(new SCPICommand("MAXFrequency", nullptr, [=](QStringList){
|
||||
return QString::number(Device::Info(getDevice()).limits_maxFreq);
|
||||
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.maxFreq);
|
||||
}));
|
||||
scpi_limits->add(new SCPICommand("MINIFBW", nullptr, [=](QStringList){
|
||||
return QString::number(Device::Info(getDevice()).limits_minIFBW);
|
||||
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.minIFBW);
|
||||
}));
|
||||
scpi_limits->add(new SCPICommand("MAXIFBW", nullptr, [=](QStringList){
|
||||
return QString::number(Device::Info(getDevice()).limits_maxIFBW);
|
||||
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.maxIFBW);
|
||||
}));
|
||||
scpi_limits->add(new SCPICommand("MAXPoints", nullptr, [=](QStringList){
|
||||
return QString::number(Device::Info(getDevice()).limits_maxPoints);
|
||||
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.maxPoints);
|
||||
}));
|
||||
scpi_limits->add(new SCPICommand("MINPOWer", nullptr, [=](QStringList){
|
||||
return QString::number(Device::Info(getDevice()).limits_cdbm_min / 100.0);
|
||||
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.mindBm);
|
||||
}));
|
||||
scpi_limits->add(new SCPICommand("MAXPOWer", nullptr, [=](QStringList){
|
||||
return QString::number(Device::Info(getDevice()).limits_cdbm_max / 100.0);
|
||||
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.maxdBm);
|
||||
}));
|
||||
scpi_limits->add(new SCPICommand("MINRBW", nullptr, [=](QStringList){
|
||||
return QString::number(Device::Info(getDevice()).limits_minRBW);
|
||||
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.minRBW);
|
||||
}));
|
||||
scpi_limits->add(new SCPICommand("MAXRBW", nullptr, [=](QStringList){
|
||||
return QString::number(Device::Info(getDevice()).limits_maxRBW);
|
||||
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.maxRBW);
|
||||
}));
|
||||
scpi_limits->add(new SCPICommand("MAXHARMonicfrequency", nullptr, [=](QStringList){
|
||||
return QString::number(Device::Info(getDevice()).limits_maxFreqHarmonic);
|
||||
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.maxFreqHarmonic);
|
||||
}));
|
||||
|
||||
auto scpi_manual = new SCPINode("MANual");
|
||||
@ -938,8 +848,8 @@ int AppWindow::UpdateDeviceList()
|
||||
deviceActionGroup->setExclusive(true);
|
||||
ui->menuConnect_to->clear();
|
||||
auto devices = Device::GetDevices();
|
||||
if(device) {
|
||||
devices.insert(device->serial());
|
||||
if(vdevice) {
|
||||
devices.insert(vdevice->serial());
|
||||
}
|
||||
int available = 0;
|
||||
bool found = false;
|
||||
@ -952,7 +862,7 @@ int AppWindow::UpdateDeviceList()
|
||||
auto connectAction = ui->menuConnect_to->addAction(d);
|
||||
connectAction->setCheckable(true);
|
||||
connectAction->setActionGroup(deviceActionGroup);
|
||||
if(device && d == device->serial()) {
|
||||
if(vdevice && d == vdevice->serial()) {
|
||||
connectAction->setChecked(true);
|
||||
}
|
||||
connect(connectAction, &QAction::triggered, [this, d]() {
|
||||
@ -969,14 +879,17 @@ int AppWindow::UpdateDeviceList()
|
||||
|
||||
void AppWindow::StartManualControl()
|
||||
{
|
||||
if(!vdevice || vdevice->isCompoundDevice()) {
|
||||
return;
|
||||
}
|
||||
if(manual) {
|
||||
// dialog already active, nothing to do
|
||||
return;
|
||||
}
|
||||
manual = new ManualControlDialog(*device, this);
|
||||
manual = new ManualControlDialog(*vdevice->getDevice(), this);
|
||||
connect(manual, &QDialog::finished, [=](){
|
||||
manual = nullptr;
|
||||
if(device) {
|
||||
if(vdevice) {
|
||||
modeHandler->getActiveMode()->initializeDevice();
|
||||
}
|
||||
});
|
||||
@ -985,37 +898,48 @@ void AppWindow::StartManualControl()
|
||||
}
|
||||
}
|
||||
|
||||
void AppWindow::UpdateReferenceToolbar()
|
||||
{
|
||||
if(!vdevice || !vdevice->getInfo().supportsExtRef) {
|
||||
toolbars.reference.type->setEnabled(false);
|
||||
toolbars.reference.outFreq->setEnabled(false);
|
||||
}
|
||||
// save current setting
|
||||
auto refInBuf = toolbars.reference.type->currentText();
|
||||
auto refOutBuf = toolbars.reference.outFreq->currentText();
|
||||
toolbars.reference.type->clear();
|
||||
for(auto in : vdevice->availableExtRefInSettings()) {
|
||||
toolbars.reference.type->addItem(in);
|
||||
}
|
||||
toolbars.reference.outFreq->clear();
|
||||
for(auto out : vdevice->availableExtRefOutSettings()) {
|
||||
toolbars.reference.outFreq->addItem(in);
|
||||
}
|
||||
// restore previous setting if still available
|
||||
if(toolbars.reference.type->findText(refInBuf) >= 0) {
|
||||
toolbars.reference.type->setCurrentText(refInBuf);
|
||||
} else {
|
||||
toolbars.reference.type->setCurrentIndex(0);
|
||||
}
|
||||
if(toolbars.reference.outFreq->findText(refOutBuf) >= 0) {
|
||||
toolbars.reference.outFreq->setCurrentText(refOutBuf);
|
||||
} else {
|
||||
toolbars.reference.outFreq->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
void AppWindow::UpdateReference()
|
||||
{
|
||||
if(!device) {
|
||||
if(!vdevice) {
|
||||
// can't update without a device connected
|
||||
return;
|
||||
}
|
||||
Protocol::ReferenceSettings s = {};
|
||||
|
||||
Reference::TypeIn t = static_cast<Reference::TypeIn>(toolbars.reference.type->currentData().toInt());
|
||||
switch (t) {
|
||||
case Reference::TypeIn::External: s.UseExternalRef = 1; break;
|
||||
case Reference::TypeIn::Auto: s.AutomaticSwitch = 1; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
Reference::OutFreq f = static_cast<Reference::OutFreq>(toolbars.reference.outFreq->currentData().toInt());
|
||||
switch(f) {
|
||||
case Reference::OutFreq::MHZ10: s.ExtRefOuputFreq = 10000000; break;
|
||||
case Reference::OutFreq::MHZ100: s.ExtRefOuputFreq = 100000000; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
Protocol::PacketInfo p;
|
||||
p.type = Protocol::PacketType::Reference;
|
||||
p.reference = s;
|
||||
device->SendPacket(p);
|
||||
vdevice->setExtRef(toolbars.reference.type->currentText(), toolbars.reference.outFreq->currentText());
|
||||
}
|
||||
|
||||
void AppWindow::UpdateAcquisitionFrequencies()
|
||||
{
|
||||
if(!device) {
|
||||
if(!vdevice) {
|
||||
return;
|
||||
}
|
||||
Protocol::PacketInfo p;
|
||||
@ -1024,18 +948,21 @@ void AppWindow::UpdateAcquisitionFrequencies()
|
||||
p.acquisitionFrequencySettings.IF1 = pref.Acquisition.IF1;
|
||||
p.acquisitionFrequencySettings.ADCprescaler = pref.Acquisition.ADCprescaler;
|
||||
p.acquisitionFrequencySettings.DFTphaseInc = pref.Acquisition.DFTPhaseInc;
|
||||
device->SendPacket(p);
|
||||
for(auto dev : vdevice->getDevices()) {
|
||||
dev->SendPacket(p);
|
||||
}
|
||||
}
|
||||
|
||||
void AppWindow::StartFirmwareUpdateDialog()
|
||||
{
|
||||
if(device) {
|
||||
auto fw_update = new FirmwareUpdateDialog(device);
|
||||
connect(fw_update, &FirmwareUpdateDialog::DeviceRebooting, this, &AppWindow::DisconnectDevice);
|
||||
connect(fw_update, &FirmwareUpdateDialog::DeviceRebooted, this, &AppWindow::ConnectToDevice);
|
||||
if(AppWindow::showGUI()) {
|
||||
fw_update->exec();
|
||||
}
|
||||
if(!vdevice || vdevice->isCompoundDevice()) {
|
||||
return;
|
||||
}
|
||||
auto fw_update = new FirmwareUpdateDialog(vdevice->getDevice());
|
||||
connect(fw_update, &FirmwareUpdateDialog::DeviceRebooting, this, &AppWindow::DisconnectDevice);
|
||||
connect(fw_update, &FirmwareUpdateDialog::DeviceRebooted, this, &AppWindow::ConnectToDevice);
|
||||
if(AppWindow::showGUI()) {
|
||||
fw_update->exec();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1046,18 +973,29 @@ void AppWindow::DeviceNeedsUpdate(int reported, int expected)
|
||||
"version (" + QString::number(reported) + ") than expected (" + QString::number(expected) + ").\n"
|
||||
"A firmware update is strongly recommended. Do you want to update now?", false);
|
||||
if (ret) {
|
||||
if (vdevice->isCompoundDevice()) {
|
||||
InformationBox::ShowError("Unable to update the firmware", "The connected device is a compound device, direct firmware"
|
||||
" update is not supported. Connect to each LibreVNA individually for the update.");
|
||||
return;
|
||||
}
|
||||
StartFirmwareUpdateDialog();
|
||||
}
|
||||
}
|
||||
|
||||
void AppWindow::DeviceStatusUpdated()
|
||||
void AppWindow::DeviceStatusUpdated(VirtualDevice::Status &status)
|
||||
{
|
||||
UpdateStatusBar(DeviceStatusBar::Updated);
|
||||
lDeviceInfo.setText(status.statusString);
|
||||
lADCOverload.setVisible(status.overload);
|
||||
lUnlevel.setVisible(status.unlevel);
|
||||
lUnlock.setVisible(status.unlocked);
|
||||
}
|
||||
|
||||
void AppWindow::SourceCalibrationDialog()
|
||||
{
|
||||
auto d = new SourceCalDialog(device, modeHandler);
|
||||
if(!vdevice || vdevice->isCompoundDevice()) {
|
||||
return;
|
||||
}
|
||||
auto d = new SourceCalDialog(vdevice->getDevice(), modeHandler);
|
||||
if(AppWindow::showGUI()) {
|
||||
d->exec();
|
||||
}
|
||||
@ -1065,7 +1003,10 @@ void AppWindow::SourceCalibrationDialog()
|
||||
|
||||
void AppWindow::ReceiverCalibrationDialog()
|
||||
{
|
||||
auto d = new ReceiverCalDialog(device, modeHandler);
|
||||
if(!vdevice || vdevice->isCompoundDevice()) {
|
||||
return;
|
||||
}
|
||||
auto d = new ReceiverCalDialog(vdevice->getDevice(), modeHandler);
|
||||
if(AppWindow::showGUI()) {
|
||||
d->exec();
|
||||
}
|
||||
@ -1073,7 +1014,10 @@ void AppWindow::ReceiverCalibrationDialog()
|
||||
|
||||
void AppWindow::FrequencyCalibrationDialog()
|
||||
{
|
||||
auto d = new FrequencyCalDialog(device, modeHandler);
|
||||
if(!vdevice || vdevice->isCompoundDevice()) {
|
||||
return;
|
||||
}
|
||||
auto d = new FrequencyCalDialog(vdevice->getDevice(), modeHandler);
|
||||
if(AppWindow::showGUI()) {
|
||||
d->exec();
|
||||
}
|
||||
@ -1109,10 +1053,8 @@ nlohmann::json AppWindow::SaveSetup()
|
||||
}
|
||||
nlohmann::json ref;
|
||||
|
||||
Reference::TypeIn t = static_cast<Reference::TypeIn>(toolbars.reference.type->currentData().toInt());
|
||||
ref["Mode"] = Reference::TypeToKey(t).toStdString();
|
||||
Reference::OutFreq f = static_cast<Reference::OutFreq>(toolbars.reference.outFreq->currentData().toInt());
|
||||
ref["Output"] = Reference::OutFreqToKey(f).toStdString();
|
||||
ref["Mode"] = toolbars.reference.type->currentText().toStdString();
|
||||
ref["Output"] = toolbars.reference.outFreq->currentText().toStdString();
|
||||
j["Reference"] = ref;
|
||||
j["version"] = qlibrevnaApp->applicationVersion().toStdString();
|
||||
return j;
|
||||
@ -1146,10 +1088,7 @@ void AppWindow::LoadSetup(nlohmann::json j)
|
||||
// auto d = new JSONPickerDialog(j);
|
||||
// d->exec();
|
||||
if(j.contains("Reference")) {
|
||||
QString fallback = Reference::TypeToKey(Reference::TypeIn::Internal);
|
||||
auto mode = QString::fromStdString(j["Reference"].value("Mode",fallback.toStdString()));
|
||||
auto index = toolbars.reference.type->findData((int)Reference::KeyToType(mode));
|
||||
toolbars.reference.type->setCurrentIndex(index);
|
||||
toolbars.reference.type->setCurrentText(QString::fromStdString(j["Reference"].value("Mode", "Internal")));
|
||||
toolbars.reference.outFreq->setCurrentText(QString::fromStdString(j["Reference"].value("Output", "Off")));
|
||||
}
|
||||
|
||||
@ -1198,9 +1137,9 @@ void AppWindow::LoadSetup(nlohmann::json j)
|
||||
}
|
||||
}
|
||||
|
||||
Device *&AppWindow::getDevice()
|
||||
VirtualDevice *AppWindow::getDevice()
|
||||
{
|
||||
return device;
|
||||
return vdevice;
|
||||
}
|
||||
|
||||
QStackedWidget *AppWindow::getCentral() const
|
||||
@ -1274,19 +1213,19 @@ void AppWindow::UpdateStatusBar(DeviceStatusBar status)
|
||||
{
|
||||
switch(status) {
|
||||
case DeviceStatusBar::Connected:
|
||||
lConnectionStatus.setText("Connected to " + device->serial());
|
||||
qInfo() << "Connected to" << device->serial();
|
||||
lDeviceInfo.setText(device->getLastDeviceInfoString());
|
||||
lConnectionStatus.setText("Connected to " + vdevice->serial());
|
||||
qInfo() << "Connected to" << vdevice->serial();
|
||||
// lDeviceInfo.setText(vdevice->getLastDeviceInfoString());
|
||||
break;
|
||||
case DeviceStatusBar::Disconnected:
|
||||
lConnectionStatus.setText("No device connected");
|
||||
lDeviceInfo.setText("No device information available yet");
|
||||
break;
|
||||
case DeviceStatusBar::Updated:
|
||||
lDeviceInfo.setText(device->getLastDeviceInfoString());
|
||||
lADCOverload.setVisible(device->StatusV1().ADC_overload);
|
||||
lUnlevel.setVisible(device->StatusV1().unlevel);
|
||||
lUnlock.setVisible(!device->StatusV1().LO1_locked || !device->StatusV1().source_locked);
|
||||
// lDeviceInfo.setText(vdevice->getLastDeviceInfoString());
|
||||
// lADCOverload.setVisible(vdevice->StatusV1().ADC_overload);
|
||||
// lUnlevel.setVisible(vdevice->StatusV1().unlevel);
|
||||
// lUnlock.setVisible(!vdevice->StatusV1().LO1_locked || !vdevice->StatusV1().source_locked);
|
||||
break;
|
||||
default:
|
||||
// invalid status
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef APPWINDOW_H
|
||||
#define APPWINDOW_H
|
||||
|
||||
#include "Device/device.h"
|
||||
#include "Device/virtualdevice.h".h"
|
||||
#include "Traces/traceplot.h"
|
||||
#include "Calibration/calibration.h"
|
||||
#include "Traces/tracemodel.h"
|
||||
@ -43,7 +43,7 @@ public:
|
||||
Ui::MainWindow *getUi() const;
|
||||
QStackedWidget *getCentral() const;
|
||||
ModeHandler* getModeHandler() const;
|
||||
Device*&getDevice();
|
||||
VirtualDevice *getDevice();
|
||||
|
||||
const QString& getAppVersion() const;
|
||||
const QString& getAppGitHash() const;
|
||||
@ -62,11 +62,12 @@ private slots:
|
||||
void DisconnectDevice();
|
||||
int UpdateDeviceList();
|
||||
void StartManualControl();
|
||||
void UpdateReferenceToolbar();
|
||||
void UpdateReference();
|
||||
void UpdateAcquisitionFrequencies();
|
||||
void StartFirmwareUpdateDialog();
|
||||
void DeviceNeedsUpdate(int reported, int expected);
|
||||
void DeviceStatusUpdated();
|
||||
void DeviceStatusUpdated(VirtualDevice::Status &status);
|
||||
void SourceCalibrationDialog();
|
||||
void ReceiverCalibrationDialog();
|
||||
void FrequencyCalibrationDialog();
|
||||
@ -102,7 +103,7 @@ private:
|
||||
} toolbars;
|
||||
|
||||
ModeHandler *modeHandler;
|
||||
Device *device;
|
||||
VirtualDevice *vdevice;
|
||||
DeviceLog deviceLog;
|
||||
QString deviceSerial;
|
||||
QActionGroup *deviceActionGroup;
|
||||
|
@ -104,11 +104,15 @@ VNAData Averaging::process(VNAData d)
|
||||
return d;
|
||||
}
|
||||
|
||||
Protocol::SpectrumAnalyzerResult Averaging::process(Protocol::SpectrumAnalyzerResult d)
|
||||
VirtualDevice::SAMeasurement Averaging::process(VirtualDevice::SAMeasurement d)
|
||||
{
|
||||
if(d.measurements.size() != numMeasurements) {
|
||||
reset(avg.size());
|
||||
}
|
||||
|
||||
if (d.pointNum == avg.size()) {
|
||||
// add moving average entry
|
||||
deque<array<complex<double>, 4>> deque;
|
||||
deque<vector<complex<double>>> deque;
|
||||
avg.push_back(deque);
|
||||
}
|
||||
|
||||
@ -117,46 +121,61 @@ Protocol::SpectrumAnalyzerResult Averaging::process(Protocol::SpectrumAnalyzerRe
|
||||
// get correct queue
|
||||
auto deque = &avg[d.pointNum];
|
||||
// add newest sample to queue
|
||||
array<complex<double>, 4> sample = {d.port1, d.port2, 0, 0};
|
||||
vector<complex<double>> sample;
|
||||
for(auto m : d.measurements) {
|
||||
sample.push_back(m.second);
|
||||
}
|
||||
deque->push_back(sample);
|
||||
if(deque->size() > averages) {
|
||||
deque->pop_front();
|
||||
}
|
||||
|
||||
deque<double> averagedResults;
|
||||
|
||||
switch(mode) {
|
||||
case Mode::Mean: {
|
||||
// calculate average
|
||||
complex<double> sum[2];
|
||||
complex<double> sum[numMeasurements];
|
||||
for(auto s : *deque) {
|
||||
sum[0] += s[0];
|
||||
sum[1] += s[1];
|
||||
for(int i=0;i<numMeasurements;i++) {
|
||||
sum[i] += s[i];
|
||||
}
|
||||
}
|
||||
for(auto s : sum) {
|
||||
averagedResults.push_back(abs(s / (double) (deque->size())));
|
||||
}
|
||||
d.port1 = abs(sum[0] / (double) (deque->size()));
|
||||
d.port2 = abs(sum[1] / (double) (deque->size()));
|
||||
}
|
||||
break;
|
||||
case Mode::Median: {
|
||||
auto size = deque->size();
|
||||
// create sorted arrays
|
||||
std::vector<double> port1, port2;
|
||||
port1.reserve(size);
|
||||
port2.reserve(size);
|
||||
// create sorted vectors
|
||||
array<vector<double>, numMeasurements> vectors;
|
||||
for(auto &v : vectors) {
|
||||
v.reserve(size);
|
||||
}
|
||||
for(auto d : *deque) {
|
||||
port1.insert(upper_bound(port1.begin(), port1.end(), abs(d[0])), abs(d[0]));
|
||||
port2.insert(upper_bound(port2.begin(), port2.end(), abs(d[0])), abs(d[0]));
|
||||
for(auto &v : vectors) {
|
||||
v.insert(upper_bound(v.begin(), v.end(), abs(d[0])), abs(d[0]));
|
||||
}
|
||||
}
|
||||
if(size & 0x01) {
|
||||
// odd number of samples
|
||||
d.port1 = port1[size / 2];
|
||||
d.port2 = port1[size / 2];
|
||||
for(auto v : vectors) {
|
||||
averagedResults.push_back(v[size / 2]);
|
||||
}
|
||||
} else {
|
||||
// even number, use average of middle samples
|
||||
d.port1 = (port1[size / 2 - 1] + port1[size / 2]) / 2;
|
||||
d.port2 = (port2[size / 2 - 1] + port2[size / 2]) / 2;
|
||||
for(auto v : vectors) {
|
||||
averagedResults.push_back((v[size / 2 - 1] + v[size / 2]) / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
for(auto &m : d.measurements) {
|
||||
m.second = averagedResults.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
return d;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef AVERAGING_H
|
||||
#define AVERAGING_H
|
||||
|
||||
#include "Device/device.h"
|
||||
#include "Device/virtualdevice.h".h"
|
||||
#include "VNA/vnadata.h"
|
||||
|
||||
#include <array>
|
||||
@ -20,7 +20,7 @@ public:
|
||||
void reset(unsigned int points);
|
||||
void setAverages(unsigned int a);
|
||||
VNAData process(VNAData d);
|
||||
Protocol::SpectrumAnalyzerResult process(Protocol::SpectrumAnalyzerResult d);
|
||||
VirtualDevice::SAMeasurement process(VirtualDevice::SAMeasurement d);
|
||||
// Returns the number of averaged sweeps. Value is incremented whenever the last point of the sweep is added.
|
||||
// Returned values are in range 0 to averages
|
||||
unsigned int getLevel();
|
||||
@ -31,8 +31,9 @@ public:
|
||||
void setMode(const Mode &value);
|
||||
|
||||
private:
|
||||
std::vector<std::deque<std::array<std::complex<double>, 4>>> avg;
|
||||
std::vector<std::deque<std::vector<std::complex<double>>>> avg;
|
||||
int maxPoints;
|
||||
int numMeasurements;
|
||||
unsigned int averages;
|
||||
Mode mode;
|
||||
};
|
||||
|
@ -115,7 +115,7 @@ void Mode::deactivate()
|
||||
qDebug() << "Deactivated mode" << name;
|
||||
|
||||
if(window->getDevice()) {
|
||||
window->getDevice()->SetIdle();
|
||||
window->getDevice()->setIdle();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user