allow segmented sweeps for more points

This commit is contained in:
Jan Käberich 2022-03-06 23:01:11 +01:00
parent c9ffdcd52b
commit ffedd3028c
5 changed files with 90 additions and 21 deletions

View File

@ -20,6 +20,7 @@
#include "CustomWidgets/informationbox.h"
#include "Deembedding/manualdeembeddingdialog.h"
#include "Calibration/manualcalibrationdialog.h"
#include "Util/util.h"
#include <QGridLayout>
#include <QVBoxLayout>
@ -365,8 +366,8 @@ VNA::VNA(AppWindow *window)
frequencySweepActions.push_back(tb_acq->addWidget(dbm));
auto points = new QSpinBox();
points->setFixedWidth(55);
points->setRange(1, 9999);
points->setFixedWidth(65);
points->setRange(1, UINT16_MAX);
points->setSingleStep(100);
points->setToolTip("Points/sweep");
points->setKeyboardTracking(false);
@ -787,6 +788,19 @@ using namespace std;
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) {
qWarning() << "Ignoring point with too large point number (" << d.pointNum << ")";
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)";
}
lastPoint = d.pointNum;
if (needsSegmentUpdate) {
if( settings.activeSegment < settings.segments - 1) {
settings.activeSegment++;
} else {
settings.activeSegment = 0;
}
SettingsChanged(false);
}
}
void VNA::UpdateAverageCount()
@ -845,7 +868,7 @@ void VNA::UpdateAverageCount()
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
Protocol::SweepSettings s;
@ -859,20 +882,40 @@ void VNA::SettingsChanged(std::function<void (Device::TransmissionResult)> cb)
}
settings.excitingPort1 = s.excitePort1;
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) {
s.fixedPowerSetting = Preferences::getInstance().Acquisition.adjustPowerLevel ? 0 : 1;
s.f_start = settings.Freq.start;
s.f_stop = settings.Freq.stop;
s.points = settings.npoints;
s.f_start = start;
s.f_stop = stop;
s.points = npoints;
s.if_bandwidth = settings.bandwidth;
s.cdbm_excitation_start = settings.Freq.excitation_power * 100;
s.cdbm_excitation_stop = settings.Freq.excitation_power * 100;
s.logSweep = settings.Freq.logSweep;
} else if(settings.sweepType == SweepType::Power) {
s.fixedPowerSetting = 0;
s.f_start = settings.Power.frequency;
s.f_stop = settings.Power.frequency;
s.points = settings.npoints;
s.f_start = start;
s.f_stop = stop;
s.points = npoints;
s.if_bandwidth = settings.bandwidth;
s.cdbm_excitation_start = settings.Power.start * 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(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();
} else {
window->getDevice()->Configure(s, [=](Device::TransmissionResult res){
// device received command, reset traces now
if (resetTraces) {
average.reset(s.points);
traceModel.clearLiveData();
UpdateAverageCount();
UpdateCalWidget();
}
if(cb) {
cb(res);
}
});
}
}
emit traceModel.SpanChanged(s.f_start, s.f_stop);
}
void VNA::StartImpedanceMatching()
@ -1045,11 +1089,21 @@ void VNA::SetPowerSweepFrequency(double freq)
void VNA::SetPoints(unsigned int points)
{
if(points > Device::Info().limits_maxPoints) {
points = Device::Info().limits_maxPoints;
auto maxPoints = Preferences::getInstance().Acquisition.allowSegmentedSweep ? UINT16_MAX : Device::Info().limits_maxPoints;
if(points > maxPoints) {
points = maxPoints;
} else if (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);
settings.npoints = points;
SettingsChanged();
@ -1161,7 +1215,7 @@ void VNA::StartCalibrationMeasurements(std::set<Calibration::Measurement> m)
cal.clearMeasurements(calMeasurements);
});
// 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)
calMeasuring = true;
});

View File

@ -40,7 +40,8 @@ public:
static QString SweepTypeToString(SweepType sw);
static SweepType SweepTypeFromString(QString s);
using Settings = struct {
class Settings {
public:
SweepType sweepType;
struct {
double start;
@ -57,6 +58,9 @@ public:
double bandwidth;
bool excitingPort1;
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:
@ -101,7 +105,7 @@ private:
bool CalibrationMeasurementActive() { return calWaitFirst || calMeasuring; }
void SetupSCPI();
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 LoadSweepSettings();
void StoreSweepSettings();

View File

@ -233,6 +233,7 @@ void PreferencesDialog::setInitialGUIState()
ui->AcquisitionSuppressPeaks->setChecked(p->Acquisition.suppressPeaks);
ui->AcquisitionAdjustPowerLevel->setChecked(p->Acquisition.adjustPowerLevel);
ui->AcquisitionUseHarmonic->setChecked(p->Acquisition.harmonicMixing);
ui->AcquisitionAllowSegmentedSweep->setChecked(p->Acquisition.allowSegmentedSweep);
ui->AcquisitionUseDFT->setChecked(p->Acquisition.useDFTinSAmode);
ui->AcquisitionDFTlimitRBW->setValue(p->Acquisition.RBWLimitForDFT);
ui->AcquisitionAveragingMode->setCurrentIndex(p->Acquisition.useMedianAveraging ? 1 : 0);
@ -292,6 +293,7 @@ void PreferencesDialog::updateFromGUI()
p->Acquisition.suppressPeaks = ui->AcquisitionSuppressPeaks->isChecked();
p->Acquisition.adjustPowerLevel = ui->AcquisitionAdjustPowerLevel->isChecked();
p->Acquisition.harmonicMixing = ui->AcquisitionUseHarmonic->isChecked();
p->Acquisition.allowSegmentedSweep = ui->AcquisitionAllowSegmentedSweep->isChecked();
p->Acquisition.useDFTinSAmode = ui->AcquisitionUseDFT->isChecked();
p->Acquisition.RBWLimitForDFT = ui->AcquisitionDFTlimitRBW->value();
p->Acquisition.useMedianAveraging = ui->AcquisitionAveragingMode->currentIndex() == 1;

View File

@ -69,6 +69,7 @@ public:
bool suppressPeaks;
bool adjustPowerLevel;
bool harmonicMixing;
bool allowSegmentedSweep;
bool useDFTinSAmode;
double RBWLimitForDFT;
bool useMedianAveraging;
@ -147,6 +148,7 @@ private:
{&Acquisition.suppressPeaks, "Acquisition.suppressPeaks", true},
{&Acquisition.adjustPowerLevel, "Acquisition.adjustPowerLevel", false},
{&Acquisition.harmonicMixing, "Acquisition.harmonicMixing", false},
{&Acquisition.allowSegmentedSweep, "Acquisition.allowSegmentedSweep", false},
{&Acquisition.useDFTinSAmode, "Acquisition.useDFTinSAmode", true},
{&Acquisition.RBWLimitForDFT, "Acquisition.RBWLimitForDFT", 3000.0},
{&Acquisition.useMedianAveraging, "Acquisition.useMedianAveraging", false},

View File

@ -83,7 +83,7 @@
</size>
</property>
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="Startup">
<layout class="QHBoxLayout" name="horizontalLayout_4">
@ -738,6 +738,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="AcquisitionAllowSegmentedSweep">
<property name="text">
<string>Allow segmented sweep (increases maximum number of points)</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>