allow segmented sweeps for more points
This commit is contained in:
parent
c9ffdcd52b
commit
ffedd3028c
@ -20,6 +20,7 @@
|
|||||||
#include "CustomWidgets/informationbox.h"
|
#include "CustomWidgets/informationbox.h"
|
||||||
#include "Deembedding/manualdeembeddingdialog.h"
|
#include "Deembedding/manualdeembeddingdialog.h"
|
||||||
#include "Calibration/manualcalibrationdialog.h"
|
#include "Calibration/manualcalibrationdialog.h"
|
||||||
|
#include "Util/util.h"
|
||||||
|
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
@ -365,8 +366,8 @@ VNA::VNA(AppWindow *window)
|
|||||||
frequencySweepActions.push_back(tb_acq->addWidget(dbm));
|
frequencySweepActions.push_back(tb_acq->addWidget(dbm));
|
||||||
|
|
||||||
auto points = new QSpinBox();
|
auto points = new QSpinBox();
|
||||||
points->setFixedWidth(55);
|
points->setFixedWidth(65);
|
||||||
points->setRange(1, 9999);
|
points->setRange(1, UINT16_MAX);
|
||||||
points->setSingleStep(100);
|
points->setSingleStep(100);
|
||||||
points->setToolTip("Points/sweep");
|
points->setToolTip("Points/sweep");
|
||||||
points->setKeyboardTracking(false);
|
points->setKeyboardTracking(false);
|
||||||
@ -787,6 +788,19 @@ using namespace std;
|
|||||||
|
|
||||||
void VNA::NewDatapoint(Protocol::Datapoint d)
|
void VNA::NewDatapoint(Protocol::Datapoint d)
|
||||||
{
|
{
|
||||||
|
bool needsSegmentUpdate = false;
|
||||||
|
if (settings.segments > 1) {
|
||||||
|
// using multiple segments, adjust pointNum
|
||||||
|
auto pointsPerSegment = ceil((double) settings.npoints / settings.segments);
|
||||||
|
if (d.pointNum == pointsPerSegment - 1) {
|
||||||
|
needsSegmentUpdate = true;
|
||||||
|
}
|
||||||
|
d.pointNum += pointsPerSegment * settings.activeSegment;
|
||||||
|
if(d.pointNum == settings.npoints - 1) {
|
||||||
|
needsSegmentUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(d.pointNum >= settings.npoints) {
|
if(d.pointNum >= settings.npoints) {
|
||||||
qWarning() << "Ignoring point with too large point number (" << d.pointNum << ")";
|
qWarning() << "Ignoring point with too large point number (" << d.pointNum << ")";
|
||||||
return;
|
return;
|
||||||
@ -838,6 +852,15 @@ void VNA::NewDatapoint(Protocol::Datapoint d)
|
|||||||
qWarning() << "Got point" << d.pointNum << "but last received point was" << lastPoint << "("<<(d.pointNum-lastPoint-1)<<"missed points)";
|
qWarning() << "Got point" << d.pointNum << "but last received point was" << lastPoint << "("<<(d.pointNum-lastPoint-1)<<"missed points)";
|
||||||
}
|
}
|
||||||
lastPoint = d.pointNum;
|
lastPoint = d.pointNum;
|
||||||
|
|
||||||
|
if (needsSegmentUpdate) {
|
||||||
|
if( settings.activeSegment < settings.segments - 1) {
|
||||||
|
settings.activeSegment++;
|
||||||
|
} else {
|
||||||
|
settings.activeSegment = 0;
|
||||||
|
}
|
||||||
|
SettingsChanged(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNA::UpdateAverageCount()
|
void VNA::UpdateAverageCount()
|
||||||
@ -845,7 +868,7 @@ void VNA::UpdateAverageCount()
|
|||||||
lAverages->setText(QString::number(average.getLevel()) + "/");
|
lAverages->setText(QString::number(average.getLevel()) + "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNA::SettingsChanged(std::function<void (Device::TransmissionResult)> cb)
|
void VNA::SettingsChanged(bool resetTraces, std::function<void (Device::TransmissionResult)> cb)
|
||||||
{
|
{
|
||||||
// assemble VNA protocol settings
|
// assemble VNA protocol settings
|
||||||
Protocol::SweepSettings s;
|
Protocol::SweepSettings s;
|
||||||
@ -859,20 +882,40 @@ void VNA::SettingsChanged(std::function<void (Device::TransmissionResult)> cb)
|
|||||||
}
|
}
|
||||||
settings.excitingPort1 = s.excitePort1;
|
settings.excitingPort1 = s.excitePort1;
|
||||||
settings.excitingPort2 = s.excitePort2;
|
settings.excitingPort2 = s.excitePort2;
|
||||||
|
|
||||||
|
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);
|
||||||
|
int segmentStartPoint = npoints * settings.activeSegment;
|
||||||
|
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) {
|
if(settings.sweepType == SweepType::Frequency) {
|
||||||
s.fixedPowerSetting = Preferences::getInstance().Acquisition.adjustPowerLevel ? 0 : 1;
|
s.fixedPowerSetting = Preferences::getInstance().Acquisition.adjustPowerLevel ? 0 : 1;
|
||||||
s.f_start = settings.Freq.start;
|
s.f_start = start;
|
||||||
s.f_stop = settings.Freq.stop;
|
s.f_stop = stop;
|
||||||
s.points = settings.npoints;
|
s.points = npoints;
|
||||||
s.if_bandwidth = settings.bandwidth;
|
s.if_bandwidth = settings.bandwidth;
|
||||||
s.cdbm_excitation_start = settings.Freq.excitation_power * 100;
|
s.cdbm_excitation_start = settings.Freq.excitation_power * 100;
|
||||||
s.cdbm_excitation_stop = settings.Freq.excitation_power * 100;
|
s.cdbm_excitation_stop = settings.Freq.excitation_power * 100;
|
||||||
s.logSweep = settings.Freq.logSweep;
|
s.logSweep = settings.Freq.logSweep;
|
||||||
} else if(settings.sweepType == SweepType::Power) {
|
} else if(settings.sweepType == SweepType::Power) {
|
||||||
s.fixedPowerSetting = 0;
|
s.fixedPowerSetting = 0;
|
||||||
s.f_start = settings.Power.frequency;
|
s.f_start = start;
|
||||||
s.f_stop = settings.Power.frequency;
|
s.f_stop = stop;
|
||||||
s.points = settings.npoints;
|
s.points = npoints;
|
||||||
s.if_bandwidth = settings.bandwidth;
|
s.if_bandwidth = settings.bandwidth;
|
||||||
s.cdbm_excitation_start = settings.Power.start * 100;
|
s.cdbm_excitation_start = settings.Power.start * 100;
|
||||||
s.cdbm_excitation_stop = settings.Power.stop * 100;
|
s.cdbm_excitation_stop = settings.Power.stop * 100;
|
||||||
@ -880,22 +923,23 @@ void VNA::SettingsChanged(std::function<void (Device::TransmissionResult)> cb)
|
|||||||
}
|
}
|
||||||
if(window->getDevice() && Mode::getActiveMode() == this) {
|
if(window->getDevice() && Mode::getActiveMode() == this) {
|
||||||
if(s.excitePort1 == 0 && s.excitePort2 == 0) {
|
if(s.excitePort1 == 0 && s.excitePort2 == 0) {
|
||||||
// no signal at either port, just set the device to idel
|
// no signal at either port, just set the device to idle
|
||||||
window->getDevice()->SetIdle();
|
window->getDevice()->SetIdle();
|
||||||
} else {
|
} else {
|
||||||
window->getDevice()->Configure(s, [=](Device::TransmissionResult res){
|
window->getDevice()->Configure(s, [=](Device::TransmissionResult res){
|
||||||
// device received command, reset traces now
|
// device received command, reset traces now
|
||||||
average.reset(s.points);
|
if (resetTraces) {
|
||||||
traceModel.clearLiveData();
|
average.reset(s.points);
|
||||||
UpdateAverageCount();
|
traceModel.clearLiveData();
|
||||||
UpdateCalWidget();
|
UpdateAverageCount();
|
||||||
|
UpdateCalWidget();
|
||||||
|
}
|
||||||
if(cb) {
|
if(cb) {
|
||||||
cb(res);
|
cb(res);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emit traceModel.SpanChanged(s.f_start, s.f_stop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNA::StartImpedanceMatching()
|
void VNA::StartImpedanceMatching()
|
||||||
@ -1045,11 +1089,21 @@ void VNA::SetPowerSweepFrequency(double freq)
|
|||||||
|
|
||||||
void VNA::SetPoints(unsigned int points)
|
void VNA::SetPoints(unsigned int points)
|
||||||
{
|
{
|
||||||
if(points > Device::Info().limits_maxPoints) {
|
auto maxPoints = Preferences::getInstance().Acquisition.allowSegmentedSweep ? UINT16_MAX : Device::Info().limits_maxPoints;
|
||||||
points = Device::Info().limits_maxPoints;
|
if(points > maxPoints) {
|
||||||
|
points = maxPoints;
|
||||||
} else if (points < 2) {
|
} else if (points < 2) {
|
||||||
points = 2;
|
points = 2;
|
||||||
}
|
}
|
||||||
|
if (points > Device::Info().limits_maxPoints) {
|
||||||
|
// needs segmented sweep
|
||||||
|
settings.segments = ceil((double) points / Device::Info().limits_maxPoints);
|
||||||
|
settings.activeSegment = 0;
|
||||||
|
} else {
|
||||||
|
// can fit all points into one segment
|
||||||
|
settings.segments = 1;
|
||||||
|
settings.activeSegment = 0;
|
||||||
|
}
|
||||||
emit pointsChanged(points);
|
emit pointsChanged(points);
|
||||||
settings.npoints = points;
|
settings.npoints = points;
|
||||||
SettingsChanged();
|
SettingsChanged();
|
||||||
@ -1161,7 +1215,7 @@ void VNA::StartCalibrationMeasurements(std::set<Calibration::Measurement> m)
|
|||||||
cal.clearMeasurements(calMeasurements);
|
cal.clearMeasurements(calMeasurements);
|
||||||
});
|
});
|
||||||
// Trigger sweep to start from beginning
|
// Trigger sweep to start from beginning
|
||||||
SettingsChanged([=](Device::TransmissionResult){
|
SettingsChanged(true, [=](Device::TransmissionResult){
|
||||||
// enable calibration measurement only in transmission callback (prevents accidental sampling of data which was still being processed)
|
// enable calibration measurement only in transmission callback (prevents accidental sampling of data which was still being processed)
|
||||||
calMeasuring = true;
|
calMeasuring = true;
|
||||||
});
|
});
|
||||||
|
@ -40,7 +40,8 @@ public:
|
|||||||
static QString SweepTypeToString(SweepType sw);
|
static QString SweepTypeToString(SweepType sw);
|
||||||
static SweepType SweepTypeFromString(QString s);
|
static SweepType SweepTypeFromString(QString s);
|
||||||
|
|
||||||
using Settings = struct {
|
class Settings {
|
||||||
|
public:
|
||||||
SweepType sweepType;
|
SweepType sweepType;
|
||||||
struct {
|
struct {
|
||||||
double start;
|
double start;
|
||||||
@ -57,6 +58,9 @@ public:
|
|||||||
double bandwidth;
|
double bandwidth;
|
||||||
bool excitingPort1;
|
bool excitingPort1;
|
||||||
bool excitingPort2;
|
bool excitingPort2;
|
||||||
|
// if the number of points is higher than supported by the hardware, the sweep has to be segmented into multiple parts
|
||||||
|
int segments;
|
||||||
|
int activeSegment;
|
||||||
};
|
};
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
@ -101,7 +105,7 @@ private:
|
|||||||
bool CalibrationMeasurementActive() { return calWaitFirst || calMeasuring; }
|
bool CalibrationMeasurementActive() { return calWaitFirst || calMeasuring; }
|
||||||
void SetupSCPI();
|
void SetupSCPI();
|
||||||
void UpdateAverageCount();
|
void UpdateAverageCount();
|
||||||
void SettingsChanged(std::function<void (Device::TransmissionResult)> cb = nullptr);
|
void SettingsChanged(bool resetTraces = true, std::function<void (Device::TransmissionResult)> cb = nullptr);
|
||||||
void ConstrainAndUpdateFrequencies();
|
void ConstrainAndUpdateFrequencies();
|
||||||
void LoadSweepSettings();
|
void LoadSweepSettings();
|
||||||
void StoreSweepSettings();
|
void StoreSweepSettings();
|
||||||
|
@ -233,6 +233,7 @@ void PreferencesDialog::setInitialGUIState()
|
|||||||
ui->AcquisitionSuppressPeaks->setChecked(p->Acquisition.suppressPeaks);
|
ui->AcquisitionSuppressPeaks->setChecked(p->Acquisition.suppressPeaks);
|
||||||
ui->AcquisitionAdjustPowerLevel->setChecked(p->Acquisition.adjustPowerLevel);
|
ui->AcquisitionAdjustPowerLevel->setChecked(p->Acquisition.adjustPowerLevel);
|
||||||
ui->AcquisitionUseHarmonic->setChecked(p->Acquisition.harmonicMixing);
|
ui->AcquisitionUseHarmonic->setChecked(p->Acquisition.harmonicMixing);
|
||||||
|
ui->AcquisitionAllowSegmentedSweep->setChecked(p->Acquisition.allowSegmentedSweep);
|
||||||
ui->AcquisitionUseDFT->setChecked(p->Acquisition.useDFTinSAmode);
|
ui->AcquisitionUseDFT->setChecked(p->Acquisition.useDFTinSAmode);
|
||||||
ui->AcquisitionDFTlimitRBW->setValue(p->Acquisition.RBWLimitForDFT);
|
ui->AcquisitionDFTlimitRBW->setValue(p->Acquisition.RBWLimitForDFT);
|
||||||
ui->AcquisitionAveragingMode->setCurrentIndex(p->Acquisition.useMedianAveraging ? 1 : 0);
|
ui->AcquisitionAveragingMode->setCurrentIndex(p->Acquisition.useMedianAveraging ? 1 : 0);
|
||||||
@ -292,6 +293,7 @@ void PreferencesDialog::updateFromGUI()
|
|||||||
p->Acquisition.suppressPeaks = ui->AcquisitionSuppressPeaks->isChecked();
|
p->Acquisition.suppressPeaks = ui->AcquisitionSuppressPeaks->isChecked();
|
||||||
p->Acquisition.adjustPowerLevel = ui->AcquisitionAdjustPowerLevel->isChecked();
|
p->Acquisition.adjustPowerLevel = ui->AcquisitionAdjustPowerLevel->isChecked();
|
||||||
p->Acquisition.harmonicMixing = ui->AcquisitionUseHarmonic->isChecked();
|
p->Acquisition.harmonicMixing = ui->AcquisitionUseHarmonic->isChecked();
|
||||||
|
p->Acquisition.allowSegmentedSweep = ui->AcquisitionAllowSegmentedSweep->isChecked();
|
||||||
p->Acquisition.useDFTinSAmode = ui->AcquisitionUseDFT->isChecked();
|
p->Acquisition.useDFTinSAmode = ui->AcquisitionUseDFT->isChecked();
|
||||||
p->Acquisition.RBWLimitForDFT = ui->AcquisitionDFTlimitRBW->value();
|
p->Acquisition.RBWLimitForDFT = ui->AcquisitionDFTlimitRBW->value();
|
||||||
p->Acquisition.useMedianAveraging = ui->AcquisitionAveragingMode->currentIndex() == 1;
|
p->Acquisition.useMedianAveraging = ui->AcquisitionAveragingMode->currentIndex() == 1;
|
||||||
|
@ -69,6 +69,7 @@ public:
|
|||||||
bool suppressPeaks;
|
bool suppressPeaks;
|
||||||
bool adjustPowerLevel;
|
bool adjustPowerLevel;
|
||||||
bool harmonicMixing;
|
bool harmonicMixing;
|
||||||
|
bool allowSegmentedSweep;
|
||||||
bool useDFTinSAmode;
|
bool useDFTinSAmode;
|
||||||
double RBWLimitForDFT;
|
double RBWLimitForDFT;
|
||||||
bool useMedianAveraging;
|
bool useMedianAveraging;
|
||||||
@ -147,6 +148,7 @@ private:
|
|||||||
{&Acquisition.suppressPeaks, "Acquisition.suppressPeaks", true},
|
{&Acquisition.suppressPeaks, "Acquisition.suppressPeaks", true},
|
||||||
{&Acquisition.adjustPowerLevel, "Acquisition.adjustPowerLevel", false},
|
{&Acquisition.adjustPowerLevel, "Acquisition.adjustPowerLevel", false},
|
||||||
{&Acquisition.harmonicMixing, "Acquisition.harmonicMixing", false},
|
{&Acquisition.harmonicMixing, "Acquisition.harmonicMixing", false},
|
||||||
|
{&Acquisition.allowSegmentedSweep, "Acquisition.allowSegmentedSweep", false},
|
||||||
{&Acquisition.useDFTinSAmode, "Acquisition.useDFTinSAmode", true},
|
{&Acquisition.useDFTinSAmode, "Acquisition.useDFTinSAmode", true},
|
||||||
{&Acquisition.RBWLimitForDFT, "Acquisition.RBWLimitForDFT", 3000.0},
|
{&Acquisition.RBWLimitForDFT, "Acquisition.RBWLimitForDFT", 3000.0},
|
||||||
{&Acquisition.useMedianAveraging, "Acquisition.useMedianAveraging", false},
|
{&Acquisition.useMedianAveraging, "Acquisition.useMedianAveraging", false},
|
||||||
|
@ -83,7 +83,7 @@
|
|||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="Startup">
|
<widget class="QWidget" name="Startup">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
@ -738,6 +738,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="AcquisitionAllowSegmentedSweep">
|
||||||
|
<property name="text">
|
||||||
|
<string>Allow segmented sweep (increases maximum number of points)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
Loading…
Reference in New Issue
Block a user