- 0.0.9 release candidate

- Fixes to calibration: Standard length compensation should be better
- Markers now show parallel R & L/C equivalent
- The marker data can be hidden, if you want more space for charts
- No more debug messages when sweeping.
pull/17/head
Rune B. Broberg 2019-09-13 11:17:37 +02:00
rodzic 7a7ab0d668
commit df521f8d8c
5 zmienionych plików z 87 dodań i 32 usunięć

Wyświetl plik

@ -308,7 +308,10 @@ class Calibration:
self.shortL2 * f**2 + self.shortL2 * f**2 +
self.shortL3 * f**3) self.shortL3 * f**3)
gammaShort = ((Zsp/50) - 1) / ((Zsp/50) + 1) gammaShort = ((Zsp/50) - 1) / ((Zsp/50) + 1)
g1 = gammaShort * math.exp(2*math.pi*f*self.shortLength) # (lower case) gamma = 2*pi*f
# e^j*2*gamma*length
# Referencing https://arxiv.org/pdf/1606.02446.pdf (18) - (21)
g1 = gammaShort * np.exp(np.complex(0, 1) * 2 * 2 * math.pi * f * self.shortLength)
if self.useIdealOpen: if self.useIdealOpen:
g2 = self.openIdeal g2 = self.openIdeal
@ -317,7 +320,7 @@ class Calibration:
if divisor != 0: if divisor != 0:
Zop = np.complex(0, -1) / divisor Zop = np.complex(0, -1) / divisor
gammaOpen = ((Zop/50) - 1) / ((Zop/50) + 1) gammaOpen = ((Zop/50) - 1) / ((Zop/50) + 1)
g2 = gammaOpen * math.exp(2 * math.pi * f * self.openLength) g2 = gammaOpen * np.exp(np.complex(0, 1) * 2 * 2 * math.pi * f * self.shortLength)
else: else:
g2 = self.openIdeal g2 = self.openIdeal
if self.useIdealLoad: if self.useIdealLoad:

Wyświetl plik

@ -48,6 +48,9 @@ class Marker(QtCore.QObject):
self.frequency_label = QtWidgets.QLabel("") self.frequency_label = QtWidgets.QLabel("")
self.frequency_label.setMinimumWidth(100) self.frequency_label.setMinimumWidth(100)
self.impedance_label = QtWidgets.QLabel("") self.impedance_label = QtWidgets.QLabel("")
# self.admittance_label = QtWidgets.QLabel("")
self.parallel_r_label = QtWidgets.QLabel("")
self.parallel_x_label = QtWidgets.QLabel("")
self.returnloss_label = QtWidgets.QLabel("") self.returnloss_label = QtWidgets.QLabel("")
self.returnloss_label.setMinimumWidth(80) self.returnloss_label.setMinimumWidth(80)
self.vswr_label = QtWidgets.QLabel("") self.vswr_label = QtWidgets.QLabel("")
@ -90,17 +93,20 @@ class Marker(QtCore.QObject):
box_layout.addLayout(right_form) box_layout.addLayout(right_form)
# Left side # Left side
left_form.addRow(QtWidgets.QLabel("Frequency:"), self.frequency_label) left_form.addRow("Frequency:", self.frequency_label)
left_form.addRow(QtWidgets.QLabel("Impedance:"), self.impedance_label) left_form.addRow("Impedance:", self.impedance_label)
left_form.addRow(QtWidgets.QLabel("L equiv.:"), self.inductance_label) # left_form.addRow("Admittance:", self.admittance_label)
left_form.addRow(QtWidgets.QLabel("C equiv.:"), self.capacitance_label) left_form.addRow("Parallel R:", self.parallel_r_label)
left_form.addRow(QtWidgets.QLabel("Q:"), self.quality_factor_label) left_form.addRow("Parallel X:", self.parallel_x_label)
left_form.addRow("L equiv.:", self.inductance_label)
left_form.addRow("C equiv.:", self.capacitance_label)
# Right side # Right side
right_form.addRow(QtWidgets.QLabel("Return loss:"), self.returnloss_label) right_form.addRow("Return loss:", self.returnloss_label)
right_form.addRow(QtWidgets.QLabel("VSWR:"), self.vswr_label) right_form.addRow("VSWR:", self.vswr_label)
right_form.addRow(QtWidgets.QLabel("S21 Gain:"), self.gain_label) right_form.addRow("Q:", self.quality_factor_label)
right_form.addRow(QtWidgets.QLabel("S21 Phase:"), self.phase_label) right_form.addRow("S21 Gain:", self.gain_label)
right_form.addRow("S21 Phase:", self.phase_label)
def setFrequency(self, frequency): def setFrequency(self, frequency):
from .NanoVNASaver import NanoVNASaver from .NanoVNASaver import NanoVNASaver
@ -144,6 +150,9 @@ class Marker(QtCore.QObject):
def resetLabels(self): def resetLabels(self):
self.frequency_label.setText("") self.frequency_label.setText("")
self.impedance_label.setText("") self.impedance_label.setText("")
self.parallel_r_label.setText("")
self.parallel_x_label.setText("")
# self.admittance_label.setText("")
self.vswr_label.setText("") self.vswr_label.setText("")
self.returnloss_label.setText("") self.returnloss_label.setText("")
self.inductance_label.setText("") self.inductance_label.setText("")
@ -157,15 +166,27 @@ class Marker(QtCore.QObject):
from NanoVNASaver.NanoVNASaver import NanoVNASaver from NanoVNASaver.NanoVNASaver import NanoVNASaver
if self.location != -1: if self.location != -1:
im50, re50, vswr = NanoVNASaver.vswr(s11data[self.location]) im50, re50, vswr = NanoVNASaver.vswr(s11data[self.location])
re50 = round(re50, 4 - math.floor(math.log10(abs(re50)))) rp = (re50 ** 2 + im50 ** 2) / re50
im50 = round(im50, 4 - math.floor(math.log10(abs(im50)))) xp = (re50 ** 2 + im50 ** 2) / im50
re50 = round(re50, 4 - max(0, math.floor(math.log10(abs(re50)))))
rp = round(rp, 4 - max(0, math.floor(math.log10(abs(rp)))))
im50 = round(im50, 4 - max(0, math.floor(math.log10(abs(im50)))))
xp = round(xp, 4 - max(0, math.floor(math.log10(abs(xp)))))
if im50 < 0: if im50 < 0:
im50str = " -j" + str(-1 * im50) im50str = " -j" + str(-1 * im50)
else: else:
im50str = " +j" + str(im50) im50str = " +j" + str(im50)
im50str += "\N{OHM SIGN}"
if xp < 0:
xpstr = NanoVNASaver.capacitanceEquivalent(xp, s11data[self.location].freq)
else:
xpstr = NanoVNASaver.inductanceEquivalent(xp, s11data[self.location].freq)
self.frequency_label.setText(NanoVNASaver.formatFrequency(s11data[self.location].freq)) self.frequency_label.setText(NanoVNASaver.formatFrequency(s11data[self.location].freq))
self.impedance_label.setText(str(round(re50, 3)) + im50str) self.impedance_label.setText(str(re50) + im50str)
self.parallel_r_label.setText(str(rp) + "\N{OHM SIGN}")
self.parallel_x_label.setText(xpstr)
self.returnloss_label.setText(str(round(20 * math.log10((vswr - 1) / (vswr + 1)), 3)) + " dB") self.returnloss_label.setText(str(round(20 * math.log10((vswr - 1) / (vswr + 1)), 3)) + " dB")
capacitance = NanoVNASaver.capacitanceEquivalent(im50, s11data[self.location].freq) capacitance = NanoVNASaver.capacitanceEquivalent(im50, s11data[self.location].freq)
inductance = NanoVNASaver.inductanceEquivalent(im50, s11data[self.location].freq) inductance = NanoVNASaver.inductanceEquivalent(im50, s11data[self.location].freq)

Wyświetl plik

@ -37,7 +37,7 @@ PID = 22336
class NanoVNASaver(QtWidgets.QWidget): class NanoVNASaver(QtWidgets.QWidget):
version = "0.0.8" version = "0.0.9"
def __init__(self): def __init__(self):
super().__init__() super().__init__()
@ -118,12 +118,15 @@ class NanoVNASaver(QtWidgets.QWidget):
left_column = QtWidgets.QVBoxLayout() left_column = QtWidgets.QVBoxLayout()
marker_column = QtWidgets.QVBoxLayout() marker_column = QtWidgets.QVBoxLayout()
self.marker_frame = QtWidgets.QFrame()
marker_column.setContentsMargins(0, 0, 0, 0)
self.marker_frame.setLayout(marker_column)
right_column = QtWidgets.QVBoxLayout() right_column = QtWidgets.QVBoxLayout()
right_column.addLayout(self.charts_layout) right_column.addLayout(self.charts_layout)
self.marker_frame.setHidden(not self.settings.value("MarkersVisible", True, bool))
layout.addLayout(left_column, 0, 0) layout.addLayout(left_column, 0, 0)
layout.addLayout(marker_column, 0, 1) layout.addWidget(self.marker_frame, 0, 1)
layout.addLayout(right_column, 0, 2) layout.addLayout(right_column, 0, 2)
################################################################################################################ ################################################################################################################
@ -214,7 +217,7 @@ class NanoVNASaver(QtWidgets.QWidget):
marker_control_box = QtWidgets.QGroupBox() marker_control_box = QtWidgets.QGroupBox()
marker_control_box.setTitle("Markers") marker_control_box.setTitle("Markers")
marker_control_box.setMaximumWidth(350) marker_control_box.setMaximumWidth(250)
marker_control_layout = QtWidgets.QFormLayout(marker_control_box) marker_control_layout = QtWidgets.QFormLayout(marker_control_box)
@ -238,18 +241,27 @@ class NanoVNASaver(QtWidgets.QWidget):
marker3.updated.connect(self.dataUpdated) marker3.updated.connect(self.dataUpdated)
label, layout = marker3.getRow() label, layout = marker3.getRow()
marker_control_layout.addRow(label, layout) marker_control_layout.addRow(label, layout)
self.markers.append(marker3) self.markers.append(marker3)
self.showMarkerButton = QtWidgets.QPushButton()
if self.marker_frame.isHidden():
self.showMarkerButton.setText("Show data")
else:
self.showMarkerButton.setText("Hide data")
self.showMarkerButton.clicked.connect(self.toggleMarkerFrame)
marker_control_layout.addRow(self.showMarkerButton)
for c in self.charts: for c in self.charts:
c.setMarkers(self.markers) c.setMarkers(self.markers)
#marker3.frequencyInput.setDisabled(True) #marker3.frequencyInput.setDisabled(True)
marker_column.addWidget(marker_control_box) left_column.addWidget(marker_control_box)
marker_column.addWidget(self.markers[0].getGroupBox()) marker_column.addWidget(self.markers[0].getGroupBox())
marker_column.addWidget(self.markers[1].getGroupBox()) marker_column.addWidget(self.markers[1].getGroupBox())
marker_column.addWidget(self.markers[2].getGroupBox()) marker_column.addWidget(self.markers[2].getGroupBox())
################################################################################################################ ################################################################################################################
# Statistics/analysis # Statistics/analysis
################################################################################################################ ################################################################################################################
@ -495,7 +507,8 @@ class NanoVNASaver(QtWidgets.QWidget):
self.lister = QtWidgets.QPlainTextEdit() self.lister = QtWidgets.QPlainTextEdit()
self.lister.setFixedHeight(200) self.lister.setFixedHeight(200)
self.lister.setMaximumWidth(350) self.lister.setMaximumWidth(350)
marker_column.addWidget(self.lister) # The lister doesn't really need to be visible for now. Maybe put it in a separate window?
#marker_column.addWidget(self.lister)
self.worker.signals.updated.connect(self.dataUpdated) self.worker.signals.updated.connect(self.dataUpdated)
self.worker.signals.finished.connect(self.sweepFinished) self.worker.signals.finished.connect(self.sweepFinished)
@ -776,10 +789,7 @@ class NanoVNASaver(QtWidgets.QWidget):
@staticmethod @staticmethod
def vswr(data: Datapoint): def vswr(data: Datapoint):
re = data.re im50, re50 = NanoVNASaver.normalize50(data)
im = data.im
re50 = 50 * (1 - re * re - im * im) / (1 + re * re + im * im - 2 * re)
im50 = 50 * (2 * im) / (1 + re * re + im * im - 2 * re)
mag = math.sqrt((re50 - 50) * (re50 - 50) + im50 * im50) / math.sqrt((re50 + 50) * (re50 + 50) + im50 * im50) mag = math.sqrt((re50 - 50) * (re50 - 50) + im50 * im50) / math.sqrt((re50 + 50) * (re50 + 50) + im50 * im50)
# mag = math.sqrt(re * re + im * im) # Is this even right? # mag = math.sqrt(re * re + im * im) # Is this even right?
vswr = (1 + mag) / (1 - mag) vswr = (1 + mag) / (1 - mag)
@ -806,15 +816,27 @@ class NanoVNASaver(QtWidgets.QWidget):
@staticmethod @staticmethod
def gain(data: Datapoint): def gain(data: Datapoint):
re = data.re im50, re50 = NanoVNASaver.normalize50(data)
im = data.im
re50 = 50 * (1 - re * re - im * im) / (1 + re * re + im * im - 2 * re)
im50 = 50 * (2 * im) / (1 + re * re + im * im - 2 * re)
# Calculate the gain / reflection coefficient # Calculate the gain / reflection coefficient
mag = math.sqrt((re50 - 50) * (re50 - 50) + im50 * im50) / math.sqrt( mag = math.sqrt((re50 - 50) * (re50 - 50) + im50 * im50) / math.sqrt(
(re50 + 50) * (re50 + 50) + im50 * im50) (re50 + 50) * (re50 + 50) + im50 * im50)
return 20 * math.log10(mag) return 20 * math.log10(mag)
@staticmethod
def normalize50(data):
re = data.re
im = data.im
re50 = 50 * (1 - re * re - im * im) / (1 + re * re + im * im - 2 * re)
im50 = 50 * (2 * im) / (1 + re * re + im * im - 2 * re)
return im50, re50
@staticmethod
def admittance(data):
re50, im50 = NanoVNASaver.normalize50(data)
rp = re50 / (re50**2 + im50**2)
xp = - im50 / (re50**2 + im50**2)
return rp, xp
def sweepFinished(self): def sweepFinished(self):
self.sweepProgressBar.setValue(100) self.sweepProgressBar.setValue(100)
self.btnSweep.setDisabled(False) self.btnSweep.setDisabled(False)
@ -964,6 +986,16 @@ class NanoVNASaver(QtWidgets.QWidget):
title = title + " (" + insert + ")" title = title + " (" + insert + ")"
self.setWindowTitle(title) self.setWindowTitle(title)
def toggleMarkerFrame(self):
if self.marker_frame.isHidden():
self.marker_frame.setHidden(False)
self.settings.setValue("MarkersVisible", True)
self.showMarkerButton.setText("Hide data")
else:
self.marker_frame.setHidden(True)
self.settings.setValue("MarkersVisible", False)
self.showMarkerButton.setText("Show data")
def resetReference(self): def resetReference(self):
self.referenceS11data = [] self.referenceS11data = []
self.referenceS21data = [] self.referenceS21data = []

Wyświetl plik

@ -69,7 +69,6 @@ class SweepWorker(QtCore.QRunnable):
span = sweepTo - sweepFrom span = sweepTo - sweepFrom
stepsize = int(span / (100 + (self.noSweeps-1)*101)) stepsize = int(span / (100 + (self.noSweeps-1)*101))
print("Doing " + str(100 + (self.noSweeps-1)*101) + " steps of size " + str(stepsize))
values = [] values = []
values12 = [] values12 = []
frequencies = [] frequencies = []
@ -191,4 +190,4 @@ class SweepWorker(QtCore.QRunnable):
return tmpfreq return tmpfreq
def setContinuousSweep(self, continuousSweep): def setContinuousSweep(self, continuousSweep):
self.continuousSweep = continuousSweep self.continuousSweep = continuousSweep

Wyświetl plik

@ -35,7 +35,7 @@ with open("README.md", "r") as fh:
setup( setup(
name='NanoVNASaver', name='NanoVNASaver',
url='https://github.com/mihtjel/nanovna-saver', url='https://github.com/mihtjel/nanovna-saver',
version='0.0.8', version='0.0.9',
author='Rune B. Broberg', author='Rune B. Broberg',
author_email='', author_email='',
packages=find_packages(), packages=find_packages(),