Added single sweep functionality
This commit is contained in:
parent
53dcff8745
commit
d84d3e80aa
Binary file not shown.
@ -382,6 +382,16 @@ Example (assuming <averaging sweep> = 3):
|
||||
\subsubsection{VNA:ACQuisition:LIMit}
|
||||
\query{Queries the status of limits that maybe set up on any graph}{VNA:ACQuisition:LIMit?}{None}{PASS or FAIL}
|
||||
|
||||
\subsubsection{VNA:ACQuisition:SINGLE}
|
||||
\event{Configures the VNA for single or continuous sweep}{VNA:ACQuisition:SINGLE}{TRUE or FALSE}
|
||||
\query{Queries whether the VNA is set up for single sweep}{VNA:ACQuisition:SINGLE?}{None}{TRUE or FALSE}
|
||||
|
||||
If single sweep is enabled, the acquisition is stopped when the required number of averages have been reached. There are two ways to trigger a new sweep:
|
||||
\begin{itemize}
|
||||
\item Change any sweep setting (e.g. center frequency)
|
||||
\item Issue the command again (i.e. VNA:ACQ:SINGLE TRUE always triggers a new sweep)
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{VNA:STIMulus:LVL}
|
||||
\event{Sets the output power of the stimulus signal when sweep type is frequency}{VNA:STIMulus:LVL}{<power>, in dBm}
|
||||
\query{Queries the currently selected output power}{VNA:STIMulus:LVL?}{None}{power in dBm}
|
||||
@ -608,6 +618,16 @@ Example (assuming <averaging sweep> = 3):
|
||||
\subsubsection{SA:ACQuisition:LIMit}
|
||||
\query{Queries the status of limits that maybe set up on any graph}{SA:ACQuisition:LIMit?}{None}{PASS or FAIL}
|
||||
|
||||
\subsubsection{SA:ACQuisition:SINGLE}
|
||||
\event{Configures the spectrum analyzer for single or continuous sweep}{SA:ACQuisition:SINGLE}{TRUE or FALSE}
|
||||
\query{Queries whether the spectrum analyzer is set up for single sweep}{SA:ACQuisition:SINGLE?}{None}{TRUE or FALSE}
|
||||
|
||||
If single sweep is enabled, the acquisition is stopped when the required number of averages have been reached. There are two ways to trigger a new sweep:
|
||||
\begin{itemize}
|
||||
\item Change any sweep setting (e.g. center frequency)
|
||||
\item Issue the command again (i.e. SA:ACQ:SINGLE TRUE always triggers a new sweep)
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{SA:ACQuisition:SIGid}
|
||||
\event{Enables/disables signal identification}{SA:ACQuisition:SIGid}{<enabled>, option are TRUE, FALSE, 1 or 0}
|
||||
\query{Queries whether signal identification is enabled}{SA:ACQuisition:SIGid?}{None}{TRUE or FALSE}
|
||||
|
@ -256,12 +256,12 @@ bool Device::Configure(Protocol::SweepSettings settings, std::function<void(Tran
|
||||
return SendPacket(p, cb);
|
||||
}
|
||||
|
||||
bool Device::Configure(Protocol::SpectrumAnalyzerSettings settings)
|
||||
bool Device::Configure(Protocol::SpectrumAnalyzerSettings settings, std::function<void (Device::TransmissionResult)> cb)
|
||||
{
|
||||
Protocol::PacketInfo p;
|
||||
p.type = Protocol::PacketType::SpectrumAnalyzerSettings;
|
||||
p.spectrumSettings = settings;
|
||||
return SendPacket(p);
|
||||
return SendPacket(p, cb);
|
||||
}
|
||||
|
||||
bool Device::SetManual(Protocol::ManualControlV1 manual)
|
||||
@ -272,9 +272,9 @@ bool Device::SetManual(Protocol::ManualControlV1 manual)
|
||||
return SendPacket(p);
|
||||
}
|
||||
|
||||
bool Device::SetIdle()
|
||||
bool Device::SetIdle(std::function<void(TransmissionResult)> cb)
|
||||
{
|
||||
return SendCommandWithoutPayload(Protocol::PacketType::SetIdle);
|
||||
return SendCommandWithoutPayload(Protocol::PacketType::SetIdle, cb);
|
||||
}
|
||||
|
||||
bool Device::SendFirmwareChunk(Protocol::FirmwarePacket &fw)
|
||||
@ -285,11 +285,11 @@ bool Device::SendFirmwareChunk(Protocol::FirmwarePacket &fw)
|
||||
return SendPacket(p);
|
||||
}
|
||||
|
||||
bool Device::SendCommandWithoutPayload(Protocol::PacketType type)
|
||||
bool Device::SendCommandWithoutPayload(Protocol::PacketType type, std::function<void(TransmissionResult)> cb)
|
||||
{
|
||||
Protocol::PacketInfo p;
|
||||
p.type = type;
|
||||
return SendPacket(p);
|
||||
return SendPacket(p, cb);
|
||||
}
|
||||
|
||||
std::set<QString> Device::GetDevices()
|
||||
|
@ -60,11 +60,11 @@ public:
|
||||
~Device();
|
||||
bool SendPacket(const Protocol::PacketInfo& packet, std::function<void(TransmissionResult)> cb = nullptr, unsigned int timeout = 500);
|
||||
bool Configure(Protocol::SweepSettings settings, std::function<void(TransmissionResult)> cb = nullptr);
|
||||
bool Configure(Protocol::SpectrumAnalyzerSettings settings);
|
||||
bool Configure(Protocol::SpectrumAnalyzerSettings settings, std::function<void(TransmissionResult)> cb = nullptr);
|
||||
bool SetManual(Protocol::ManualControlV1 manual);
|
||||
bool SetIdle();
|
||||
bool SetIdle(std::function<void(TransmissionResult)> cb = nullptr);
|
||||
bool SendFirmwareChunk(Protocol::FirmwarePacket &fw);
|
||||
bool SendCommandWithoutPayload(Protocol::PacketType type);
|
||||
bool SendCommandWithoutPayload(Protocol::PacketType type, std::function<void(TransmissionResult)> cb = nullptr);
|
||||
QString serial() const;
|
||||
const Protocol::DeviceInfo& Info();
|
||||
static const Protocol::DeviceInfo& Info(Device *dev);
|
||||
|
@ -50,6 +50,7 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
|
||||
central(new TileWidget(traceModel, window))
|
||||
{
|
||||
averages = 1;
|
||||
singleSweep = false;
|
||||
settings = {};
|
||||
normalize.active = false;
|
||||
normalize.measuring = false;
|
||||
@ -83,6 +84,14 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
|
||||
// Create menu entries and connections
|
||||
// Sweep toolbar
|
||||
auto tb_sweep = new QToolBar("Sweep");
|
||||
|
||||
auto bSingle = new QPushButton("Single");
|
||||
bSingle->setToolTip("Single sweep");
|
||||
bSingle->setCheckable(true);
|
||||
connect(bSingle, &QPushButton::toggled, this, &SpectrumAnalyzer::SetSingleSweep);
|
||||
connect(this, &SpectrumAnalyzer::singleSweepChanged, bSingle, &QPushButton::setChecked);
|
||||
tb_sweep->addWidget(bSingle);
|
||||
|
||||
auto eStart = new SIUnitEdit("Hz", " kMG", 6);
|
||||
// calculate width required with expected string length
|
||||
auto width = QFontMetrics(eStart->font()).width("3.00000GHz") + 15;
|
||||
@ -313,6 +322,7 @@ nlohmann::json SpectrumAnalyzer::toJSON()
|
||||
freq["start"] = settings.f_start;
|
||||
freq["stop"] = settings.f_stop;
|
||||
sweep["frequency"] = freq;
|
||||
sweep["single"] = singleSweep;
|
||||
nlohmann::json acq;
|
||||
acq["RBW"] = settings.RBW;
|
||||
acq["window"] = WindowToString((Window) settings.WindowType).toStdString();
|
||||
@ -414,6 +424,7 @@ void SpectrumAnalyzer::fromJSON(nlohmann::json j)
|
||||
EnableNormalization(false);
|
||||
}
|
||||
}
|
||||
SetSingleSweep(sweep.value("single", singleSweep));
|
||||
}
|
||||
}
|
||||
|
||||
@ -425,6 +436,19 @@ void SpectrumAnalyzer::NewDatapoint(Protocol::SpectrumAnalyzerResult d)
|
||||
return;
|
||||
}
|
||||
|
||||
if(changingSettings) {
|
||||
// already setting new sweep settings, ignore incoming points from old settings
|
||||
return;
|
||||
}
|
||||
|
||||
if(singleSweep && average.getLevel() == averages) {
|
||||
changingSettings = true;
|
||||
// single sweep finished
|
||||
window->getDevice()->SetIdle([=](Device::TransmissionResult){
|
||||
changingSettings = false;
|
||||
});
|
||||
}
|
||||
|
||||
if(d.pointNum >= settings.pointNum) {
|
||||
qWarning() << "Ignoring point with too large point number (" << d.pointNum << ")";
|
||||
return;
|
||||
@ -477,6 +501,7 @@ void SpectrumAnalyzer::NewDatapoint(Protocol::SpectrumAnalyzerResult d)
|
||||
|
||||
void SpectrumAnalyzer::SettingsChanged()
|
||||
{
|
||||
changingSettings = true;
|
||||
if(settings.f_stop - settings.f_start >= 1000) {
|
||||
settings.pointNum = 1001;
|
||||
} else {
|
||||
@ -529,7 +554,10 @@ void SpectrumAnalyzer::SettingsChanged()
|
||||
}
|
||||
|
||||
if(window->getDevice() && Mode::getActiveMode() == this) {
|
||||
window->getDevice()->Configure(settings);
|
||||
window->getDevice()->Configure(settings, [=](Device::TransmissionResult res){
|
||||
// device received command
|
||||
changingSettings = false;
|
||||
});
|
||||
}
|
||||
average.reset(settings.pointNum);
|
||||
UpdateAverageCount();
|
||||
@ -620,6 +648,15 @@ void SpectrumAnalyzer::SpanZoomOut()
|
||||
ConstrainAndUpdateFrequencies();
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::SetSingleSweep(bool single)
|
||||
{
|
||||
if(singleSweep != single) {
|
||||
singleSweep = single;
|
||||
emit singleSweepChanged(single);
|
||||
}
|
||||
SettingsChanged();
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::SetRBW(double bandwidth)
|
||||
{
|
||||
if(bandwidth > Device::Info(window->getDevice()).limits_maxRBW) {
|
||||
@ -923,6 +960,17 @@ void SpectrumAnalyzer::SetupSCPI()
|
||||
}, [=](QStringList) -> QString {
|
||||
return settings.SignalID ? "TRUE" : "FALSE";
|
||||
}));
|
||||
scpi_acq->add(new SCPICommand("SINGLE", [=](QStringList params) -> QString {
|
||||
bool single;
|
||||
if(!SCPI::paramToBool(params, 0, single)) {
|
||||
return "ERROR";
|
||||
} else {
|
||||
SetSingleSweep(single);
|
||||
return "";
|
||||
}
|
||||
}, [=](QStringList) -> QString {
|
||||
return singleSweep ? "TRUE" : "FALSE";
|
||||
}));
|
||||
auto scpi_tg = new SCPINode("TRACKing");
|
||||
SCPINode::add(scpi_tg);
|
||||
scpi_tg->add(new SCPICommand("ENable", [=](QStringList params) -> QString {
|
||||
|
@ -63,6 +63,7 @@ private slots:
|
||||
void SetFullSpan();
|
||||
void SpanZoomIn();
|
||||
void SpanZoomOut();
|
||||
void SetSingleSweep(bool single);
|
||||
// Acquisition control
|
||||
void SetRBW(double bandwidth);
|
||||
void SetWindow(Window w);
|
||||
@ -88,7 +89,9 @@ private:
|
||||
void StoreSweepSettings();
|
||||
|
||||
Protocol::SpectrumAnalyzerSettings settings;
|
||||
bool changingSettings;
|
||||
unsigned int averages;
|
||||
bool singleSweep;
|
||||
TraceModel traceModel;
|
||||
TraceWidget *traceWidget;
|
||||
MarkerModel *markerModel;
|
||||
@ -122,6 +125,7 @@ signals:
|
||||
void stopFreqChanged(double freq);
|
||||
void centerFreqChanged(double freq);
|
||||
void spanChanged(double span);
|
||||
void singleSweepChanged(bool single);
|
||||
void RBWChanged(double RBW);
|
||||
void TGStateChanged(bool enabled);
|
||||
void TGPortChanged(int port);
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "vna.h"
|
||||
#include "vna.h"
|
||||
|
||||
#include "unit.h"
|
||||
#include "CustomWidgets/toggleswitch.h"
|
||||
@ -58,6 +58,7 @@ VNA::VNA(AppWindow *window, QString name)
|
||||
central(new TileWidget(traceModel))
|
||||
{
|
||||
averages = 1;
|
||||
singleSweep = false;
|
||||
calValid = false;
|
||||
calMeasuring = false;
|
||||
calWaitFirst = false;
|
||||
@ -257,6 +258,13 @@ VNA::VNA(AppWindow *window, QString name)
|
||||
cbSweepType->addItem("Power");
|
||||
tb_sweep->addWidget(cbSweepType);
|
||||
|
||||
auto bSingle = new QPushButton("Single");
|
||||
bSingle->setToolTip("Single sweep");
|
||||
bSingle->setCheckable(true);
|
||||
connect(bSingle, &QPushButton::toggled, this, &VNA::SetSingleSweep);
|
||||
connect(this, &VNA::singleSweepChanged, bSingle, &QPushButton::setChecked);
|
||||
tb_sweep->addWidget(bSingle);
|
||||
|
||||
auto eStart = new SIUnitEdit("Hz", " kMG", 6);
|
||||
// calculate width required with expected string length
|
||||
auto width = QFontMetrics(eStart->font()).width("3.00000GHz") + 15;
|
||||
@ -719,6 +727,7 @@ nlohmann::json VNA::toJSON()
|
||||
freq["power"] = settings.Freq.excitation_power;
|
||||
freq["log"] = settings.Freq.logSweep;
|
||||
sweep["frequency"] = freq;
|
||||
sweep["single"] = singleSweep;
|
||||
nlohmann::json power;
|
||||
power["start"] = settings.Power.start;
|
||||
power["stop"] = settings.Power.stop;
|
||||
@ -782,6 +791,7 @@ void VNA::fromJSON(nlohmann::json j)
|
||||
type = SweepType::Frequency;
|
||||
}
|
||||
SetSweepType(type);
|
||||
SetSingleSweep(sweep.value("single", singleSweep));
|
||||
}
|
||||
}
|
||||
|
||||
@ -799,6 +809,14 @@ void VNA::NewDatapoint(Protocol::Datapoint d)
|
||||
return;
|
||||
}
|
||||
|
||||
if(singleSweep && average.getLevel() == averages) {
|
||||
changingSettings = true;
|
||||
// single sweep finished
|
||||
window->getDevice()->SetIdle([=](Device::TransmissionResult){
|
||||
changingSettings = false;
|
||||
});
|
||||
}
|
||||
|
||||
bool needsSegmentUpdate = false;
|
||||
if (settings.segments > 1) {
|
||||
// using multiple segments, adjust pointNum
|
||||
@ -1377,6 +1395,17 @@ void VNA::SetupSCPI()
|
||||
scpi_acq->add(new SCPICommand("LIMit", nullptr, [=](QStringList) -> QString {
|
||||
return central->allLimitsPassing() ? "PASS" : "FAIL";
|
||||
}));
|
||||
scpi_acq->add(new SCPICommand("SINGLE", [=](QStringList params) -> QString {
|
||||
bool single;
|
||||
if(!SCPI::paramToBool(params, 0, single)) {
|
||||
return "ERROR";
|
||||
} else {
|
||||
SetSingleSweep(single);
|
||||
return "";
|
||||
}
|
||||
}, [=](QStringList) -> QString {
|
||||
return singleSweep ? "TRUE" : "FALSE";
|
||||
}));
|
||||
auto scpi_stim = new SCPINode("STIMulus");
|
||||
SCPINode::add(scpi_stim);
|
||||
scpi_stim->add(new SCPICommand("LVL", [=](QStringList params) -> QString {
|
||||
@ -1627,6 +1656,15 @@ void VNA::UpdateStatusbar()
|
||||
}
|
||||
}
|
||||
|
||||
void VNA::SetSingleSweep(bool single)
|
||||
{
|
||||
if(singleSweep != single) {
|
||||
singleSweep = single;
|
||||
emit singleSweepChanged(single);
|
||||
}
|
||||
SettingsChanged();
|
||||
}
|
||||
|
||||
bool VNA::LoadCalibration(QString filename)
|
||||
{
|
||||
cal.openFromFile(filename);
|
||||
|
@ -123,6 +123,7 @@ private:
|
||||
private slots:
|
||||
void EnableDeembedding(bool enable);
|
||||
void UpdateStatusbar();
|
||||
void SetSingleSweep(bool single);
|
||||
private:
|
||||
Settings settings;
|
||||
unsigned int averages;
|
||||
@ -130,6 +131,7 @@ private:
|
||||
TraceWidget *traceWidget;
|
||||
MarkerModel *markerModel;
|
||||
Averaging average;
|
||||
bool singleSweep;
|
||||
|
||||
// Calibration
|
||||
Calibration cal;
|
||||
@ -167,6 +169,7 @@ signals:
|
||||
void centerFreqChanged(double freq);
|
||||
void spanChanged(double span);
|
||||
void logSweepChanged(bool log);
|
||||
void singleSweepChanged(bool single);
|
||||
|
||||
void sourceLevelChanged(double level);
|
||||
void pointsChanged(unsigned int points);
|
||||
|
Loading…
Reference in New Issue
Block a user