diff --git a/NanoVNASaver/Chart.py b/NanoVNASaver/Chart.py index 0f4e44b..85add23 100644 --- a/NanoVNASaver/Chart.py +++ b/NanoVNASaver/Chart.py @@ -1875,10 +1875,11 @@ class TDRChart(Chart): def __init__(self, name): super().__init__(name) self.tdrWindow = None - self.leftMargin = 20 + self.leftMargin = 30 self.rightMargin = 20 - self.bottomMargin = 35 - self.setMinimumSize(250, 250) + self.bottomMargin = 25 + self.topMargin = 20 + self.setMinimumSize(300, 300) self.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)) pal = QtGui.QPalette() @@ -1975,12 +1976,12 @@ class TDRChart(Chart): qp.drawText(3, 15, self.name) width = self.width() - self.leftMargin - self.rightMargin - height = self.height() - self.bottomMargin + height = self.height() - self.bottomMargin - self.topMargin qp.setPen(QtGui.QPen(self.foregroundColor)) qp.drawLine(self.leftMargin - 5, self.height() - self.bottomMargin, self.width() - self.rightMargin, self.height() - self.bottomMargin) - qp.drawLine(self.leftMargin, 20, self.leftMargin, self.height() - self.bottomMargin + 5) + qp.drawLine(self.leftMargin, self.topMargin - 5, self.leftMargin, self.height() - self.bottomMargin + 5) ticks = math.floor((self.width() - self.leftMargin)/100) # Number of ticks does not include the origin @@ -1991,33 +1992,58 @@ class TDRChart(Chart): x_step = (max_index - min_index) / width else: min_index = 0 - max_index = len(self.tdrWindow.distance_axis) - x_step = len(self.tdrWindow.distance_axis) / (width * 2) + max_index = math.ceil(len(self.tdrWindow.distance_axis) / 2) + x_step = max_index / width - y_step = np.max(self.tdrWindow.td)*1.1 / height + # TODO: Limit the search to the selected span? + min_impedance = max(0, np.min(self.tdrWindow.step_response_Z) / 1.05) + max_impedance = min(10000, np.max(self.tdrWindow.step_response_Z) * 1.05) + + y_step = np.max(self.tdrWindow.td) * 1.1 / height + y_impedance_step = (max_impedance - min_impedance) / height for i in range(ticks): x = self.leftMargin + round((i + 1) * width / ticks) qp.setPen(QtGui.QPen(self.foregroundColor)) - qp.drawLine(x, 20, x, height) + qp.drawLine(x, self.topMargin, x, self.topMargin + height) qp.setPen(QtGui.QPen(self.textColor)) - qp.drawText(x - 15, 20 + height, + qp.drawText(x - 15, self.topMargin + height + 15, str(round(self.tdrWindow.distance_axis[min_index + int((x - self.leftMargin) * x_step) - 1]/2, 1)) + "m") qp.setPen(QtGui.QPen(self.textColor)) - qp.drawText(self.leftMargin - 10, 20 + height, + qp.drawText(self.leftMargin - 10, self.topMargin + height + 15, str(round(self.tdrWindow.distance_axis[min_index]/2, 1)) + "m") + y_ticks = math.floor(height / 60) + y_tick_step = height/y_ticks + + for i in range(y_ticks): + y = self.bottomMargin + int(i * y_tick_step) + qp.setPen(QtGui.QPen(self.foregroundColor)) + qp.drawLine(self.leftMargin, y, self.leftMargin + width, y) + y_val = max_impedance - y_impedance_step * i * y_tick_step + qp.drawText(3, y + 3, str(round(y_val, 1))) + + qp.drawText(3, self.topMargin + height + 3, str(round(min_impedance, 1))) + pen = QtGui.QPen(self.sweepColor) pen.setWidth(self.pointSize) qp.setPen(pen) - for i in range(len(self.tdrWindow.distance_axis)): + for i in range(min_index, max_index): if i < min_index or i > max_index: continue - qp.drawPoint(self.leftMargin + int((i - min_index) / x_step), height - int(self.tdrWindow.td[i] / y_step)) + pen.setColor(self.sweepColor) + qp.setPen(pen) + qp.drawPoint(self.leftMargin + int((i - min_index) / x_step), + (self.topMargin + height) - int(self.tdrWindow.td[i] / y_step)) + pen.setColor(self.secondarySweepColor) + qp.setPen(pen) + qp.drawPoint(self.leftMargin + int((i - min_index) / x_step), + (self.topMargin + height) - int((self.tdrWindow.step_response_Z[i]-min_impedance) / y_impedance_step)) + id_max = np.argmax(self.tdrWindow.td) max_point = QtCore.QPoint(self.leftMargin + int((id_max - min_index) / x_step), - height - int(self.tdrWindow.td[id_max] / y_step)) + (self.topMargin + height) - int(self.tdrWindow.td[id_max] / y_step)) qp.setPen(self.markers[0].color) qp.drawEllipse(max_point, 2, 2) qp.setPen(self.textColor) diff --git a/NanoVNASaver/NanoVNASaver.py b/NanoVNASaver/NanoVNASaver.py index e8333d6..aa18285 100644 --- a/NanoVNASaver/NanoVNASaver.py +++ b/NanoVNASaver/NanoVNASaver.py @@ -22,6 +22,7 @@ from time import sleep, strftime, localtime from typing import List, Tuple import numpy as np +import scipy.signal as signal import serial import typing from PyQt5 import QtWidgets, QtCore, QtGui @@ -1691,6 +1692,8 @@ class TDRWindow(QtWidgets.QWidget): self.td = [] self.distance_axis = [] + self.step_response = [] + self.step_response_Z = [] self.setWindowTitle("TDR") self.setWindowIcon(self.app.icon) @@ -1754,6 +1757,9 @@ class TDRWindow(QtWidgets.QWidget): def updateTDR(self): c = 299792458 + # TODO: Let the user select whether to use high or low resolution TDR? + FFT_POINTS = 2**14 + if len(self.app.data) < 2: return @@ -1781,12 +1787,14 @@ class TDRWindow(QtWidgets.QWidget): window = np.blackman(len(self.app.data)) windowed_s11 = window * s11 + self.td = np.abs(np.fft.ifft(windowed_s11, FFT_POINTS)) + step = np.ones(FFT_POINTS) + self.step_response = signal.convolve(self.td, step) - self.td = np.abs(np.fft.ifft(windowed_s11, 2**16)) + self.step_response_Z = 50 * (1 + self.step_response) / (1 - self.step_response) - time_axis = np.linspace(0, 1/step_size, 2**16) + time_axis = np.linspace(0, 1/step_size, FFT_POINTS) self.distance_axis = time_axis * v * c - # peak = np.max(td) # We should check that this is an actual *peak*, and not just a vague maximum index_peak = np.argmax(self.td) diff --git a/NanoVNASaver/about.py b/NanoVNASaver/about.py index 96f5e5d..0bdc267 100644 --- a/NanoVNASaver/about.py +++ b/NanoVNASaver/about.py @@ -14,5 +14,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -version = '0.1.4' -debug = False +version = '0.1.5alpha' +debug = True diff --git a/requirements.txt b/requirements.txt index 117fb75..c058afa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +scipy pyqt5 pyserial numpy \ No newline at end of file diff --git a/setup.py b/setup.py index 3a4b50e..7582693 100644 --- a/setup.py +++ b/setup.py @@ -52,5 +52,6 @@ setup( 'pyserial', 'PyQt5==5.11.2', 'numpy', + 'scipy' ], )