Cable impedance measurement - first version.

pull/71/head
Rune B. Broberg 2019-10-26 09:54:19 +02:00
rodzic 6acf4f532d
commit 55f7934df9
5 zmienionych plików z 55 dodań i 19 usunięć

Wyświetl plik

@ -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)

Wyświetl plik

@ -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)

Wyświetl plik

@ -14,5 +14,5 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
version = '0.1.4'
debug = False
version = '0.1.5alpha'
debug = True

Wyświetl plik

@ -1,3 +1,4 @@
scipy
pyqt5
pyserial
numpy

Wyświetl plik

@ -52,5 +52,6 @@ setup(
'pyserial',
'PyQt5==5.11.2',
'numpy',
'scipy'
],
)