2020-08-31 04:03:41 +08:00
# include "vna.h"
# include <QGridLayout>
# include <QVBoxLayout>
# include <QHBoxLayout>
# include <QPushButton>
# include <math.h>
# include <QToolBar>
# include <QMenu>
# include <QToolButton>
# include <QActionGroup>
# include <QSpinBox>
# include <QCheckBox>
# include <QComboBox>
# include <QSettings>
# include <algorithm>
# include <QMessageBox>
# include <QFileDialog>
# include <QFile>
# include <iostream>
# include <fstream>
# include <QDateTime>
# include "unit.h"
2020-09-20 16:13:06 +08:00
# include <queue>
2020-08-31 04:03:41 +08:00
# include "CustomWidgets/toggleswitch.h"
# include "Device/manualcontroldialog.h"
# include "Traces/tracemodel.h"
2020-11-25 01:08:00 +08:00
# include "tracewidgetvna.h"
2020-08-31 04:03:41 +08:00
# include "Traces/tracesmithchart.h"
2020-10-28 05:07:14 +08:00
# include "Traces/tracexyplot.h"
2020-08-31 04:03:41 +08:00
# include "Traces/traceimportdialog.h"
# include "CustomWidgets/tilewidget.h"
2020-09-13 20:44:45 +08:00
# include "CustomWidgets/siunitedit.h"
2020-08-31 04:03:41 +08:00
# include <QDockWidget>
2021-06-19 21:33:43 +08:00
# include "Traces/Marker/markerwidget.h"
2020-08-31 04:03:41 +08:00
# include "Tools/impedancematchdialog.h"
# include "Calibration/calibrationtracedialog.h"
# include "ui_main.h"
# include "Device/firmwareupdatedialog.h"
2020-09-12 05:07:15 +08:00
# include "preferences.h"
2020-09-13 20:44:45 +08:00
# include "Generator/signalgenwidget.h"
2020-09-12 05:07:15 +08:00
# include <QDesktopWidget>
# include <QApplication>
2020-09-13 20:44:45 +08:00
# include <QActionGroup>
2020-11-11 02:16:16 +08:00
# include <QErrorMessage>
# include "CustomWidgets/informationbox.h"
2020-11-22 07:41:42 +08:00
# include <QDebug>
2021-03-12 04:52:58 +08:00
# include "Deembedding/manualdeembeddingdialog.h"
# include "Calibration/manualcalibrationdialog.h"
2020-08-31 04:03:41 +08:00
2020-09-13 20:44:45 +08:00
VNA : : VNA ( AppWindow * window )
: Mode ( window , " Vector Network Analyzer " ) ,
2021-04-11 06:10:22 +08:00
SCPINode ( " VNA " ) ,
2021-02-11 23:59:59 +08:00
deembedding ( traceModel ) ,
2020-09-13 20:44:45 +08:00
central ( new TileWidget ( traceModel ) )
2020-08-31 04:03:41 +08:00
{
averages = 1 ;
calValid = false ;
calMeasuring = false ;
calDialog . reset ( ) ;
2020-12-08 03:21:24 +08:00
calEdited = false ;
2020-08-31 04:03:41 +08:00
2020-09-12 05:07:15 +08:00
// Create default traces
auto tS11 = new Trace ( " S11 " , Qt : : yellow ) ;
tS11 - > fromLivedata ( Trace : : LivedataType : : Overwrite , Trace : : LiveParameter : : S11 ) ;
traceModel . addTrace ( tS11 ) ;
auto tS12 = new Trace ( " S12 " , Qt : : blue ) ;
tS12 - > fromLivedata ( Trace : : LivedataType : : Overwrite , Trace : : LiveParameter : : S12 ) ;
traceModel . addTrace ( tS12 ) ;
auto tS21 = new Trace ( " S21 " , Qt : : green ) ;
tS21 - > fromLivedata ( Trace : : LivedataType : : Overwrite , Trace : : LiveParameter : : S21 ) ;
traceModel . addTrace ( tS21 ) ;
auto tS22 = new Trace ( " S22 " , Qt : : red ) ;
tS22 - > fromLivedata ( Trace : : LivedataType : : Overwrite , Trace : : LiveParameter : : S22 ) ;
traceModel . addTrace ( tS22 ) ;
auto tracesmith1 = new TraceSmithChart ( traceModel ) ;
tracesmith1 - > enableTrace ( tS11 , true ) ;
2021-06-29 10:47:02 +08:00
2020-09-12 05:07:15 +08:00
auto tracesmith2 = new TraceSmithChart ( traceModel ) ;
tracesmith2 - > enableTrace ( tS22 , true ) ;
2020-10-28 05:08:05 +08:00
auto traceXY1 = new TraceXYPlot ( traceModel ) ;
traceXY1 - > enableTrace ( tS12 , true ) ;
auto traceXY2 = new TraceXYPlot ( traceModel ) ;
traceXY2 - > enableTrace ( tS21 , true ) ;
2020-09-12 05:07:15 +08:00
2021-06-29 10:47:02 +08:00
connect ( this , & VNA : : graphColorsChanged , [ = ] ( ) {
for ( auto p : TracePlot : : getPlots ( ) ) {
p - > updateGraphColors ( ) ;
}
} ) ;
2020-09-16 05:22:08 +08:00
connect ( & traceModel , & TraceModel : : requiredExcitation , this , & VNA : : ExcitationRequired ) ;
2020-09-13 20:44:45 +08:00
central - > splitVertically ( ) ;
central - > Child1 ( ) - > splitHorizontally ( ) ;
central - > Child2 ( ) - > splitHorizontally ( ) ;
central - > Child1 ( ) - > Child1 ( ) - > setPlot ( tracesmith1 ) ;
2020-10-28 05:08:05 +08:00
central - > Child1 ( ) - > Child2 ( ) - > setPlot ( traceXY1 ) ;
central - > Child2 ( ) - > Child1 ( ) - > setPlot ( traceXY2 ) ;
2020-09-13 20:44:45 +08:00
central - > Child2 ( ) - > Child2 ( ) - > setPlot ( tracesmith2 ) ;
// Create menu entries and connections
2020-11-01 06:03:34 +08:00
auto calMenu = new QMenu ( " Calibration " , window ) ;
2020-09-13 20:44:45 +08:00
window - > menuBar ( ) - > insertMenu ( window - > getUi ( ) - > menuWindow - > menuAction ( ) , calMenu ) ;
actions . insert ( calMenu - > menuAction ( ) ) ;
2020-11-11 02:16:16 +08:00
auto calLoad = calMenu - > addAction ( " Load " ) ;
saveCal = calMenu - > addAction ( " Save " ) ;
calMenu - > addSeparator ( ) ;
saveCal - > setEnabled ( false ) ;
connect ( calLoad , & QAction : : triggered , [ = ] ( ) {
2020-11-15 03:43:36 +08:00
cal . openFromFile ( ) ;
if ( cal . getType ( ) = = Calibration : : Type : : None ) {
DisableCalibration ( ) ;
} else {
2020-11-11 02:16:16 +08:00
ApplyCalibration ( cal . getType ( ) ) ;
}
2020-12-08 03:21:24 +08:00
calEdited = false ;
2020-11-11 02:16:16 +08:00
} ) ;
connect ( saveCal , & QAction : : triggered , [ = ] ( ) {
2020-12-08 03:21:24 +08:00
if ( cal . saveToFile ( ) ) {
calEdited = false ;
}
2020-11-11 02:16:16 +08:00
} ) ;
2020-09-13 20:44:45 +08:00
auto calDisable = calMenu - > addAction ( " Disabled " ) ;
calDisable - > setCheckable ( true ) ;
calDisable - > setChecked ( true ) ;
calMenu - > addSeparator ( ) ;
2020-11-11 02:16:16 +08:00
auto calData = calMenu - > addAction ( " Calibration Measurements " ) ;
2020-09-13 20:44:45 +08:00
connect ( calData , & QAction : : triggered , [ = ] ( ) {
2020-10-30 02:27:04 +08:00
StartCalibrationDialog ( ) ;
2020-08-31 04:03:41 +08:00
} ) ;
2020-09-13 20:44:45 +08:00
auto calEditKit = calMenu - > addAction ( " Edit Calibration Kit " ) ;
connect ( calEditKit , & QAction : : triggered , [ = ] ( ) {
2020-11-15 03:43:36 +08:00
cal . getCalibrationKit ( ) . edit ( [ = ] ( ) {
if ( calValid ) {
ApplyCalibration ( cal . getType ( ) ) ;
}
} ) ;
2020-09-13 20:44:45 +08:00
} ) ;
2020-11-28 01:18:31 +08:00
calMenu - > addSeparator ( ) ;
auto calImportTerms = calMenu - > addAction ( " Import error terms as traces " ) ;
calImportTerms - > setEnabled ( false ) ;
connect ( calImportTerms , & QAction : : triggered , [ = ] ( ) {
auto import = new TraceImportDialog ( traceModel , cal . getErrorTermTraces ( ) ) ;
import - > show ( ) ;
} ) ;
auto calImportMeas = calMenu - > addAction ( " Import measurements as traces " ) ;
calImportMeas - > setEnabled ( false ) ;
connect ( calImportMeas , & QAction : : triggered , [ = ] ( ) {
auto import = new TraceImportDialog ( traceModel , cal . getMeasurementTraces ( ) ) ;
import - > show ( ) ;
} ) ;
2021-03-12 04:52:58 +08:00
calMenu - > addSeparator ( ) ;
auto calApplyToTraces = calMenu - > addAction ( " Apply to traces... " ) ;
calApplyToTraces - > setEnabled ( false ) ;
connect ( calApplyToTraces , & QAction : : triggered , [ = ] ( ) {
auto manualCalibration = new ManualCalibrationDialog ( traceModel , & cal ) ;
manualCalibration - > show ( ) ;
} ) ;
2021-01-30 04:44:44 +08:00
// portExtension.setCalkit(&cal.getCalibrationKit());
2020-09-13 20:44:45 +08:00
2021-03-12 04:52:58 +08:00
// De-embedding menu
auto menuDeembed = new QMenu ( " De-embedding " , window ) ;
window - > menuBar ( ) - > insertMenu ( window - > getUi ( ) - > menuWindow - > menuAction ( ) , menuDeembed ) ;
2021-03-23 04:28:30 +08:00
actions . insert ( menuDeembed - > menuAction ( ) ) ;
2021-03-12 04:52:58 +08:00
auto confDeembed = menuDeembed - > addAction ( " Setup... " ) ;
connect ( confDeembed , & QAction : : triggered , & deembedding , & Deembedding : : configure ) ;
enableDeembeddingAction = menuDeembed - > addAction ( " De-embed VNA samples " ) ;
enableDeembeddingAction - > setCheckable ( true ) ;
enableDeembeddingAction - > setEnabled ( false ) ;
connect ( enableDeembeddingAction , & QAction : : toggled , this , & VNA : : EnableDeembedding ) ;
auto manualDeembed = menuDeembed - > addAction ( " De-embed traces... " ) ;
manualDeembed - > setEnabled ( false ) ;
connect ( manualDeembed , & QAction : : triggered , [ = ] ( ) {
auto manualDeembedding = new ManualDeembeddingDialog ( traceModel , & deembedding ) ;
manualDeembedding - > show ( ) ;
} ) ;
connect ( & deembedding , & Deembedding : : optionAdded , [ = ] ( ) {
EnableDeembedding ( true ) ;
enableDeembeddingAction - > setEnabled ( true ) ;
manualDeembed - > setEnabled ( true ) ;
} ) ;
connect ( & deembedding , & Deembedding : : allOptionsCleared , [ = ] ( ) {
EnableDeembedding ( false ) ;
enableDeembeddingAction - > setEnabled ( false ) ;
manualDeembed - > setEnabled ( false ) ;
} ) ;
2020-09-13 20:44:45 +08:00
// Tools menu
2020-11-01 06:03:34 +08:00
auto toolsMenu = new QMenu ( " Tools " , window ) ;
2020-09-13 20:44:45 +08:00
window - > menuBar ( ) - > insertMenu ( window - > getUi ( ) - > menuWindow - > menuAction ( ) , toolsMenu ) ;
actions . insert ( toolsMenu - > menuAction ( ) ) ;
auto impedanceMatching = toolsMenu - > addAction ( " Impedance Matching " ) ;
connect ( impedanceMatching , & QAction : : triggered , this , & VNA : : StartImpedanceMatching ) ;
2020-11-01 06:03:34 +08:00
defaultCalMenu = new QMenu ( " Default Calibration " , window ) ;
2020-09-14 00:01:32 +08:00
assignDefaultCal = defaultCalMenu - > addAction ( " Assign... " ) ;
removeDefaultCal = defaultCalMenu - > addAction ( " Remove " ) ;
removeDefaultCal - > setEnabled ( false ) ;
defaultCalMenu - > setEnabled ( false ) ;
actions . insert ( window - > getUi ( ) - > menuDevice - > addSeparator ( ) ) ;
window - > getUi ( ) - > menuDevice - > addMenu ( defaultCalMenu ) ;
actions . insert ( defaultCalMenu - > menuAction ( ) ) ;
connect ( assignDefaultCal , & QAction : : triggered , [ = ] ( ) {
2020-09-13 20:44:45 +08:00
if ( window - > getDevice ( ) ) {
auto key = " DefaultCalibration " + window - > getDevice ( ) - > serial ( ) ;
2020-08-31 04:03:41 +08:00
QSettings settings ;
auto filename = QFileDialog : : getOpenFileName ( nullptr , " Load calibration data " , settings . value ( key ) . toString ( ) , " Calibration files (*.cal) " , nullptr , QFileDialog : : DontUseNativeDialog ) ;
if ( ! filename . isEmpty ( ) ) {
settings . setValue ( key , filename ) ;
2020-09-14 00:01:32 +08:00
removeDefaultCal - > setEnabled ( true ) ;
2020-08-31 04:03:41 +08:00
}
}
} ) ;
2020-09-14 00:01:32 +08:00
connect ( removeDefaultCal , & QAction : : triggered , [ = ] ( ) {
2020-08-31 04:03:41 +08:00
QSettings settings ;
2020-09-13 20:44:45 +08:00
settings . remove ( " DefaultCalibration " + window - > getDevice ( ) - > serial ( ) ) ;
2020-09-14 00:01:32 +08:00
removeDefaultCal - > setEnabled ( false ) ;
2020-08-31 04:03:41 +08:00
} ) ;
// Sweep toolbar
2020-09-13 20:44:45 +08:00
auto tb_sweep = new QToolBar ( " Sweep " ) ;
2021-07-10 00:42:22 +08:00
std : : vector < QAction * > frequencySweepActions ;
std : : vector < QAction * > powerSweepActions ;
tb_sweep - > addWidget ( new QLabel ( " Sweep type: " ) ) ;
auto cbSweepType = new QComboBox ( ) ;
cbSweepType - > addItem ( " Frequency " ) ;
cbSweepType - > addItem ( " Power " ) ;
tb_sweep - > addWidget ( cbSweepType ) ;
2020-08-31 04:03:41 +08:00
auto eStart = new SIUnitEdit ( " Hz " , " kMG " , 6 ) ;
2020-11-23 19:43:24 +08:00
// calculate width required with expected string length
auto width = QFontMetrics ( eStart - > font ( ) ) . width ( " 3.00000GHz " ) + 15 ;
eStart - > setFixedWidth ( width ) ;
2020-08-31 04:03:41 +08:00
eStart - > setToolTip ( " Start frequency " ) ;
connect ( eStart , & SIUnitEdit : : valueChanged , this , & VNA : : SetStartFreq ) ;
connect ( this , & VNA : : startFreqChanged , eStart , & SIUnitEdit : : setValueQuiet ) ;
2021-07-10 00:42:22 +08:00
frequencySweepActions . push_back ( tb_sweep - > addWidget ( new QLabel ( " Start: " ) ) ) ;
frequencySweepActions . push_back ( tb_sweep - > addWidget ( eStart ) ) ;
2020-08-31 04:03:41 +08:00
auto eCenter = new SIUnitEdit ( " Hz " , " kMG " , 6 ) ;
2020-11-23 19:43:24 +08:00
eCenter - > setFixedWidth ( width ) ;
2020-08-31 04:03:41 +08:00
eCenter - > setToolTip ( " Center frequency " ) ;
connect ( eCenter , & SIUnitEdit : : valueChanged , this , & VNA : : SetCenterFreq ) ;
connect ( this , & VNA : : centerFreqChanged , eCenter , & SIUnitEdit : : setValueQuiet ) ;
2021-07-10 00:42:22 +08:00
frequencySweepActions . push_back ( tb_sweep - > addWidget ( new QLabel ( " Center: " ) ) ) ;
frequencySweepActions . push_back ( tb_sweep - > addWidget ( eCenter ) ) ;
2020-08-31 04:03:41 +08:00
auto eStop = new SIUnitEdit ( " Hz " , " kMG " , 6 ) ;
2020-11-23 19:43:24 +08:00
eStop - > setFixedWidth ( width ) ;
2020-08-31 04:03:41 +08:00
eStop - > setToolTip ( " Stop frequency " ) ;
connect ( eStop , & SIUnitEdit : : valueChanged , this , & VNA : : SetStopFreq ) ;
connect ( this , & VNA : : stopFreqChanged , eStop , & SIUnitEdit : : setValueQuiet ) ;
2021-07-10 00:42:22 +08:00
frequencySweepActions . push_back ( tb_sweep - > addWidget ( new QLabel ( " Stop: " ) ) ) ;
frequencySweepActions . push_back ( tb_sweep - > addWidget ( eStop ) ) ;
2020-08-31 04:03:41 +08:00
auto eSpan = new SIUnitEdit ( " Hz " , " kMG " , 6 ) ;
2020-11-23 19:43:24 +08:00
eSpan - > setFixedWidth ( width ) ;
2020-08-31 04:03:41 +08:00
eSpan - > setToolTip ( " Span " ) ;
connect ( eSpan , & SIUnitEdit : : valueChanged , this , & VNA : : SetSpan ) ;
connect ( this , & VNA : : spanChanged , eSpan , & SIUnitEdit : : setValueQuiet ) ;
2021-07-10 00:42:22 +08:00
frequencySweepActions . push_back ( tb_sweep - > addWidget ( new QLabel ( " Span: " ) ) ) ;
frequencySweepActions . push_back ( tb_sweep - > addWidget ( eSpan ) ) ;
2020-08-31 04:03:41 +08:00
2020-10-25 06:12:46 +08:00
auto bFull = new QPushButton ( QIcon : : fromTheme ( " zoom-fit-best " , QIcon ( " :/icons/zoom-fit.png " ) ) , " " ) ;
2020-08-31 04:03:41 +08:00
bFull - > setToolTip ( " Full span " ) ;
connect ( bFull , & QPushButton : : clicked , this , & VNA : : SetFullSpan ) ;
2021-07-10 00:42:22 +08:00
frequencySweepActions . push_back ( tb_sweep - > addWidget ( bFull ) ) ;
2020-08-31 04:03:41 +08:00
2020-10-25 06:12:46 +08:00
auto bZoomIn = new QPushButton ( QIcon : : fromTheme ( " zoom-in " , QIcon ( " :/icons/zoom-in.png " ) ) , " " ) ;
2020-08-31 04:03:41 +08:00
bZoomIn - > setToolTip ( " Zoom in " ) ;
connect ( bZoomIn , & QPushButton : : clicked , this , & VNA : : SpanZoomIn ) ;
2021-07-10 00:42:22 +08:00
frequencySweepActions . push_back ( tb_sweep - > addWidget ( bZoomIn ) ) ;
2020-08-31 04:03:41 +08:00
2020-10-25 06:12:46 +08:00
auto bZoomOut = new QPushButton ( QIcon : : fromTheme ( " zoom-out " , QIcon ( " :/icons/zoom-out.png " ) ) , " " ) ;
2020-08-31 04:03:41 +08:00
bZoomOut - > setToolTip ( " Zoom out " ) ;
connect ( bZoomOut , & QPushButton : : clicked , this , & VNA : : SpanZoomOut ) ;
2021-07-10 00:42:22 +08:00
frequencySweepActions . push_back ( tb_sweep - > addWidget ( bZoomOut ) ) ;
// power sweep widgets
auto sbPowerLow = new QDoubleSpinBox ( ) ;
width = QFontMetrics ( sbPowerLow - > font ( ) ) . width ( " -30.00dBm " ) + 20 ;
sbPowerLow - > setFixedWidth ( width ) ;
sbPowerLow - > setRange ( - 100.0 , 100.0 ) ;
sbPowerLow - > setSingleStep ( 0.25 ) ;
sbPowerLow - > setSuffix ( " dbm " ) ;
sbPowerLow - > setToolTip ( " Stimulus level " ) ;
sbPowerLow - > setKeyboardTracking ( false ) ;
2021-07-10 04:26:44 +08:00
connect ( sbPowerLow , qOverload < double > ( & QDoubleSpinBox : : valueChanged ) , this , & VNA : : SetStartPower ) ;
connect ( this , & VNA : : startPowerChanged , sbPowerLow , & QDoubleSpinBox : : setValue ) ;
2021-07-10 00:42:22 +08:00
powerSweepActions . push_back ( tb_sweep - > addWidget ( new QLabel ( " From: " ) ) ) ;
powerSweepActions . push_back ( tb_sweep - > addWidget ( sbPowerLow ) ) ;
auto sbPowerHigh = new QDoubleSpinBox ( ) ;
width = QFontMetrics ( sbPowerHigh - > font ( ) ) . width ( " -30.00dBm " ) + 20 ;
sbPowerHigh - > setFixedWidth ( width ) ;
sbPowerHigh - > setRange ( - 100.0 , 100.0 ) ;
sbPowerHigh - > setSingleStep ( 0.25 ) ;
sbPowerHigh - > setSuffix ( " dbm " ) ;
sbPowerHigh - > setToolTip ( " Stimulus level " ) ;
sbPowerHigh - > setKeyboardTracking ( false ) ;
2021-07-10 04:26:44 +08:00
connect ( sbPowerHigh , qOverload < double > ( & QDoubleSpinBox : : valueChanged ) , this , & VNA : : SetStopPower ) ;
connect ( this , & VNA : : stopPowerChanged , sbPowerHigh , & QDoubleSpinBox : : setValue ) ;
2021-07-10 00:42:22 +08:00
powerSweepActions . push_back ( tb_sweep - > addWidget ( new QLabel ( " To: " ) ) ) ;
powerSweepActions . push_back ( tb_sweep - > addWidget ( sbPowerHigh ) ) ;
auto ePowerFreq = new SIUnitEdit ( " Hz " , " kMG " , 6 ) ;
width = QFontMetrics ( ePowerFreq - > font ( ) ) . width ( " 3.00000GHz " ) + 15 ;
ePowerFreq - > setFixedWidth ( width ) ;
ePowerFreq - > setToolTip ( " Start frequency " ) ;
2021-07-10 04:26:44 +08:00
connect ( ePowerFreq , & SIUnitEdit : : valueChanged , this , & VNA : : SetPowerSweepFrequency ) ;
connect ( this , & VNA : : powerSweepFrequencyChanged , ePowerFreq , & SIUnitEdit : : setValueQuiet ) ;
2021-07-10 00:42:22 +08:00
powerSweepActions . push_back ( tb_sweep - > addWidget ( new QLabel ( " at: " ) ) ) ;
powerSweepActions . push_back ( tb_sweep - > addWidget ( ePowerFreq ) ) ;
2020-08-31 04:03:41 +08:00
2020-09-13 20:44:45 +08:00
window - > addToolBar ( tb_sweep ) ;
toolbars . insert ( tb_sweep ) ;
2020-08-31 04:03:41 +08:00
// Acquisition toolbar
2020-09-13 20:44:45 +08:00
auto tb_acq = new QToolBar ( " Acquisition " ) ;
2020-08-31 04:03:41 +08:00
auto dbm = new QDoubleSpinBox ( ) ;
2020-11-23 19:43:24 +08:00
width = QFontMetrics ( dbm - > font ( ) ) . width ( " -30.00dBm " ) + 20 ;
dbm - > setFixedWidth ( width ) ;
2020-09-30 05:03:20 +08:00
dbm - > setRange ( - 100.0 , 100.0 ) ;
2020-08-31 04:03:41 +08:00
dbm - > setSingleStep ( 0.25 ) ;
dbm - > setSuffix ( " dbm " ) ;
dbm - > setToolTip ( " Stimulus level " ) ;
2020-11-13 01:56:39 +08:00
dbm - > setKeyboardTracking ( false ) ;
2020-08-31 04:03:41 +08:00
connect ( dbm , qOverload < double > ( & QDoubleSpinBox : : valueChanged ) , this , & VNA : : SetSourceLevel ) ;
connect ( this , & VNA : : sourceLevelChanged , dbm , & QDoubleSpinBox : : setValue ) ;
2021-07-10 00:42:22 +08:00
frequencySweepActions . push_back ( tb_acq - > addWidget ( new QLabel ( " Level: " ) ) ) ;
frequencySweepActions . push_back ( tb_acq - > addWidget ( dbm ) ) ;
2020-08-31 04:03:41 +08:00
auto points = new QSpinBox ( ) ;
points - > setFixedWidth ( 55 ) ;
2020-11-13 01:56:39 +08:00
points - > setRange ( 1 , 9999 ) ;
2020-08-31 04:03:41 +08:00
points - > setSingleStep ( 100 ) ;
points - > setToolTip ( " Points/sweep " ) ;
2020-11-13 01:56:39 +08:00
points - > setKeyboardTracking ( false ) ;
2020-08-31 04:03:41 +08:00
connect ( points , qOverload < int > ( & QSpinBox : : valueChanged ) , this , & VNA : : SetPoints ) ;
2020-11-07 20:22:10 +08:00
connect ( this , & VNA : : pointsChanged , [ = ] ( int p ) {
points - > blockSignals ( true ) ;
points - > setValue ( p ) ;
points - > blockSignals ( false ) ;
} ) ;
2020-08-31 04:03:41 +08:00
tb_acq - > addWidget ( new QLabel ( " Points: " ) ) ;
tb_acq - > addWidget ( points ) ;
auto eBandwidth = new SIUnitEdit ( " Hz " , " k " , 3 ) ;
eBandwidth - > setFixedWidth ( 70 ) ;
eBandwidth - > setToolTip ( " IF bandwidth " ) ;
connect ( eBandwidth , & SIUnitEdit : : valueChanged , this , & VNA : : SetIFBandwidth ) ;
connect ( this , & VNA : : IFBandwidthChanged , eBandwidth , & SIUnitEdit : : setValueQuiet ) ;
tb_acq - > addWidget ( new QLabel ( " IF BW: " ) ) ;
tb_acq - > addWidget ( eBandwidth ) ;
2020-10-23 17:39:07 +08:00
tb_acq - > addWidget ( new QLabel ( " Averaging: " ) ) ;
lAverages = new QLabel ( " 0/ " ) ;
tb_acq - > addWidget ( lAverages ) ;
auto sbAverages = new QSpinBox ;
sbAverages - > setRange ( 1 , 99 ) ;
sbAverages - > setFixedWidth ( 40 ) ;
connect ( sbAverages , qOverload < int > ( & QSpinBox : : valueChanged ) , this , & VNA : : SetAveraging ) ;
connect ( this , & VNA : : averagingChanged , sbAverages , & QSpinBox : : setValue ) ;
tb_acq - > addWidget ( sbAverages ) ;
2020-09-13 20:44:45 +08:00
window - > addToolBar ( tb_acq ) ;
toolbars . insert ( tb_acq ) ;
2020-08-31 04:03:41 +08:00
// Calibration toolbar (and populate calibration menu)
auto tb_cal = new QToolBar ( " Calibration " ) ;
2020-12-08 00:58:13 +08:00
calLabel = new QLabel ( " Calibration: " ) ;
UpdateCalWidget ( ) ;
tb_cal - > addWidget ( calLabel ) ;
2020-08-31 04:03:41 +08:00
auto cbEnableCal = new QCheckBox ;
tb_cal - > addWidget ( cbEnableCal ) ;
auto cbType = new QComboBox ( ) ;
auto calMenuGroup = new QActionGroup ( this ) ;
2020-09-13 20:44:45 +08:00
calMenuGroup - > addAction ( calDisable ) ;
2020-08-31 04:03:41 +08:00
for ( auto type : Calibration : : Types ( ) ) {
cbType - > addItem ( Calibration : : TypeToString ( type ) , ( int ) type ) ;
2020-11-01 06:03:34 +08:00
auto menuAction = new QAction ( Calibration : : TypeToString ( type ) , calMenu ) ;
2020-08-31 04:03:41 +08:00
calMenuGroup - > addAction ( menuAction ) ;
connect ( menuAction , & QAction : : triggered , [ = ] ( ) {
ApplyCalibration ( type ) ;
} ) ;
connect ( this , & VNA : : CalibrationApplied , [ = ] ( Calibration : : Type applied ) {
if ( type = = applied ) {
menuAction - > setChecked ( true ) ;
}
} ) ;
menuAction - > setCheckable ( true ) ;
2020-09-13 20:44:45 +08:00
calMenu - > insertAction ( calDisable , menuAction ) ;
2020-08-31 04:03:41 +08:00
}
auto calToolbarLambda = [ = ] ( ) {
if ( cbEnableCal - > isChecked ( ) ) {
// Get requested calibration type from combobox
ApplyCalibration ( ( Calibration : : Type ) cbType - > itemData ( cbType - > currentIndex ( ) ) . toInt ( ) ) ;
} else {
DisableCalibration ( ) ;
}
} ;
// Calibration connections
connect ( cbEnableCal , & QCheckBox : : stateChanged , calToolbarLambda ) ;
connect ( cbType , qOverload < int > ( & QComboBox : : currentIndexChanged ) , calToolbarLambda ) ;
connect ( this , & VNA : : CalibrationDisabled , [ = ] ( ) {
cbType - > blockSignals ( true ) ;
cbEnableCal - > blockSignals ( true ) ;
2020-09-13 20:44:45 +08:00
calDisable - > setChecked ( true ) ;
2020-08-31 04:03:41 +08:00
cbEnableCal - > setCheckState ( Qt : : CheckState : : Unchecked ) ;
2020-12-08 00:58:13 +08:00
// visually indicate loss of calibration
// cal. file unknown at this moment
UpdateCalWidget ( ) ;
2020-08-31 04:03:41 +08:00
cbType - > blockSignals ( false ) ;
cbEnableCal - > blockSignals ( false ) ;
2020-11-28 01:18:31 +08:00
calImportTerms - > setEnabled ( false ) ;
calImportMeas - > setEnabled ( false ) ;
2021-03-12 04:52:58 +08:00
calApplyToTraces - > setEnabled ( false ) ;
2020-11-11 02:16:16 +08:00
saveCal - > setEnabled ( false ) ;
2020-08-31 04:03:41 +08:00
} ) ;
2020-09-13 20:44:45 +08:00
connect ( calDisable , & QAction : : triggered , this , & VNA : : DisableCalibration ) ;
2020-08-31 04:03:41 +08:00
connect ( this , & VNA : : CalibrationApplied , [ = ] ( Calibration : : Type applied ) {
cbType - > blockSignals ( true ) ;
cbEnableCal - > blockSignals ( true ) ;
for ( int i = 0 ; i < cbType - > count ( ) ; i + + ) {
if ( cbType - > itemData ( i ) . toInt ( ) = = ( int ) applied ) {
cbType - > setCurrentIndex ( i ) ;
break ;
}
}
cbEnableCal - > setCheckState ( Qt : : CheckState : : Checked ) ;
2020-12-08 00:58:13 +08:00
// restore default look of widget
// on hover, show name of active cal. file
UpdateCalWidget ( ) ;
2020-08-31 04:03:41 +08:00
cbType - > blockSignals ( false ) ;
cbEnableCal - > blockSignals ( false ) ;
2020-11-28 01:18:31 +08:00
calImportTerms - > setEnabled ( true ) ;
calImportMeas - > setEnabled ( true ) ;
2021-03-12 04:52:58 +08:00
calApplyToTraces - > setEnabled ( true ) ;
2020-11-11 02:16:16 +08:00
saveCal - > setEnabled ( true ) ;
2020-08-31 04:03:41 +08:00
} ) ;
tb_cal - > addWidget ( cbType ) ;
2020-09-13 20:44:45 +08:00
window - > addToolBar ( tb_cal ) ;
2021-07-10 04:26:44 +08:00
auto configureToolbarForFrequencySweep = [ = ] ( ) {
for ( auto a : frequencySweepActions ) {
a - > setVisible ( true ) ;
}
for ( auto a : powerSweepActions ) {
a - > setVisible ( false ) ;
}
// enable calibration menu entries
calData - > setEnabled ( true ) ;
} ;
auto configureToolbarForPowerSweep = [ = ] ( ) {
for ( auto a : frequencySweepActions ) {
a - > setVisible ( false ) ;
}
for ( auto a : powerSweepActions ) {
a - > setVisible ( true ) ;
}
// disable calibration menu entries
calData - > setEnabled ( false ) ;
} ;
connect ( cbSweepType , qOverload < int > ( & QComboBox : : currentIndexChanged ) , [ = ] ( int index ) {
SetSweepType ( ( SweepType ) index ) ;
} ) ;
connect ( this , & VNA : : sweepTypeChanged , [ = ] ( SweepType sw ) {
if ( sw = = SweepType : : Frequency ) {
configureToolbarForFrequencySweep ( ) ;
} else if ( sw = = SweepType : : Power ) {
configureToolbarForPowerSweep ( ) ;
}
2021-07-10 20:04:05 +08:00
cbSweepType - > setCurrentIndex ( ( int ) sw ) ;
2021-07-10 04:26:44 +08:00
} ) ;
2021-10-11 21:22:08 +08:00
configureToolbarForFrequencySweep ( ) ;
2021-07-10 04:26:44 +08:00
// initial setup is frequency sweep
2021-07-15 03:47:43 +08:00
configureToolbarForFrequencySweep ( ) ;
2021-07-10 04:26:44 +08:00
SetSweepType ( SweepType : : Frequency ) ;
2020-09-13 20:44:45 +08:00
toolbars . insert ( tb_cal ) ;
2021-01-30 04:44:44 +08:00
// auto tb_portExtension = portExtension.createToolbar();
// window->addToolBar(tb_portExtension);
// toolbars.insert(tb_portExtension);
2020-10-31 23:52:59 +08:00
2020-09-13 20:44:45 +08:00
2021-06-19 21:33:43 +08:00
markerModel = new MarkerModel ( traceModel , this ) ;
2020-09-13 20:44:45 +08:00
auto tracesDock = new QDockWidget ( " Traces " ) ;
2021-04-13 01:48:19 +08:00
traceWidget = new TraceWidgetVNA ( traceModel , cal , deembedding ) ;
tracesDock - > setWidget ( traceWidget ) ;
2020-09-13 20:44:45 +08:00
window - > addDockWidget ( Qt : : LeftDockWidgetArea , tracesDock ) ;
docks . insert ( tracesDock ) ;
auto markerWidget = new MarkerWidget ( * markerModel ) ;
auto markerDock = new QDockWidget ( " Marker " ) ;
markerDock - > setWidget ( markerWidget ) ;
window - > addDockWidget ( Qt : : BottomDockWidgetArea , markerDock ) ;
docks . insert ( markerDock ) ;
2021-04-13 01:48:19 +08:00
SetupSCPI ( ) ;
2020-09-13 20:44:45 +08:00
// Set initial sweep settings
2020-10-23 03:12:33 +08:00
auto pref = Preferences : : getInstance ( ) ;
2021-07-10 04:26:44 +08:00
2020-09-13 20:44:45 +08:00
if ( pref . Startup . RememberSweepSettings ) {
LoadSweepSettings ( ) ;
} else {
2021-07-10 04:26:44 +08:00
settings . Freq . start = pref . Startup . DefaultSweep . f_start ;
settings . Freq . stop = pref . Startup . DefaultSweep . f_stop ;
SetSourceLevel ( pref . Startup . DefaultSweep . f_excitation ) ;
2020-09-13 20:44:45 +08:00
ConstrainAndUpdateFrequencies ( ) ;
2021-07-10 04:26:44 +08:00
SetStartPower ( pref . Startup . DefaultSweep . dbm_start ) ;
SetStopPower ( pref . Startup . DefaultSweep . dbm_stop ) ;
SetPowerSweepFrequency ( pref . Startup . DefaultSweep . dbm_freq ) ;
2020-09-13 20:44:45 +08:00
SetIFBandwidth ( pref . Startup . DefaultSweep . bandwidth ) ;
2020-10-23 17:39:07 +08:00
SetAveraging ( pref . Startup . DefaultSweep . averaging ) ;
2020-09-13 20:44:45 +08:00
SetPoints ( pref . Startup . DefaultSweep . points ) ;
2021-07-10 20:04:05 +08:00
if ( pref . Startup . DefaultSweep . type = = " Power Sweep " ) {
SetSweepType ( SweepType : : Power ) ;
}
2020-09-13 20:44:45 +08:00
}
2020-09-17 21:51:20 +08:00
// Set ObjectName for toolbars and docks
for ( auto d : findChildren < QDockWidget * > ( ) ) {
d - > setObjectName ( d - > windowTitle ( ) ) ;
}
for ( auto t : findChildren < QToolBar * > ( ) ) {
t - > setObjectName ( t - > windowTitle ( ) ) ;
}
finalize ( central ) ;
2020-09-13 20:44:45 +08:00
}
2021-07-10 04:26:44 +08:00
Calibration : : InterpolationType VNA : : getCalInterpolation ( )
{
double f_min , f_max ;
switch ( settings . sweepType ) {
2021-09-04 01:01:22 +08:00
case SweepType : : Last :
// should never get here, use frequency values just in case
2021-07-10 04:26:44 +08:00
case SweepType : : Frequency :
f_min = settings . Freq . start ;
f_max = settings . Freq . stop ;
break ;
case SweepType : : Power :
f_min = settings . Power . frequency ;
f_max = settings . Power . frequency ;
break ;
}
return cal . getInterpolation ( f_min , f_max , settings . npoints ) ;
}
2020-12-07 23:04:59 +08:00
QString VNA : : getCalStyle ( )
2020-12-07 11:18:01 +08:00
{
2021-07-10 04:26:44 +08:00
Calibration : : InterpolationType interpol = getCalInterpolation ( ) ;
2020-12-07 11:18:01 +08:00
QString style = " " ;
switch ( interpol )
{
case Calibration : : InterpolationType : : Unchanged :
case Calibration : : InterpolationType : : Exact :
case Calibration : : InterpolationType : : Interpolate :
style = " " ;
break ;
case Calibration : : InterpolationType : : Extrapolate :
style = " background-color: yellow " ;
break ;
case Calibration : : InterpolationType : : NoCalibration :
style = " background-color: red " ;
break ;
}
return style ;
}
QString VNA : : getCalToolTip ( )
{
2021-07-10 04:26:44 +08:00
Calibration : : InterpolationType interpol = getCalInterpolation ( ) ;
2020-12-07 11:18:01 +08:00
QString txt = " " ;
switch ( interpol )
{
case Calibration : : InterpolationType : : Unchanged :
case Calibration : : InterpolationType : : Exact :
case Calibration : : InterpolationType : : Interpolate :
case Calibration : : InterpolationType : : Extrapolate :
2020-12-07 23:04:59 +08:00
{
QString lo = Unit : : ToString ( cal . getMinFreq ( ) , " " , " kMG " , 5 ) ;
QString hi = Unit : : ToString ( cal . getMaxFreq ( ) , " " , " kMG " , 5 ) ;
2021-07-10 04:26:44 +08:00
if ( settings . Freq . start < cal . getMinFreq ( ) ) { lo = " <font color= \" red \" > " + lo + " </font> " ; }
if ( settings . Freq . stop > cal . getMaxFreq ( ) ) { hi = " <font color= \" red \" > " + hi + " </font> " ; }
2020-12-07 23:04:59 +08:00
txt =
" limits: " + lo + " - " + hi
+ " <br> "
+ " points: " + QString : : number ( cal . getNumPoints ( ) )
+ " <br> "
" file: " + cal . getCurrentCalibrationFile ( ) ;
2020-12-07 11:18:01 +08:00
break ;
2020-12-07 23:04:59 +08:00
}
2020-12-07 11:18:01 +08:00
case Calibration : : InterpolationType : : NoCalibration :
txt = " none " ;
break ;
}
return txt ;
}
2020-12-07 09:44:25 +08:00
2020-09-13 20:44:45 +08:00
void VNA : : deactivate ( )
{
StoreSweepSettings ( ) ;
Mode : : deactivate ( ) ;
}
void VNA : : initializeDevice ( )
{
2020-09-14 00:01:32 +08:00
defaultCalMenu - > setEnabled ( true ) ;
2020-09-13 20:44:45 +08:00
connect ( window - > getDevice ( ) , & Device : : DatapointReceived , this , & VNA : : NewDatapoint , Qt : : UniqueConnection ) ;
// Check if default calibration exists and attempt to load it
QSettings s ;
auto key = " DefaultCalibration " + window - > getDevice ( ) - > serial ( ) ;
if ( s . contains ( key ) ) {
auto filename = s . value ( key ) . toString ( ) ;
2020-11-12 02:13:53 +08:00
qDebug ( ) < < " Attempting to load default calibration file " < < filename ;
2020-09-13 20:44:45 +08:00
if ( QFile : : exists ( filename ) ) {
2020-11-11 02:16:16 +08:00
if ( cal . openFromFile ( filename ) ) {
ApplyCalibration ( cal . getType ( ) ) ;
2021-01-30 04:44:44 +08:00
// portExtension.setCalkit(&cal.getCalibrationKit());
2020-12-01 00:05:15 +08:00
qDebug ( ) < < " Calibration successful from " < < filename ;
} else {
qDebug ( ) < < " Calibration not successfull from: " < < filename ;
2020-11-11 02:16:16 +08:00
}
2020-12-01 00:05:15 +08:00
} else {
qDebug ( ) < < " Calibration file not found: " < < filename ;
2020-09-13 20:44:45 +08:00
}
2020-09-14 00:01:32 +08:00
removeDefaultCal - > setEnabled ( true ) ;
2020-09-13 20:44:45 +08:00
} else {
qDebug ( ) < < " No default calibration file set for this device " ;
2020-09-14 00:01:32 +08:00
removeDefaultCal - > setEnabled ( false ) ;
2020-09-13 20:44:45 +08:00
}
// Configure initial state of device
2020-09-20 16:13:06 +08:00
SettingsChanged ( ) ;
2020-08-31 04:03:41 +08:00
}
2020-09-14 00:01:32 +08:00
void VNA : : deviceDisconnected ( )
{
defaultCalMenu - > setEnabled ( false ) ;
}
2020-12-08 03:21:24 +08:00
void VNA : : shutdown ( )
{
if ( calEdited & & calValid ) {
auto save = InformationBox : : AskQuestion ( " Save calibration? " , " The calibration contains data that has not been saved yet. Do you want to save it before exiting? " , false ) ;
if ( save ) {
cal . saveToFile ( ) ;
}
}
}
2020-12-05 06:49:52 +08:00
nlohmann : : json VNA : : toJSON ( )
{
nlohmann : : json j ;
2021-09-04 01:01:22 +08:00
// save current sweep/acquisition settings
nlohmann : : json sweep ;
sweep [ " type " ] = SweepTypeToString ( settings . sweepType ) . toStdString ( ) ;
nlohmann : : json freq ;
freq [ " start " ] = settings . Freq . start ;
freq [ " stop " ] = settings . Freq . stop ;
freq [ " power " ] = settings . Freq . excitation_power ;
sweep [ " frequency " ] = freq ;
nlohmann : : json power ;
power [ " start " ] = settings . Power . start ;
power [ " stop " ] = settings . Power . stop ;
power [ " frequency " ] = settings . Power . frequency ;
sweep [ " power " ] = power ;
sweep [ " points " ] = settings . npoints ;
sweep [ " IFBW " ] = settings . bandwidth ;
j [ " sweep " ] = sweep ;
2020-12-05 06:49:52 +08:00
j [ " traces " ] = traceModel . toJSON ( ) ;
j [ " tiles " ] = central - > toJSON ( ) ;
2020-12-05 19:59:23 +08:00
j [ " markers " ] = markerModel - > toJSON ( ) ;
2021-01-30 04:44:44 +08:00
j [ " de-embedding " ] = deembedding . toJSON ( ) ;
2021-03-12 04:52:58 +08:00
j [ " de-embedding_enabled " ] = deembedding_active ;
2020-12-05 06:49:52 +08:00
return j ;
}
void VNA : : fromJSON ( nlohmann : : json j )
{
2021-09-04 01:01:22 +08:00
if ( j . is_null ( ) ) {
return ;
}
2020-12-05 06:49:52 +08:00
if ( j . contains ( " traces " ) ) {
traceModel . fromJSON ( j [ " traces " ] ) ;
}
if ( j . contains ( " tiles " ) ) {
central - > fromJSON ( j [ " tiles " ] ) ;
}
2020-12-05 19:59:23 +08:00
if ( j . contains ( " markers " ) ) {
markerModel - > fromJSON ( j [ " markers " ] ) ;
}
2021-01-30 04:44:44 +08:00
if ( j . contains ( " de-embedding " ) ) {
deembedding . fromJSON ( j [ " de-embedding " ] ) ;
2021-03-12 04:52:58 +08:00
EnableDeembedding ( j . value ( " de-embedding_enabled " , true ) ) ;
} else {
EnableDeembedding ( false ) ;
2021-01-30 04:44:44 +08:00
}
2021-09-04 01:01:22 +08:00
// sweep configuration has to go last sog graphs can catch events from changed sweep
if ( j . contains ( " sweep " ) ) {
auto sweep = j [ " sweep " ] ;
// restore sweep settings, keep current value as default in case of missing entry
SetPoints ( sweep . value ( " points " , settings . npoints ) ) ;
SetIFBandwidth ( sweep . value ( " IFBW " , settings . bandwidth ) ) ;
if ( sweep . contains ( " frequency " ) ) {
auto freq = sweep [ " frequency " ] ;
SetStartFreq ( freq . value ( " start " , settings . Freq . start ) ) ;
SetStopFreq ( freq . value ( " stop " , settings . Freq . stop ) ) ;
SetSourceLevel ( freq . value ( " power " , settings . Freq . excitation_power ) ) ;
}
if ( sweep . contains ( " power " ) ) {
auto power = sweep [ " power " ] ;
SetStartPower ( power . value ( " start " , settings . Power . start ) ) ;
SetStopPower ( power . value ( " stop " , settings . Power . stop ) ) ;
SetPowerSweepFrequency ( power . value ( " frequency " , settings . Power . frequency ) ) ;
}
auto type = SweepTypeFromString ( QString : : fromStdString ( sweep [ " type " ] ) ) ;
if ( type = = SweepType : : Last ) {
// default to frequency sweep
type = SweepType : : Frequency ;
}
SetSweepType ( type ) ;
}
2020-12-05 06:49:52 +08:00
}
2020-09-13 20:44:45 +08:00
using namespace std ;
void VNA : : NewDatapoint ( Protocol : : Datapoint d )
2020-08-31 04:03:41 +08:00
{
2020-10-30 02:27:04 +08:00
d = average . process ( d ) ;
2020-09-13 20:44:45 +08:00
if ( calMeasuring ) {
2020-10-30 02:27:04 +08:00
if ( average . currentSweep ( ) = = averages ) {
// this is the last averaging sweep, use values for calibration
if ( ! calWaitFirst | | d . pointNum = = 0 ) {
calWaitFirst = false ;
2021-09-03 19:13:33 +08:00
cal . addMeasurements ( calMeasurements , d ) ;
2021-07-10 04:26:44 +08:00
if ( d . pointNum = = settings . npoints - 1 ) {
2020-10-30 02:27:04 +08:00
calMeasuring = false ;
2021-09-03 19:13:33 +08:00
emit CalibrationMeasurementsComplete ( calMeasurements ) ;
2020-10-30 02:27:04 +08:00
}
2020-08-31 04:03:41 +08:00
}
2020-09-13 20:44:45 +08:00
}
2021-07-10 04:26:44 +08:00
int percentage = ( ( ( average . currentSweep ( ) - 1 ) * 100 ) + ( d . pointNum + 1 ) * 100 / settings . npoints ) / averages ;
2020-10-30 02:27:04 +08:00
calDialog . setValue ( percentage ) ;
2020-09-13 20:44:45 +08:00
}
if ( calValid ) {
cal . correctMeasurement ( d ) ;
}
2021-01-30 04:44:44 +08:00
2021-03-12 04:52:58 +08:00
if ( deembedding_active ) {
deembedding . Deembed ( d ) ;
}
2020-10-31 23:52:59 +08:00
2021-07-10 04:26:44 +08:00
TraceMath : : DataType type ;
switch ( settings . sweepType ) {
2021-09-04 01:01:22 +08:00
case SweepType : : Last :
2021-07-10 04:26:44 +08:00
case SweepType : : Frequency :
type = TraceMath : : DataType : : Frequency ;
break ;
case SweepType : : Power :
type = TraceMath : : DataType : : Power ;
break ;
}
traceModel . addVNAData ( d , type ) ;
2020-09-13 20:44:45 +08:00
emit dataChanged ( ) ;
2021-07-10 04:26:44 +08:00
if ( d . pointNum = = settings . npoints - 1 ) {
2020-10-23 17:39:07 +08:00
UpdateAverageCount ( ) ;
2020-10-20 23:03:49 +08:00
markerModel - > updateMarkers ( ) ;
2020-09-13 20:44:45 +08:00
}
2020-11-24 23:28:57 +08:00
static unsigned int lastPoint = 0 ;
if ( d . pointNum > 0 & & d . pointNum ! = lastPoint + 1 ) {
qWarning ( ) < < " Got point " < < d . pointNum < < " but last received point was " < < lastPoint < < " ( " < < ( d . pointNum - lastPoint - 1 ) < < " missed points) " ;
}
lastPoint = d . pointNum ;
2020-09-13 20:44:45 +08:00
}
2020-10-23 17:39:07 +08:00
void VNA : : UpdateAverageCount ( )
2020-09-13 20:44:45 +08:00
{
2020-10-23 17:39:07 +08:00
lAverages - > setText ( QString : : number ( average . getLevel ( ) ) + " / " ) ;
2020-08-31 04:03:41 +08:00
}
2020-10-30 02:27:04 +08:00
void VNA : : SettingsChanged ( std : : function < void ( Device : : TransmissionResult ) > cb )
2020-08-31 04:03:41 +08:00
{
2021-07-10 04:26:44 +08:00
// assemble VNA protocol settings
Protocol : : SweepSettings s ;
s . suppressPeaks = Preferences : : getInstance ( ) . Acquisition . suppressPeaks ? 1 : 0 ;
if ( Preferences : : getInstance ( ) . Acquisition . alwaysExciteBothPorts ) {
s . excitePort1 = 1 ;
s . excitePort2 = 1 ;
} else {
s . excitePort1 = traceModel . PortExcitationRequired ( 1 ) ;
s . excitePort2 = traceModel . PortExcitationRequired ( 2 ) ;
}
settings . excitingPort1 = s . excitePort1 ;
settings . excitingPort2 = s . excitePort2 ;
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 . if_bandwidth = settings . bandwidth ;
s . cdbm_excitation_start = settings . Freq . excitation_power * 100 ;
s . cdbm_excitation_stop = settings . Freq . excitation_power * 100 ;
} 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 . if_bandwidth = settings . bandwidth ;
s . cdbm_excitation_start = settings . Power . start * 100 ;
s . cdbm_excitation_stop = settings . Power . stop * 100 ;
}
2021-04-11 18:33:37 +08:00
if ( window - > getDevice ( ) & & Mode : : getActiveMode ( ) = = this ) {
2021-09-04 01:01:22 +08:00
if ( s . excitePort1 = = 0 & & s . excitePort2 = = 0 ) {
// no signal at either port, just set the device to idel
window - > getDevice ( ) - > SetIdle ( ) ;
} else {
window - > getDevice ( ) - > Configure ( s , [ = ] ( Device : : TransmissionResult res ) {
// device received command, reset traces now
average . reset ( s . points ) ;
traceModel . clearLiveData ( ) ;
UpdateAverageCount ( ) ;
UpdateCalWidget ( ) ;
if ( cb ) {
cb ( res ) ;
}
} ) ;
}
2020-09-13 20:44:45 +08:00
}
2021-07-10 04:26:44 +08:00
emit traceModel . SpanChanged ( s . f_start , s . f_stop ) ;
2020-08-31 04:03:41 +08:00
}
void VNA : : StartImpedanceMatching ( )
{
auto dialog = new ImpedanceMatchDialog ( * markerModel ) ;
dialog - > show ( ) ;
}
2021-07-10 04:26:44 +08:00
void VNA : : SetSweepType ( SweepType sw )
{
if ( settings . sweepType ! = sw ) {
settings . sweepType = sw ;
emit sweepTypeChanged ( sw ) ;
SettingsChanged ( ) ;
}
}
2020-08-31 04:03:41 +08:00
void VNA : : SetStartFreq ( double freq )
{
2021-07-10 04:26:44 +08:00
settings . Freq . start = freq ;
if ( settings . Freq . stop < freq ) {
settings . Freq . stop = freq ;
2020-08-31 04:03:41 +08:00
}
ConstrainAndUpdateFrequencies ( ) ;
}
void VNA : : SetStopFreq ( double freq )
{
2021-07-10 04:26:44 +08:00
settings . Freq . stop = freq ;
if ( settings . Freq . start > freq ) {
settings . Freq . start = freq ;
2020-08-31 04:03:41 +08:00
}
ConstrainAndUpdateFrequencies ( ) ;
}
void VNA : : SetCenterFreq ( double freq )
{
2021-07-10 04:26:44 +08:00
auto old_span = settings . Freq . stop - settings . Freq . start ;
2020-11-13 01:56:39 +08:00
if ( freq - old_span / 2 < = Device : : Info ( ) . limits_minFreq ) {
// would shift start frequency below minimum
2021-07-10 04:26:44 +08:00
settings . Freq . start = 0 ;
settings . Freq . stop = 2 * freq ;
2020-11-13 01:56:39 +08:00
} else if ( freq + old_span / 2 > = Device : : Info ( ) . limits_maxFreq ) {
// would shift stop frequency above maximum
2021-07-10 04:26:44 +08:00
settings . Freq . start = 2 * freq - Device : : Info ( ) . limits_maxFreq ;
settings . Freq . stop = Device : : Info ( ) . limits_maxFreq ;
2020-11-13 01:56:39 +08:00
} else {
2021-07-10 04:26:44 +08:00
settings . Freq . start = freq - old_span / 2 ;
settings . Freq . stop = freq + old_span / 2 ;
2020-08-31 04:03:41 +08:00
}
ConstrainAndUpdateFrequencies ( ) ;
}
void VNA : : SetSpan ( double span )
{
2021-04-18 05:22:14 +08:00
auto maxFreq = Preferences : : getInstance ( ) . Acquisition . harmonicMixing ? Device : : Info ( ) . limits_maxFreqHarmonic : Device : : Info ( ) . limits_maxFreq ;
2021-07-10 04:26:44 +08:00
auto old_center = ( settings . Freq . start + settings . Freq . stop ) / 2 ;
2020-11-13 01:56:39 +08:00
if ( old_center < Device : : Info ( ) . limits_minFreq + span / 2 ) {
// would shift start frequency below minimum
2021-07-10 04:26:44 +08:00
settings . Freq . start = Device : : Info ( ) . limits_minFreq ;
settings . Freq . stop = Device : : Info ( ) . limits_minFreq + span ;
2021-04-18 05:22:14 +08:00
} else if ( old_center > maxFreq - span / 2 ) {
2020-11-13 01:56:39 +08:00
// would shift stop frequency above maximum
2021-07-10 04:26:44 +08:00
settings . Freq . start = maxFreq - span ;
settings . Freq . stop = maxFreq ;
2020-08-31 04:03:41 +08:00
} else {
2021-07-10 04:26:44 +08:00
settings . Freq . start = old_center - span / 2 ;
settings . Freq . stop = settings . Freq . start + span ;
2020-08-31 04:03:41 +08:00
}
ConstrainAndUpdateFrequencies ( ) ;
}
void VNA : : SetFullSpan ( )
{
2021-07-10 04:26:44 +08:00
settings . Freq . start = Device : : Info ( ) . limits_minFreq ;
settings . Freq . stop = Device : : Info ( ) . limits_maxFreq ;
2020-08-31 04:03:41 +08:00
ConstrainAndUpdateFrequencies ( ) ;
}
void VNA : : SpanZoomIn ( )
{
2021-07-10 04:26:44 +08:00
auto center = ( settings . Freq . start + settings . Freq . stop ) / 2 ;
auto old_span = settings . Freq . stop - settings . Freq . start ;
settings . Freq . start = center - old_span / 4 ;
settings . Freq . stop = center + old_span / 4 ;
2020-08-31 04:03:41 +08:00
ConstrainAndUpdateFrequencies ( ) ;
}
void VNA : : SpanZoomOut ( )
{
2021-07-10 04:26:44 +08:00
auto center = ( settings . Freq . start + settings . Freq . stop ) / 2 ;
auto old_span = settings . Freq . stop - settings . Freq . start ;
2020-08-31 04:03:41 +08:00
if ( center > old_span ) {
2021-07-10 04:26:44 +08:00
settings . Freq . start = center - old_span ;
2020-08-31 04:03:41 +08:00
} else {
2021-07-10 04:26:44 +08:00
settings . Freq . start = 0 ;
2020-08-31 04:03:41 +08:00
}
2021-07-10 04:26:44 +08:00
settings . Freq . stop = center + old_span ;
2020-08-31 04:03:41 +08:00
ConstrainAndUpdateFrequencies ( ) ;
}
void VNA : : SetSourceLevel ( double level )
{
2020-11-07 20:22:10 +08:00
if ( level > Device : : Info ( ) . limits_cdbm_max / 100.0 ) {
level = Device : : Info ( ) . limits_cdbm_max / 100.0 ;
} else if ( level < Device : : Info ( ) . limits_cdbm_min / 100.0 ) {
level = Device : : Info ( ) . limits_cdbm_min / 100.0 ;
2020-08-31 04:03:41 +08:00
}
emit sourceLevelChanged ( level ) ;
2021-07-10 04:26:44 +08:00
settings . Freq . excitation_power = level ;
SettingsChanged ( ) ;
}
void VNA : : SetStartPower ( double level )
{
settings . Power . start = level ;
emit startPowerChanged ( level ) ;
SettingsChanged ( ) ;
}
void VNA : : SetStopPower ( double level )
{
settings . Power . stop = level ;
emit stopPowerChanged ( level ) ;
SettingsChanged ( ) ;
}
void VNA : : SetPowerSweepFrequency ( double freq )
{
settings . Power . frequency = freq ;
emit powerSweepFrequencyChanged ( freq ) ;
2020-08-31 04:03:41 +08:00
SettingsChanged ( ) ;
}
void VNA : : SetPoints ( unsigned int points )
{
2020-11-07 20:22:10 +08:00
if ( points > Device : : Info ( ) . limits_maxPoints ) {
points = Device : : Info ( ) . limits_maxPoints ;
} else if ( points < 2 ) {
2020-11-03 01:12:06 +08:00
points = 2 ;
2020-08-31 04:03:41 +08:00
}
emit pointsChanged ( points ) ;
2021-07-10 04:26:44 +08:00
settings . npoints = points ;
2020-08-31 04:03:41 +08:00
SettingsChanged ( ) ;
}
void VNA : : SetIFBandwidth ( double bandwidth )
{
2020-11-07 20:22:10 +08:00
if ( bandwidth > Device : : Info ( ) . limits_maxIFBW ) {
bandwidth = Device : : Info ( ) . limits_maxIFBW ;
} else if ( bandwidth < Device : : Info ( ) . limits_minIFBW ) {
bandwidth = Device : : Info ( ) . limits_minIFBW ;
2020-09-27 05:34:31 +08:00
}
2021-07-10 04:26:44 +08:00
settings . bandwidth = bandwidth ;
emit IFBandwidthChanged ( settings . bandwidth ) ;
2020-08-31 04:03:41 +08:00
SettingsChanged ( ) ;
}
void VNA : : SetAveraging ( unsigned int averages )
{
this - > averages = averages ;
average . setAverages ( averages ) ;
emit averagingChanged ( averages ) ;
SettingsChanged ( ) ;
}
2020-09-16 05:22:08 +08:00
void VNA : : ExcitationRequired ( bool port1 , bool port2 )
{
2020-10-23 03:12:33 +08:00
if ( Preferences : : getInstance ( ) . Acquisition . alwaysExciteBothPorts ) {
2020-09-16 05:22:08 +08:00
port1 = true ;
port2 = true ;
}
// check if settings actually changed
2021-07-10 04:26:44 +08:00
if ( settings . excitingPort1 ! = port1
| | settings . excitingPort2 ! = port2 ) {
settings . excitingPort1 = port1 ;
settings . excitingPort2 = port2 ;
2020-09-16 05:22:08 +08:00
SettingsChanged ( ) ;
}
}
2020-08-31 04:03:41 +08:00
void VNA : : DisableCalibration ( bool force )
{
if ( calValid | | force ) {
calValid = false ;
2021-03-12 04:52:58 +08:00
cal . resetErrorTerms ( ) ;
2020-08-31 04:03:41 +08:00
emit CalibrationDisabled ( ) ;
}
}
void VNA : : ApplyCalibration ( Calibration : : Type type )
{
if ( cal . calculationPossible ( type ) ) {
try {
2020-10-03 19:01:59 +08:00
if ( cal . constructErrorTerms ( type ) ) {
calValid = true ;
emit CalibrationApplied ( type ) ;
2020-11-12 02:13:53 +08:00
} else {
DisableCalibration ( true ) ;
2020-10-03 19:01:59 +08:00
}
2020-08-31 04:03:41 +08:00
} catch ( runtime_error e ) {
2020-11-01 06:03:34 +08:00
QMessageBox : : critical ( window , " Calibration failure " , e . what ( ) ) ;
2020-08-31 04:03:41 +08:00
DisableCalibration ( true ) ;
}
} else {
2021-07-10 04:26:44 +08:00
if ( settings . sweepType = = SweepType : : Frequency ) {
// Not all required traces available
InformationBox : : ShowMessageBlocking ( " Missing calibration measurements " , " Not all calibration measurements for this type of calibration have been taken. The calibration can be enabled after the missing measurements have been acquired. " ) ;
DisableCalibration ( true ) ;
StartCalibrationDialog ( type ) ;
} else {
// Not all required traces available
InformationBox : : ShowMessageBlocking ( " Missing calibration measurements " , " Not all calibration measurements for this type of calibration have been taken. Please switch to frequency sweep to take these measurements. " ) ;
DisableCalibration ( true ) ;
}
2020-08-31 04:03:41 +08:00
}
}
2021-09-03 19:13:33 +08:00
void VNA : : StartCalibrationMeasurements ( std : : set < Calibration : : Measurement > m )
2020-08-31 04:03:41 +08:00
{
2020-10-30 02:27:04 +08:00
auto device = window - > getDevice ( ) ;
if ( ! device ) {
return ;
}
// Stop sweep
StopSweep ( ) ;
2021-09-03 19:13:33 +08:00
calMeasurements = m ;
2020-08-31 04:03:41 +08:00
// Delete any already captured data of this measurement
2021-09-03 19:13:33 +08:00
cal . clearMeasurements ( m ) ;
2020-08-31 04:03:41 +08:00
calWaitFirst = true ;
2021-09-03 19:13:33 +08:00
// show messagebox
QString text = " Measuring " ;
if ( m . size ( ) = = 1 ) {
text . append ( " \" " ) ;
text . append ( Calibration : : MeasurementToString ( * m . begin ( ) ) ) ;
text . append ( " \" parameters. " ) ;
} else {
text . append ( " multiple calibration standards. " ) ;
}
2020-08-31 04:03:41 +08:00
calDialog . setLabelText ( text ) ;
calDialog . setCancelButtonText ( " Abort " ) ;
calDialog . setWindowTitle ( " Taking calibration measurement... " ) ;
calDialog . setValue ( 0 ) ;
calDialog . setWindowModality ( Qt : : ApplicationModal ) ;
// always show the dialog
calDialog . setMinimumDuration ( 0 ) ;
connect ( & calDialog , & QProgressDialog : : canceled , [ = ] ( ) {
// the user aborted the calibration measurement
calMeasuring = false ;
2021-09-03 19:13:33 +08:00
cal . clearMeasurements ( calMeasurements ) ;
2020-08-31 04:03:41 +08:00
} ) ;
2020-10-30 02:27:04 +08:00
// Trigger sweep to start from beginning
SettingsChanged ( [ = ] ( Device : : TransmissionResult ) {
// enable calibration measurement only in transmission callback (prevents accidental sampling of data which was still being processed)
calMeasuring = true ;
} ) ;
2020-12-08 03:21:24 +08:00
calEdited = true ;
2020-09-12 18:17:35 +08:00
}
2021-04-11 06:10:22 +08:00
void VNA : : SetupSCPI ( )
{
2021-07-12 00:41:05 +08:00
SCPINode : : add ( new SCPICommand ( " SWEEP " , [ = ] ( QStringList params ) - > QString {
if ( params . size ( ) > = 1 ) {
if ( params [ 0 ] = = " FREQUENCY " ) {
SetSweepType ( SweepType : : Frequency ) ;
return " " ;
} else if ( params [ 0 ] = = " POWER " ) {
SetSweepType ( SweepType : : Power ) ;
return " " ;
}
}
// either no parameter or invalid
return " ERROR " ;
} , [ = ] ( QStringList ) - > QString {
return settings . sweepType = = SweepType : : Frequency ? " FREQUENCY " : " POWER " ;
} ) ) ;
2021-04-11 06:10:22 +08:00
auto scpi_freq = new SCPINode ( " FREQuency " ) ;
SCPINode : : add ( scpi_freq ) ;
scpi_freq - > add ( new SCPICommand ( " SPAN " , [ = ] ( QStringList params ) - > QString {
2021-04-14 03:33:51 +08:00
unsigned long newval ;
if ( ! SCPI : : paramToULong ( params , 0 , newval ) ) {
2021-04-11 06:10:22 +08:00
return " ERROR " ;
} else {
SetSpan ( newval ) ;
return " " ;
}
2021-04-13 01:48:19 +08:00
} , [ = ] ( QStringList ) - > QString {
2021-07-10 04:26:44 +08:00
return QString : : number ( settings . Freq . stop - settings . Freq . start ) ;
2021-04-11 06:10:22 +08:00
} ) ) ;
scpi_freq - > add ( new SCPICommand ( " START " , [ = ] ( QStringList params ) - > QString {
2021-04-14 03:33:51 +08:00
unsigned long newval ;
if ( ! SCPI : : paramToULong ( params , 0 , newval ) ) {
2021-04-11 06:10:22 +08:00
return " ERROR " ;
} else {
SetStartFreq ( newval ) ;
return " " ;
}
2021-04-13 01:48:19 +08:00
} , [ = ] ( QStringList ) - > QString {
2021-07-10 04:26:44 +08:00
return QString : : number ( settings . Freq . start ) ;
2021-04-11 06:10:22 +08:00
} ) ) ;
2021-04-11 18:33:37 +08:00
scpi_freq - > add ( new SCPICommand ( " CENTer " , [ = ] ( QStringList params ) - > QString {
2021-04-14 03:33:51 +08:00
unsigned long newval ;
if ( ! SCPI : : paramToULong ( params , 0 , newval ) ) {
2021-04-11 06:10:22 +08:00
return " ERROR " ;
} else {
SetCenterFreq ( newval ) ;
return " " ;
}
2021-04-13 01:48:19 +08:00
} , [ = ] ( QStringList ) - > QString {
2021-07-10 04:26:44 +08:00
return QString : : number ( ( settings . Freq . start + settings . Freq . stop ) / 2 ) ;
2021-04-11 06:10:22 +08:00
} ) ) ;
scpi_freq - > add ( new SCPICommand ( " STOP " , [ = ] ( QStringList params ) - > QString {
2021-04-14 03:33:51 +08:00
unsigned long newval ;
if ( ! SCPI : : paramToULong ( params , 0 , newval ) ) {
2021-04-11 06:10:22 +08:00
return " ERROR " ;
} else {
SetStopFreq ( newval ) ;
return " " ;
}
2021-04-13 01:48:19 +08:00
} , [ = ] ( QStringList ) - > QString {
2021-07-10 04:26:44 +08:00
return QString : : number ( settings . Freq . stop ) ;
2021-04-11 06:10:22 +08:00
} ) ) ;
scpi_freq - > add ( new SCPICommand ( " FULL " , [ = ] ( QStringList params ) - > QString {
2021-04-13 01:48:19 +08:00
Q_UNUSED ( params )
2021-04-11 06:10:22 +08:00
SetFullSpan ( ) ;
return " " ;
} , nullptr ) ) ;
2021-07-12 00:41:05 +08:00
auto scpi_power = new SCPINode ( " POWer " ) ;
SCPINode : : add ( scpi_power ) ;
scpi_power - > add ( new SCPICommand ( " START " , [ = ] ( QStringList params ) - > QString {
double newval ;
if ( ! SCPI : : paramToDouble ( params , 0 , newval ) ) {
return " ERROR " ;
} else {
SetStartPower ( newval ) ;
return " " ;
}
} , [ = ] ( QStringList ) - > QString {
return QString : : number ( settings . Power . start ) ;
} ) ) ;
scpi_power - > add ( new SCPICommand ( " STOP " , [ = ] ( QStringList params ) - > QString {
double newval ;
if ( ! SCPI : : paramToDouble ( params , 0 , newval ) ) {
return " ERROR " ;
} else {
SetStopPower ( newval ) ;
return " " ;
}
} , [ = ] ( QStringList ) - > QString {
return QString : : number ( settings . Power . stop ) ;
} ) ) ;
2021-04-11 06:10:22 +08:00
auto scpi_acq = new SCPINode ( " ACQuisition " ) ;
SCPINode : : add ( scpi_acq ) ;
scpi_acq - > add ( new SCPICommand ( " IFBW " , [ = ] ( QStringList params ) - > QString {
2021-04-14 03:33:51 +08:00
unsigned long newval ;
if ( ! SCPI : : paramToULong ( params , 0 , newval ) ) {
2021-04-11 06:10:22 +08:00
return " ERROR " ;
} else {
SetIFBandwidth ( newval ) ;
return " " ;
}
2021-04-13 01:48:19 +08:00
} , [ = ] ( QStringList ) - > QString {
2021-07-10 04:26:44 +08:00
return QString : : number ( settings . bandwidth ) ;
2021-04-11 06:10:22 +08:00
} ) ) ;
scpi_acq - > add ( new SCPICommand ( " POINTS " , [ = ] ( QStringList params ) - > QString {
2021-04-14 03:33:51 +08:00
unsigned long newval ;
if ( ! SCPI : : paramToULong ( params , 0 , newval ) ) {
2021-04-11 06:10:22 +08:00
return " ERROR " ;
} else {
SetPoints ( newval ) ;
return " " ;
}
2021-04-13 01:48:19 +08:00
} , [ = ] ( QStringList ) - > QString {
2021-07-10 04:26:44 +08:00
return QString : : number ( settings . npoints ) ;
2021-04-11 06:10:22 +08:00
} ) ) ;
scpi_acq - > add ( new SCPICommand ( " AVG " , [ = ] ( QStringList params ) - > QString {
2021-04-14 03:33:51 +08:00
unsigned long newval ;
if ( ! SCPI : : paramToULong ( params , 0 , newval ) ) {
2021-04-11 06:10:22 +08:00
return " ERROR " ;
} else {
SetAveraging ( newval ) ;
return " " ;
}
2021-04-13 01:48:19 +08:00
} , [ = ] ( QStringList ) - > QString {
2021-04-11 06:10:22 +08:00
return QString : : number ( averages ) ;
} ) ) ;
2021-06-12 00:53:31 +08:00
scpi_acq - > add ( new SCPICommand ( " AVGLEVel " , nullptr , [ = ] ( QStringList ) - > QString {
return QString : : number ( average . getLevel ( ) ) ;
} ) ) ;
scpi_acq - > add ( new SCPICommand ( " FINished " , nullptr , [ = ] ( QStringList ) - > QString {
return average . getLevel ( ) = = averages ? " TRUE " : " FALSE " ;
} ) ) ;
2021-04-11 06:10:22 +08:00
auto scpi_stim = new SCPINode ( " STIMulus " ) ;
SCPINode : : add ( scpi_stim ) ;
scpi_stim - > add ( new SCPICommand ( " LVL " , [ = ] ( QStringList params ) - > QString {
2021-04-14 03:33:51 +08:00
double newval ;
if ( ! SCPI : : paramToDouble ( params , 0 , newval ) ) {
2021-04-11 06:10:22 +08:00
return " ERROR " ;
} else {
SetSourceLevel ( newval ) ;
return " " ;
}
2021-04-13 01:48:19 +08:00
} , [ = ] ( QStringList ) - > QString {
2021-07-10 04:26:44 +08:00
return QString : : number ( settings . Freq . excitation_power ) ;
2021-04-11 06:10:22 +08:00
} ) ) ;
2021-07-12 00:41:05 +08:00
scpi_stim - > add ( new SCPICommand ( " FREQuency " , [ = ] ( QStringList params ) - > QString {
unsigned long newval ;
if ( ! SCPI : : paramToULong ( params , 0 , newval ) ) {
return " ERROR " ;
} else {
SetPowerSweepFrequency ( newval ) ;
return " " ;
}
} , [ = ] ( QStringList ) - > QString {
return QString : : number ( settings . Power . frequency ) ;
} ) ) ;
2021-04-13 01:48:19 +08:00
SCPINode : : add ( traceWidget ) ;
2021-04-16 01:24:11 +08:00
auto scpi_cal = new SCPINode ( " CALibration " ) ;
SCPINode : : add ( scpi_cal ) ;
scpi_cal - > add ( new SCPICommand ( " TYPE " , [ = ] ( QStringList params ) - > QString {
if ( params . size ( ) ! = 1 ) {
return " ERROR " ;
} else {
auto type = Calibration : : TypeFromString ( params [ 0 ] . replace ( ' _ ' , ' ' ) ) ;
if ( type = = Calibration : : Type : : Last ) {
// failed to parse string
return " ERROR " ;
} else if ( type = = Calibration : : Type : : None ) {
DisableCalibration ( ) ;
} else {
// check if calibration can be activated
if ( cal . calculationPossible ( type ) ) {
ApplyCalibration ( type ) ;
} else {
return " ERROR " ;
}
}
}
return " " ;
} , [ = ] ( QStringList ) - > QString {
auto ret = Calibration : : TypeToString ( cal . getType ( ) ) ;
ret . replace ( ' ' , ' _ ' ) ;
return ret ;
} ) ) ;
scpi_cal - > add ( new SCPICommand ( " MEASure " , [ = ] ( QStringList params ) - > QString {
if ( params . size ( ) ! = 1 | | CalibrationMeasurementActive ( ) | | ! window - > getDevice ( ) | | Mode : : getActiveMode ( ) ! = this ) {
// no measurement specified, still busy or invalid mode
return " ERROR " ;
} else {
auto meas = Calibration : : MeasurementFromString ( params [ 0 ] . replace ( ' _ ' , ' ' ) ) ;
if ( meas = = Calibration : : Measurement : : Last ) {
// failed to parse string
return " ERROR " ;
} else {
2021-09-03 19:13:33 +08:00
std : : set < Calibration : : Measurement > m ;
m . insert ( meas ) ;
StartCalibrationMeasurements ( m ) ;
2021-04-16 01:24:11 +08:00
}
}
return " " ;
} , nullptr ) ) ;
scpi_cal - > add ( new SCPICommand ( " BUSy " , nullptr , [ = ] ( QStringList ) - > QString {
return CalibrationMeasurementActive ( ) ? " TRUE " : " FALSE " ;
} ) ) ;
2021-04-11 06:10:22 +08:00
}
2020-08-31 04:03:41 +08:00
void VNA : : ConstrainAndUpdateFrequencies ( )
{
2020-12-18 22:03:01 +08:00
auto pref = Preferences : : getInstance ( ) ;
double maxFreq ;
if ( pref . Acquisition . harmonicMixing ) {
maxFreq = Device : : Info ( ) . limits_maxFreqHarmonic ;
} else {
maxFreq = Device : : Info ( ) . limits_maxFreq ;
}
2021-07-10 04:26:44 +08:00
if ( settings . Freq . stop > maxFreq ) {
settings . Freq . stop = maxFreq ;
2020-08-31 04:03:41 +08:00
}
2021-07-10 04:26:44 +08:00
if ( settings . Freq . start > settings . Freq . stop ) {
settings . Freq . start = settings . Freq . stop ;
2020-08-31 04:03:41 +08:00
}
2021-07-10 04:26:44 +08:00
if ( settings . Freq . start < Device : : Info ( ) . limits_minFreq ) {
settings . Freq . start = Device : : Info ( ) . limits_minFreq ;
2020-09-27 05:34:31 +08:00
}
2021-07-10 04:26:44 +08:00
emit startFreqChanged ( settings . Freq . start ) ;
emit stopFreqChanged ( settings . Freq . stop ) ;
emit spanChanged ( settings . Freq . stop - settings . Freq . start ) ;
emit centerFreqChanged ( ( settings . Freq . stop + settings . Freq . start ) / 2 ) ;
2020-08-31 04:03:41 +08:00
SettingsChanged ( ) ;
}
2020-09-12 05:07:15 +08:00
void VNA : : LoadSweepSettings ( )
{
2020-10-23 03:12:33 +08:00
auto pref = Preferences : : getInstance ( ) ;
2020-09-12 05:07:15 +08:00
QSettings s ;
2021-07-10 04:26:44 +08:00
// frequency sweep settings
settings . Freq . start = s . value ( " SweepFreqStart " , pref . Startup . DefaultSweep . f_start ) . toULongLong ( ) ;
settings . Freq . stop = s . value ( " SweepFreqStop " , pref . Startup . DefaultSweep . f_stop ) . toULongLong ( ) ;
SetSourceLevel ( s . value ( " SweepFreqLevel " , pref . Startup . DefaultSweep . f_excitation ) . toDouble ( ) ) ;
// power sweep settings
SetStartPower ( s . value ( " SweepPowerStart " , pref . Startup . DefaultSweep . dbm_start ) . toDouble ( ) ) ;
SetStopPower ( s . value ( " SweepPowerStop " , pref . Startup . DefaultSweep . dbm_stop ) . toDouble ( ) ) ;
2021-07-10 20:04:05 +08:00
SetPowerSweepFrequency ( s . value ( " SweepPowerFreq " , pref . Startup . DefaultSweep . dbm_freq ) . toULongLong ( ) ) ;
2020-09-12 05:07:15 +08:00
SetPoints ( s . value ( " SweepPoints " , pref . Startup . DefaultSweep . points ) . toInt ( ) ) ;
2020-11-01 06:03:34 +08:00
SetIFBandwidth ( s . value ( " SweepBandwidth " , pref . Startup . DefaultSweep . bandwidth ) . toUInt ( ) ) ;
2020-10-23 17:39:07 +08:00
SetAveraging ( s . value ( " SweepAveraging " , pref . Startup . DefaultSweep . averaging ) . toInt ( ) ) ;
2020-11-01 06:03:34 +08:00
ConstrainAndUpdateFrequencies ( ) ;
2021-07-10 20:04:05 +08:00
auto typeString = s . value ( " SweepType " , pref . Startup . DefaultSweep . type ) . toString ( ) ;
if ( typeString = = " Power " ) {
SetSweepType ( SweepType : : Power ) ;
} else {
SetSweepType ( SweepType : : Frequency ) ;
}
2020-09-12 05:07:15 +08:00
}
void VNA : : StoreSweepSettings ( )
{
QSettings s ;
2021-07-10 04:26:44 +08:00
s . setValue ( " SweepType " , settings . sweepType = = SweepType : : Frequency ? " Frequency " : " Power " ) ;
s . setValue ( " SweepFreqStart " , static_cast < unsigned long long > ( settings . Freq . start ) ) ;
s . setValue ( " SweepFreqStop " , static_cast < unsigned long long > ( settings . Freq . stop ) ) ;
s . setValue ( " SweepFreqLevel " , settings . Freq . excitation_power ) ;
s . setValue ( " SweepPowerStart " , settings . Power . start ) ;
s . setValue ( " SweepPowerStop " , settings . Power . stop ) ;
s . setValue ( " SweepPowerFreq " , static_cast < unsigned long long > ( settings . Power . frequency ) ) ;
s . setValue ( " SweepBandwidth " , settings . bandwidth ) ;
s . setValue ( " SweepPoints " , settings . npoints ) ;
2020-10-23 17:39:07 +08:00
s . setValue ( " SweepAveraging " , averages ) ;
2020-09-12 05:07:15 +08:00
}
2020-10-30 02:27:04 +08:00
void VNA : : StopSweep ( )
{
if ( window - > getDevice ( ) ) {
window - > getDevice ( ) - > SetIdle ( ) ;
}
}
void VNA : : StartCalibrationDialog ( Calibration : : Type type )
{
2021-07-10 04:26:44 +08:00
auto traceDialog = new CalibrationTraceDialog ( & cal , settings . Freq . start , settings . Freq . stop , type ) ;
2021-09-03 19:13:33 +08:00
connect ( traceDialog , & CalibrationTraceDialog : : triggerMeasurements , this , & VNA : : StartCalibrationMeasurements ) ;
2020-10-30 02:27:04 +08:00
connect ( traceDialog , & CalibrationTraceDialog : : applyCalibration , this , & VNA : : ApplyCalibration ) ;
2021-09-03 19:13:33 +08:00
connect ( this , & VNA : : CalibrationMeasurementsComplete , traceDialog , & CalibrationTraceDialog : : measurementsComplete ) ;
2020-11-11 02:16:16 +08:00
connect ( traceDialog , & CalibrationTraceDialog : : calibrationInvalidated , [ = ] ( ) {
DisableCalibration ( true ) ;
2021-05-24 18:02:31 +08:00
InformationBox : : ShowMessageBlocking ( " Calibration disabled " , " The currently active calibration is no longer supported by the available measurements and was disabled. " ) ;
2020-11-11 02:16:16 +08:00
} ) ;
2020-10-30 02:27:04 +08:00
traceDialog - > show ( ) ;
}
2020-12-08 00:58:13 +08:00
void VNA : : UpdateCalWidget ( )
{
calLabel - > setStyleSheet ( getCalStyle ( ) ) ;
calLabel - > setToolTip ( getCalToolTip ( ) ) ;
}
2021-03-12 04:52:58 +08:00
void VNA : : EnableDeembedding ( bool enable )
{
deembedding_active = enable ;
enableDeembeddingAction - > blockSignals ( true ) ;
enableDeembeddingAction - > setChecked ( enable ) ;
enableDeembeddingAction - > blockSignals ( false ) ;
}
2021-06-29 10:47:02 +08:00
void VNA : : updateGraphColors ( )
{
emit graphColorsChanged ( ) ;
}
2021-09-04 01:01:22 +08:00
QString VNA : : SweepTypeToString ( VNA : : SweepType sw )
{
switch ( sw ) {
case SweepType : : Frequency : return " Frequency " ;
case SweepType : : Power : return " Power " ;
default : return " Unknown " ;
}
}
VNA : : SweepType VNA : : SweepTypeFromString ( QString s )
{
for ( int i = 0 ; i < ( int ) SweepType : : Last ; i + + ) {
if ( SweepTypeToString ( ( SweepType ) i ) = = s ) {
return ( SweepType ) i ;
}
}
// not found
return SweepType : : Last ;
}