Improve load time of setup files by omitting excessive device configuration
This commit is contained in:
parent
2f5cbc80e9
commit
eff18a22e8
@ -64,6 +64,11 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
|
||||
normalize.measure = nullptr;
|
||||
normalize.enable = nullptr;
|
||||
|
||||
configurationTimer.setSingleShot(true);
|
||||
connect(&configurationTimer, &QTimer::timeout, this, [=](){
|
||||
ConfigureDevice();
|
||||
});
|
||||
|
||||
traceModel.setSource(TraceModel::DataSource::SA);
|
||||
|
||||
// Create default traces
|
||||
@ -543,77 +548,7 @@ void SpectrumAnalyzer::NewDatapoint(VirtualDevice::SAMeasurement m)
|
||||
|
||||
void SpectrumAnalyzer::SettingsChanged()
|
||||
{
|
||||
if(running) {
|
||||
changingSettings = true;
|
||||
if(settings.freqStop - settings.freqStart >= 1000 || settings.freqStop - settings.freqStart <= 0) {
|
||||
settings.points = 1001;
|
||||
} else {
|
||||
settings.points = settings.freqStop - settings.freqStart + 1;
|
||||
}
|
||||
|
||||
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.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.freqStop;
|
||||
while(stop <= 3000000000) {
|
||||
minSpacing /= 2;
|
||||
stop *= 2;
|
||||
}
|
||||
if(pointSpacing < minSpacing) {
|
||||
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.";
|
||||
InformationBox::ShowMessage("Warning", message, "TrackingGeneratorSpanTooSmallWarning");
|
||||
}
|
||||
}
|
||||
|
||||
if(normalize.active) {
|
||||
// check if normalization is still valid
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
if(window->getDevice() && isActive) {
|
||||
window->getDevice()->setSA(settings, [=](bool){
|
||||
// device received command
|
||||
changingSettings = false;
|
||||
});
|
||||
emit sweepStarted();
|
||||
} else {
|
||||
// no device, unable to start sweep
|
||||
emit sweepStopped();
|
||||
changingSettings = false;
|
||||
}
|
||||
average.reset(settings.points);
|
||||
UpdateAverageCount();
|
||||
traceModel.clearLiveData();
|
||||
emit traceModel.SpanChanged(settings.freqStart, settings.freqStop);
|
||||
} else {
|
||||
if(window->getDevice()) {
|
||||
changingSettings = true;
|
||||
// single sweep finished
|
||||
window->getDevice()->setIdle([=](bool){
|
||||
emit sweepStopped();
|
||||
changingSettings = false;
|
||||
});
|
||||
} else {
|
||||
emit sweepStopped();
|
||||
changingSettings = false;
|
||||
}
|
||||
}
|
||||
configurationTimer.start(100);
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::SetStartFreq(double freq)
|
||||
@ -718,7 +653,9 @@ void SpectrumAnalyzer::SetSingleSweep(bool single)
|
||||
singleSweep = single;
|
||||
emit singleSweepChanged(single);
|
||||
}
|
||||
SettingsChanged();
|
||||
if(single) {
|
||||
Run();
|
||||
}
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::SetRBW(double bandwidth)
|
||||
@ -888,13 +825,88 @@ void SpectrumAnalyzer::SetNormalizationLevel(double level)
|
||||
void SpectrumAnalyzer::Run()
|
||||
{
|
||||
running = true;
|
||||
SettingsChanged();
|
||||
ConfigureDevice();
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::Stop()
|
||||
{
|
||||
running = false;
|
||||
SettingsChanged();
|
||||
ConfigureDevice();
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::ConfigureDevice()
|
||||
{
|
||||
if(running) {
|
||||
changingSettings = true;
|
||||
if(settings.freqStop - settings.freqStart >= 1000 || settings.freqStop - settings.freqStart <= 0) {
|
||||
settings.points = 1001;
|
||||
} else {
|
||||
settings.points = settings.freqStop - settings.freqStart + 1;
|
||||
}
|
||||
|
||||
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.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.freqStop;
|
||||
while(stop <= 3000000000) {
|
||||
minSpacing /= 2;
|
||||
stop *= 2;
|
||||
}
|
||||
if(pointSpacing < minSpacing) {
|
||||
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.";
|
||||
InformationBox::ShowMessage("Warning", message, "TrackingGeneratorSpanTooSmallWarning");
|
||||
}
|
||||
}
|
||||
|
||||
if(normalize.active) {
|
||||
// check if normalization is still valid
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
if(window->getDevice() && isActive) {
|
||||
window->getDevice()->setSA(settings, [=](bool){
|
||||
// device received command
|
||||
changingSettings = false;
|
||||
});
|
||||
emit sweepStarted();
|
||||
} else {
|
||||
// no device, unable to start sweep
|
||||
emit sweepStopped();
|
||||
changingSettings = false;
|
||||
}
|
||||
average.reset(settings.points);
|
||||
UpdateAverageCount();
|
||||
traceModel.clearLiveData();
|
||||
emit traceModel.SpanChanged(settings.freqStart, settings.freqStop);
|
||||
} else {
|
||||
if(window->getDevice()) {
|
||||
changingSettings = true;
|
||||
// single sweep finished
|
||||
window->getDevice()->setIdle([=](bool){
|
||||
emit sweepStopped();
|
||||
changingSettings = false;
|
||||
});
|
||||
} else {
|
||||
emit sweepStopped();
|
||||
changingSettings = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::SetupSCPI()
|
||||
|
@ -73,6 +73,7 @@ private slots:
|
||||
|
||||
void Run();
|
||||
void Stop();
|
||||
void ConfigureDevice();
|
||||
|
||||
private:
|
||||
void SetupSCPI();
|
||||
@ -89,6 +90,8 @@ private:
|
||||
unsigned int averages;
|
||||
bool singleSweep;
|
||||
bool running;
|
||||
QTimer configurationTimer;
|
||||
|
||||
double firstPointTime; // timestamp of the first point in the sweep, only use when zerospan is used
|
||||
TraceModel traceModel;
|
||||
TraceWidget *traceWidget;
|
||||
|
@ -69,6 +69,11 @@ VNA::VNA(AppWindow *window, QString name)
|
||||
|
||||
traceModel.setSource(TraceModel::DataSource::VNA);
|
||||
|
||||
configurationTimer.setSingleShot(true);
|
||||
connect(&configurationTimer, &QTimer::timeout, this, [=](){
|
||||
ConfigureDevice();
|
||||
});
|
||||
|
||||
// Create default traces
|
||||
createDefaultTracesAndGraphs(2);
|
||||
|
||||
@ -886,7 +891,7 @@ void VNA::NewDatapoint(VirtualDevice::VNAMeasurement m)
|
||||
} else {
|
||||
settings.activeSegment = 0;
|
||||
}
|
||||
SettingsChanged(false);
|
||||
SettingsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@ -895,95 +900,9 @@ void VNA::UpdateAverageCount()
|
||||
lAverages->setText(QString::number(average.getLevel()) + "/");
|
||||
}
|
||||
|
||||
void VNA::SettingsChanged(bool resetTraces, std::function<void (bool)> cb)
|
||||
void VNA::SettingsChanged()
|
||||
{
|
||||
if(running) {
|
||||
if (resetTraces) {
|
||||
settings.activeSegment = 0;
|
||||
}
|
||||
changingSettings = true;
|
||||
// assemble VNA protocol settings
|
||||
VirtualDevice::VNASettings s = {};
|
||||
s.IFBW = settings.bandwidth;
|
||||
if(Preferences::getInstance().Acquisition.alwaysExciteAllPorts) {
|
||||
for(unsigned int i=0;i<VirtualDevice::getInfo(window->getDevice()).ports;i++) {
|
||||
s.excitedPorts.push_back(i);
|
||||
}
|
||||
} else {
|
||||
for(unsigned int i=0;i<VirtualDevice::getInfo(window->getDevice()).ports;i++) {
|
||||
if(traceModel.PortExcitationRequired(i))
|
||||
s.excitedPorts.push_back(i);
|
||||
}
|
||||
}
|
||||
settings.excitedPorts = s.excitedPorts;
|
||||
|
||||
double start = settings.sweepType == SweepType::Frequency ? settings.Freq.start : settings.Power.start;
|
||||
double stop = settings.sweepType == SweepType::Frequency ? settings.Freq.stop : settings.Power.stop;
|
||||
int npoints = settings.npoints;
|
||||
emit traceModel.SpanChanged(start, stop);
|
||||
if (settings.segments > 1) {
|
||||
// more than one segment, adjust start/stop
|
||||
npoints = ceil((double) settings.npoints / settings.segments);
|
||||
unsigned int segmentStartPoint = npoints * settings.activeSegment;
|
||||
unsigned int segmentStopPoint = segmentStartPoint + npoints - 1;
|
||||
if(segmentStopPoint >= settings.npoints) {
|
||||
segmentStopPoint = settings.npoints - 1;
|
||||
npoints = settings.npoints - segmentStartPoint;
|
||||
}
|
||||
auto seg_start = Util::Scale<double>(segmentStartPoint, 0, settings.npoints - 1, start, stop);
|
||||
auto seg_stop = Util::Scale<double>(segmentStopPoint, 0, settings.npoints - 1, start, stop);
|
||||
start = seg_start;
|
||||
stop = seg_stop;
|
||||
}
|
||||
|
||||
if(settings.sweepType == SweepType::Frequency) {
|
||||
s.freqStart = start;
|
||||
s.freqStop = stop;
|
||||
s.points = npoints;
|
||||
s.dBmStart = settings.Freq.excitation_power;
|
||||
s.dBmStop = settings.Freq.excitation_power;
|
||||
s.logSweep = settings.Freq.logSweep;
|
||||
} else if(settings.sweepType == SweepType::Power) {
|
||||
s.freqStart = settings.Power.frequency;
|
||||
s.freqStop = settings.Power.frequency;
|
||||
s.points = npoints;
|
||||
s.dBmStart = start;
|
||||
s.dBmStop = stop;
|
||||
s.logSweep = false;
|
||||
}
|
||||
if(window->getDevice() && isActive) {
|
||||
window->getDevice()->setVNA(s, [=](bool res){
|
||||
// device received command, reset traces now
|
||||
if (resetTraces) {
|
||||
average.reset(settings.npoints);
|
||||
traceModel.clearLiveData();
|
||||
UpdateAverageCount();
|
||||
UpdateCalWidget();
|
||||
}
|
||||
if(cb) {
|
||||
cb(res);
|
||||
}
|
||||
changingSettings = false;
|
||||
});
|
||||
emit sweepStarted();
|
||||
} else {
|
||||
// no device, unable to start sweep
|
||||
emit sweepStopped();
|
||||
changingSettings = false;
|
||||
}
|
||||
} else {
|
||||
if(window->getDevice()) {
|
||||
changingSettings = true;
|
||||
// single sweep finished
|
||||
window->getDevice()->setIdle([=](bool){
|
||||
emit sweepStopped();
|
||||
changingSettings = false;
|
||||
});
|
||||
} else {
|
||||
emit sweepStopped();
|
||||
changingSettings = false;
|
||||
}
|
||||
}
|
||||
configurationTimer.start(100);
|
||||
}
|
||||
|
||||
void VNA::StartImpedanceMatching()
|
||||
@ -1268,7 +1187,7 @@ void VNA::StartCalibrationMeasurements(std::set<CalibrationMeasurement::Base*> m
|
||||
cal.clearMeasurements(calMeasurements);
|
||||
});
|
||||
// Trigger sweep to start from beginning
|
||||
SettingsChanged(true, [=](bool){
|
||||
ConfigureDevice(true, [=](bool){
|
||||
// enable calibration measurement only in transmission callback (prevents accidental sampling of data which was still being processed)
|
||||
calMeasuring = true;
|
||||
});
|
||||
@ -1693,20 +1612,111 @@ void VNA::SetSingleSweep(bool single)
|
||||
emit singleSweepChanged(single);
|
||||
}
|
||||
if(single) {
|
||||
SettingsChanged();
|
||||
Run();
|
||||
}
|
||||
}
|
||||
|
||||
void VNA::Run()
|
||||
{
|
||||
running = true;
|
||||
SettingsChanged();
|
||||
ConfigureDevice();
|
||||
}
|
||||
|
||||
void VNA::Stop()
|
||||
{
|
||||
running = false;
|
||||
SettingsChanged();
|
||||
ConfigureDevice(false);
|
||||
}
|
||||
|
||||
void VNA::ConfigureDevice(bool resetTraces, std::function<void(bool)> cb)
|
||||
{
|
||||
if(running) {
|
||||
if (resetTraces) {
|
||||
settings.activeSegment = 0;
|
||||
}
|
||||
changingSettings = true;
|
||||
// assemble VNA protocol settings
|
||||
VirtualDevice::VNASettings s = {};
|
||||
s.IFBW = settings.bandwidth;
|
||||
if(Preferences::getInstance().Acquisition.alwaysExciteAllPorts) {
|
||||
for(unsigned int i=0;i<VirtualDevice::getInfo(window->getDevice()).ports;i++) {
|
||||
s.excitedPorts.push_back(i);
|
||||
}
|
||||
} else {
|
||||
for(unsigned int i=0;i<VirtualDevice::getInfo(window->getDevice()).ports;i++) {
|
||||
if(traceModel.PortExcitationRequired(i))
|
||||
s.excitedPorts.push_back(i);
|
||||
}
|
||||
}
|
||||
settings.excitedPorts = s.excitedPorts;
|
||||
|
||||
double start = settings.sweepType == SweepType::Frequency ? settings.Freq.start : settings.Power.start;
|
||||
double stop = settings.sweepType == SweepType::Frequency ? settings.Freq.stop : settings.Power.stop;
|
||||
int npoints = settings.npoints;
|
||||
emit traceModel.SpanChanged(start, stop);
|
||||
if (settings.segments > 1) {
|
||||
// more than one segment, adjust start/stop
|
||||
npoints = ceil((double) settings.npoints / settings.segments);
|
||||
unsigned int segmentStartPoint = npoints * settings.activeSegment;
|
||||
unsigned int segmentStopPoint = segmentStartPoint + npoints - 1;
|
||||
if(segmentStopPoint >= settings.npoints) {
|
||||
segmentStopPoint = settings.npoints - 1;
|
||||
npoints = settings.npoints - segmentStartPoint;
|
||||
}
|
||||
auto seg_start = Util::Scale<double>(segmentStartPoint, 0, settings.npoints - 1, start, stop);
|
||||
auto seg_stop = Util::Scale<double>(segmentStopPoint, 0, settings.npoints - 1, start, stop);
|
||||
start = seg_start;
|
||||
stop = seg_stop;
|
||||
}
|
||||
|
||||
if(settings.sweepType == SweepType::Frequency) {
|
||||
s.freqStart = start;
|
||||
s.freqStop = stop;
|
||||
s.points = npoints;
|
||||
s.dBmStart = settings.Freq.excitation_power;
|
||||
s.dBmStop = settings.Freq.excitation_power;
|
||||
s.logSweep = settings.Freq.logSweep;
|
||||
} else if(settings.sweepType == SweepType::Power) {
|
||||
s.freqStart = settings.Power.frequency;
|
||||
s.freqStop = settings.Power.frequency;
|
||||
s.points = npoints;
|
||||
s.dBmStart = start;
|
||||
s.dBmStop = stop;
|
||||
s.logSweep = false;
|
||||
}
|
||||
if(window->getDevice() && isActive) {
|
||||
window->getDevice()->setVNA(s, [=](bool res){
|
||||
// device received command, reset traces now
|
||||
if (resetTraces) {
|
||||
average.reset(settings.npoints);
|
||||
traceModel.clearLiveData();
|
||||
UpdateAverageCount();
|
||||
UpdateCalWidget();
|
||||
}
|
||||
if(cb) {
|
||||
cb(res);
|
||||
}
|
||||
changingSettings = false;
|
||||
});
|
||||
emit sweepStarted();
|
||||
} else {
|
||||
// no device, unable to start sweep
|
||||
emit sweepStopped();
|
||||
changingSettings = false;
|
||||
}
|
||||
} else {
|
||||
if(window->getDevice()) {
|
||||
changingSettings = true;
|
||||
// single sweep finished
|
||||
window->getDevice()->setIdle([=](bool){
|
||||
emit sweepStopped();
|
||||
changingSettings = false;
|
||||
});
|
||||
} else {
|
||||
emit sweepStopped();
|
||||
changingSettings = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool VNA::LoadCalibration(QString filename)
|
||||
|
@ -116,7 +116,7 @@ private:
|
||||
bool CalibrationMeasurementActive() { return calWaitFirst || calMeasuring; }
|
||||
void SetupSCPI();
|
||||
void UpdateAverageCount();
|
||||
void SettingsChanged(bool resetTraces = true, std::function<void(bool)> cb = nullptr);
|
||||
void SettingsChanged();
|
||||
void ConstrainAndUpdateFrequencies();
|
||||
void LoadSweepSettings();
|
||||
void StoreSweepSettings();
|
||||
@ -129,6 +129,7 @@ private slots:
|
||||
void SetSingleSweep(bool single);
|
||||
void Run();
|
||||
void Stop();
|
||||
void ConfigureDevice(bool resetTraces = true, std::function<void(bool)> cb = nullptr);
|
||||
private:
|
||||
Settings settings;
|
||||
unsigned int averages;
|
||||
@ -138,6 +139,7 @@ private:
|
||||
Averaging average;
|
||||
bool singleSweep;
|
||||
bool running;
|
||||
QTimer configurationTimer;
|
||||
|
||||
// Calibration
|
||||
Calibration cal;
|
||||
|
@ -1140,6 +1140,14 @@ void AppWindow::LoadSetup(nlohmann::json j)
|
||||
toolbars.reference.outFreq->setCurrentText(QString::fromStdString(j["Reference"].value("Output", "Off")));
|
||||
}
|
||||
|
||||
// Disconnect device prior to deleting and creating new modes. This prevents excessice and unnnecessary configuration of the device
|
||||
QString serial = QString();
|
||||
if(vdevice->getConnected()) {
|
||||
serial = vdevice->serial();
|
||||
delete vdevice;
|
||||
vdevice = nullptr;
|
||||
}
|
||||
|
||||
modeHandler->closeModes();
|
||||
|
||||
/* old style VNA/Generator/Spectrum Analyzer settings,
|
||||
@ -1170,6 +1178,11 @@ void AppWindow::LoadSetup(nlohmann::json j)
|
||||
}
|
||||
}
|
||||
|
||||
// reconnect to device
|
||||
if(!serial.isEmpty()) {
|
||||
vdevice = new VirtualDevice(serial);
|
||||
}
|
||||
|
||||
// activate the correct mode
|
||||
QString modeName = QString::fromStdString(j.value("activeMode", ""));
|
||||
for(auto m : modeHandler->getModes()) {
|
||||
|
@ -23,17 +23,17 @@ void ModeHandler::shutdown()
|
||||
int ModeHandler::createMode(QString name, Mode::Type t)
|
||||
{
|
||||
auto mode = createNew(aw, name, t);
|
||||
return createMode(mode);
|
||||
return addMode(mode);
|
||||
}
|
||||
|
||||
int ModeHandler::createMode(Mode *mode)
|
||||
int ModeHandler::addMode(Mode *mode)
|
||||
{
|
||||
modes.push_back(mode);
|
||||
currentModeIndex = int(modes.size()) - 1;
|
||||
connect(mode, &Mode::statusbarMessage, this, &ModeHandler::setStatusBarMessageChanged);
|
||||
|
||||
auto m = getMode(currentModeIndex);
|
||||
activate(m);
|
||||
// auto m = getMode(currentModeIndex);
|
||||
// activate(m);
|
||||
|
||||
emit ModeCreated(currentModeIndex);
|
||||
return (currentModeIndex);
|
||||
|
@ -46,7 +46,7 @@ public slots:
|
||||
private:
|
||||
std::vector<Mode*> modes;
|
||||
int currentModeIndex;
|
||||
int createMode(Mode *mode);
|
||||
int addMode(Mode *mode);
|
||||
Mode *createNew(AppWindow *window, QString name, Mode::Type t);
|
||||
AppWindow *aw;
|
||||
Mode *activeMode;
|
||||
|
Loading…
Reference in New Issue
Block a user