WIP: rework 2.LO + add dwell time

This commit is contained in:
Jan Käberich 2025-01-02 19:16:53 +01:00
parent a2abc0c2af
commit 24314e2361
33 changed files with 483 additions and 190 deletions

View file

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>488</width>
<height>364</height>
<width>487</width>
<height>356</height>
</rect>
</property>
<property name="windowTitle">
@ -33,7 +33,7 @@
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -141,7 +141,7 @@
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
</property>
</widget>
</item>

View file

@ -428,6 +428,13 @@ bool LibreVNADriver::setVNA(const DeviceDriver::VNASettings &s, std::function<vo
p.settings.cdbm_excitation_start = s.dBmStart * 100;
p.settings.cdbm_excitation_stop = s.dBmStop * 100;
p.settings.stages = s.excitedPorts.size() - 1;
auto dwell_us = s.dwellTime * 1e6;
if(dwell_us < 0) {
dwell_us = 0;
} else if(dwell_us > UINT16_MAX) {
dwell_us = UINT16_MAX;
}
p.settings.dwell_time = dwell_us;
p.settings.suppressPeaks = VNASuppressInvalidPeaks ? 1 : 0;
p.settings.fixedPowerSetting = VNAAdjustPowerLevel || s.dBmStart != s.dBmStop ? 0 : 1;
p.settings.logSweep = s.logSweep ? 1 : 0;
@ -664,7 +671,7 @@ void LibreVNADriver::handleReceivedPacket(const Protocol::PacketInfo &packet)
info.firmware_version = QString::number(packet.info.FW_major)+"."+QString::number(packet.info.FW_minor)+"."+QString::number(packet.info.FW_patch);
info.hardware_version = hardwareVersionToString(packet.info.hardware_version)+" Rev."+QString(packet.info.HW_Revision);
info.supportedFeatures = {
Feature::VNA, Feature::VNAFrequencySweep, Feature::VNALogSweep, Feature::VNAPowerSweep, Feature::VNAZeroSpan,
Feature::VNA, Feature::VNAFrequencySweep, Feature::VNALogSweep, Feature::VNAPowerSweep, Feature::VNAZeroSpan, Feature::VNADwellTime,
Feature::Generator,
Feature::SA, Feature::SATrackingGenerator, Feature::SATrackingOffset,
Feature::ExtRefIn, Feature::ExtRefOut,
@ -677,6 +684,8 @@ void LibreVNADriver::handleReceivedPacket(const Protocol::PacketInfo &packet)
info.Limits.VNA.maxIFBW = packet.info.limits_maxIFBW;
info.Limits.VNA.mindBm = (double) packet.info.limits_cdbm_min / 100;
info.Limits.VNA.maxdBm = (double) packet.info.limits_cdbm_max / 100;
info.Limits.VNA.minDwellTime = (double) packet.info.limits_minDwellTime * 1e-6;
info.Limits.VNA.maxDwellTime = (double) packet.info.limits_maxDwellTime * 1e-6;
info.Limits.Generator.ports = packet.info.num_ports;
info.Limits.Generator.minFreq = packet.info.limits_minFreq;

View file

@ -118,6 +118,8 @@ DeviceDriver::Info::Info()
Limits.VNA.minIFBW = 1;
Limits.VNA.maxIFBW = 100000000;
Limits.VNA.maxPoints = 65535;
Limits.VNA.minDwellTime = 0;
Limits.VNA.maxDwellTime = 1;
Limits.Generator.ports = 2;
Limits.Generator.minFreq = 0;

View file

@ -72,6 +72,7 @@ public:
VNAPowerSweep,
VNAZeroSpan,
VNALogSweep,
VNADwellTime,
// Generator features
Generator,
// Spectrum analyzer features
@ -101,6 +102,8 @@ public:
unsigned int maxPoints;
// Stimulus level limits in dBm
double mindBm, maxdBm;
// dwell time limts
double minDwellTime, maxDwellTime;
} VNA;
struct {
// Number of ports
@ -264,6 +267,8 @@ public:
bool logSweep;
// List of ports that should be excited during the sweep (port count starts at 1)
std::vector<int> excitedPorts;
// amount of time the source stays at each point before taking measurements. Ignore if not supported
double dwellTime;
};
class VNAMeasurement {

View file

@ -72,6 +72,14 @@ namespace Util {
return brightness > 0.6 ? Qt::black : Qt::white;
}
template<typename T> void constrain(T &value, const T &min, const T &max) {
if(value > max) {
value = max;
} else if(value < min) {
value = min;
}
}
/*
* Performs interpolation of a list of sorted values.
* T: type of the elements in the list. Must contain a value by which these elements are sorted in the list.

View file

@ -454,6 +454,14 @@ VNA::VNA(AppWindow *window, QString name)
tb_acq->addWidget(new QLabel("IF BW:"));
tb_acq->addWidget(eBandwidth);
tb_acq->addWidget(new QLabel("Dwell time:"));
acquisitionDwellTime = new SIUnitEdit("s", "um ", 3);
width = QFontMetrics(dbm->font()).horizontalAdvance("100ms") + 20;
acquisitionDwellTime->setFixedWidth(width);
connect(acquisitionDwellTime, &SIUnitEdit::valueChanged, this, &VNA::SetDwellTime);
connect(this, &VNA::dwellTimeChanged, acquisitionDwellTime, &SIUnitEdit::setValueQuiet);
tb_acq->addWidget(acquisitionDwellTime);
tb_acq->addWidget(new QLabel("Averaging:"));
lAverages = new QLabel("0/");
tb_acq->addWidget(lAverages);
@ -1235,6 +1243,17 @@ void VNA::SetSourceLevel(double level)
SettingsChanged();
}
void VNA::SetDwellTime(double time) {
if(time > DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxDwellTime) {
time = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxDwellTime;
} else if(time < DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minDwellTime) {
time = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minDwellTime;
}
emit dwellTimeChanged(time);
settings.dwellTime = time;
SettingsChanged();
}
void VNA::SetStartPower(double level)
{
settings.Power.start = level;
@ -1652,6 +1671,37 @@ void VNA::UpdateCalWidget()
calLabel->setToolTip(getCalToolTip());
}
void VNA::ConstrainAllSettings()
{
auto maxFreq = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxFreq;
auto minFreq = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq;
auto maxPower = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxdBm;
auto minPower = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.mindBm;
auto maxIFBW = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxIFBW;
auto minIFBW = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minIFBW;
auto maxDwell = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxDwellTime;
auto minDwell = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minDwellTime;
auto maxPoints = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxPoints;
Util::constrain(settings.Freq.start, minFreq, maxFreq);
Util::constrain(settings.Freq.stop, minFreq, maxFreq);
Util::constrain(settings.Freq.excitation_power, minPower, maxPower);
Util::constrain(settings.bandwidth, minIFBW, maxIFBW);
Util::constrain(settings.dwellTime, minDwell, maxDwell);
Util::constrain(settings.npoints, (unsigned int) 0, maxPoints);
Util::constrain(settings.Power.frequency, minFreq, maxFreq);
Util::constrain(settings.Power.start, minPower, maxPower);
Util::constrain(settings.Power.stop, minPower, maxPower);
emit startFreqChanged(settings.Freq.start);
emit stopFreqChanged(settings.Freq.stop);
emit sourceLevelChanged(settings.Freq.excitation_power);
emit IFBandwidthChanged(settings.bandwidth);
emit dwellTimeChanged(settings.dwellTime);
emit pointsChanged(settings.npoints);
emit powerSweepFrequencyChanged(settings.Power.frequency);
emit startPowerChanged(settings.Power.start);
emit stopPowerChanged(settings.Power.stop);
}
void VNA::createDefaultTracesAndGraphs(int ports)
{
auto getDefaultColor = [](int ports, int i, int j)->QColor {
@ -1780,6 +1830,16 @@ void VNA::preset()
createDefaultTracesAndGraphs(DeviceDriver::getInfo(window->getDevice()).Limits.VNA.ports);
}
void VNA::deviceInfoUpdated()
{
if(DeviceDriver::getInfo(window->getDevice()).supportedFeatures.count(DeviceDriver::Feature::VNADwellTime)) {
acquisitionDwellTime->setEnabled(true);
} else {
acquisitionDwellTime->setEnabled(false);
}
ConstrainAllSettings();
}
QString VNA::SweepTypeToString(VNA::SweepType sw)
{
switch(sw) {
@ -1904,6 +1964,7 @@ void VNA::ConfigureDevice(bool resetTraces, std::function<void(bool)> cb)
s.dBmStop = stop;
s.logSweep = false;
}
s.dwellTime = settings.dwellTime;
if(window->getDevice() && isActive) {
window->getDevice()->setVNA(s, [=](bool res){
// device received command, reset traces now

View file

@ -38,6 +38,8 @@ public:
void preset() override;
virtual void deviceInfoUpdated() override;
QList<QAction*> getImportOptions() override { return importActions;}
QList<QAction*> getExportOptions() override { return exportActions;}
@ -72,6 +74,7 @@ public:
} Power;
unsigned int npoints;
double bandwidth;
double dwellTime;
std::vector<int> excitedPorts;
// if the number of points is higher than supported by the hardware, the sweep has to be segmented into multiple parts
int segments;
@ -109,6 +112,7 @@ private slots:
void SetLogSweep(bool log);
// Acquisition control
void SetSourceLevel(double level);
void SetDwellTime(double time);
// Power sweep settings
void SetStartPower(double level);
void SetStopPower(double level);
@ -135,6 +139,7 @@ private:
void LoadSweepSettings();
void StoreSweepSettings();
void UpdateCalWidget();
void ConstrainAllSettings();
void createDefaultTracesAndGraphs(int ports);
private slots:
@ -155,6 +160,9 @@ private:
QTimer configurationTimer;
bool configurationTimerResetTraces;
// Toolbar elements
SIUnitEdit *acquisitionDwellTime;
// Calibration
Calibration cal;
bool changingSettings;
@ -205,6 +213,7 @@ signals:
void pointsChanged(unsigned int points);
void IFBandwidthChanged(double bandwidth);
void averagingChanged(unsigned int averages);
void dwellTimeChanged(double time);
void startPowerChanged(double level);
void stopPowerChanged(double level);