kopia lustrzana https://github.com/NanoVNA-Saver/nanovna-saver
Merge pull request #536 from zarath/bugfix/535_msspad
Made changes on suggestions of #535 by @msspadpull/537/head
commit
b2b64ab9cd
|
@ -23,9 +23,9 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
python3.9 -m venv build
|
python3.9 -m venv build
|
||||||
. build/bin/activate
|
. build/bin/activate
|
||||||
python -m pip install pip==22.1.2 setuptools==62.6.0
|
python -m pip install pip==22.2.2 setuptools==65.3.0
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
pip install PyInstaller==5.1
|
pip install PyInstaller==5.3
|
||||||
- name: Build binary
|
- name: Build binary
|
||||||
run: |
|
run: |
|
||||||
. build/bin/activate
|
. build/bin/activate
|
||||||
|
|
|
@ -18,9 +18,9 @@ jobs:
|
||||||
python-version: 3.9
|
python-version: 3.9
|
||||||
- name: Install dependencies and pyinstall
|
- name: Install dependencies and pyinstall
|
||||||
run: |
|
run: |
|
||||||
python -m pip install pip==22.1.2 setuptools==62.6.0
|
python -m pip install pip==22.2.2 setuptools==65.3.0
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
pip install PyInstaller=5.1
|
pip install PyInstaller=5.3
|
||||||
- name: Build binary
|
- name: Build binary
|
||||||
run: |
|
run: |
|
||||||
pyinstaller --onefile -n nanovna-saver nanovna-saver.py
|
pyinstaller --onefile -n nanovna-saver nanovna-saver.py
|
||||||
|
|
|
@ -22,9 +22,9 @@ jobs:
|
||||||
architecture: ${{ matrix.arch }}
|
architecture: ${{ matrix.arch }}
|
||||||
- name: Install dependencies and pyinstall
|
- name: Install dependencies and pyinstall
|
||||||
run: |
|
run: |
|
||||||
python -m pip install pip==22.1.2 setuptools==62.6.0
|
python -m pip install pip==22.2.2 setuptools==65.3.0
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
pip install PyInstaller==5.1
|
pip install PyInstaller==5.3
|
||||||
- name: Build binary
|
- name: Build binary
|
||||||
run: |
|
run: |
|
||||||
pyinstaller --onefile -n nanovna-saver.exe nanovna-saver.py
|
pyinstaller --onefile -n nanovna-saver.exe nanovna-saver.py
|
||||||
|
|
|
@ -109,11 +109,13 @@ class TDRChart(Chart):
|
||||||
|
|
||||||
self.y_action_set_fixed_maximum = QtWidgets.QAction(
|
self.y_action_set_fixed_maximum = QtWidgets.QAction(
|
||||||
f"Maximum ({self.maxImpedance})")
|
f"Maximum ({self.maxImpedance})")
|
||||||
self.y_action_set_fixed_maximum.triggered.connect(self.setMaximumImpedance)
|
self.y_action_set_fixed_maximum.triggered.connect(
|
||||||
|
self.setMaximumImpedance)
|
||||||
|
|
||||||
self.y_action_set_fixed_minimum = QtWidgets.QAction(
|
self.y_action_set_fixed_minimum = QtWidgets.QAction(
|
||||||
f"Minimum ({self.minImpedance})")
|
f"Minimum ({self.minImpedance})")
|
||||||
self.y_action_set_fixed_minimum.triggered.connect(self.setMinimumImpedance)
|
self.y_action_set_fixed_minimum.triggered.connect(
|
||||||
|
self.setMinimumImpedance)
|
||||||
|
|
||||||
self.y_menu.addAction(self.y_action_set_fixed_maximum)
|
self.y_menu.addAction(self.y_action_set_fixed_maximum)
|
||||||
self.y_menu.addAction(self.y_action_set_fixed_minimum)
|
self.y_menu.addAction(self.y_action_set_fixed_minimum)
|
||||||
|
@ -143,7 +145,7 @@ class TDRChart(Chart):
|
||||||
|
|
||||||
def isPlotable(self, x, y):
|
def isPlotable(self, x, y):
|
||||||
return self.leftMargin <= x <= self.width() - self.rightMargin and \
|
return self.leftMargin <= x <= self.width() - self.rightMargin and \
|
||||||
self.topMargin <= y <= self.height() - self.bottomMargin
|
self.topMargin <= y <= self.height() - self.bottomMargin
|
||||||
|
|
||||||
def resetDisplayLimits(self):
|
def resetDisplayLimits(self):
|
||||||
self.fixedSpan = False
|
self.fixedSpan = False
|
||||||
|
@ -256,10 +258,12 @@ class TDRChart(Chart):
|
||||||
return
|
return
|
||||||
a0.accept()
|
a0.accept()
|
||||||
width = self.width() - self.leftMargin - self.rightMargin
|
width = self.width() - self.leftMargin - self.rightMargin
|
||||||
if len(self.tdrWindow.td) > 0:
|
if self.tdrWindow.td.size:
|
||||||
if self.fixedSpan:
|
if self.fixedSpan:
|
||||||
max_index = np.searchsorted(self.tdrWindow.distance_axis, self.maxDisplayLength * 2)
|
max_index = np.searchsorted(
|
||||||
min_index = np.searchsorted(self.tdrWindow.distance_axis, self.minDisplayLength * 2)
|
self.tdrWindow.distance_axis, self.maxDisplayLength * 2)
|
||||||
|
min_index = np.searchsorted(
|
||||||
|
self.tdrWindow.distance_axis, self.minDisplayLength * 2)
|
||||||
x_step = (max_index - min_index) / width
|
x_step = (max_index - min_index) / width
|
||||||
else:
|
else:
|
||||||
max_index = math.ceil(len(self.tdrWindow.distance_axis) / 2)
|
max_index = math.ceil(len(self.tdrWindow.distance_axis) / 2)
|
||||||
|
@ -290,11 +294,13 @@ class TDRChart(Chart):
|
||||||
ticks = math.floor((self.width() - self.leftMargin) / 100)
|
ticks = math.floor((self.width() - self.leftMargin) / 100)
|
||||||
self.drawTitle(qp)
|
self.drawTitle(qp)
|
||||||
|
|
||||||
if self.tdrWindow.td:
|
if self.tdrWindow.td.size:
|
||||||
if self.fixedSpan:
|
if self.fixedSpan:
|
||||||
max_length = max(0.1, self.maxDisplayLength)
|
max_length = max(0.1, self.maxDisplayLength)
|
||||||
max_index = np.searchsorted(self.tdrWindow.distance_axis, max_length * 2)
|
max_index = np.searchsorted(
|
||||||
min_index = np.searchsorted(self.tdrWindow.distance_axis, self.minDisplayLength * 2)
|
self.tdrWindow.distance_axis, max_length * 2)
|
||||||
|
min_index = np.searchsorted(
|
||||||
|
self.tdrWindow.distance_axis, self.minDisplayLength * 2)
|
||||||
if max_index == min_index:
|
if max_index == min_index:
|
||||||
if max_index < len(self.tdrWindow.distance_axis) - 1:
|
if max_index < len(self.tdrWindow.distance_axis) - 1:
|
||||||
max_index += 1
|
max_index += 1
|
||||||
|
@ -343,7 +349,7 @@ class TDRChart(Chart):
|
||||||
1)) + "m")
|
1)) + "m")
|
||||||
|
|
||||||
y_ticks = math.floor(height / 60)
|
y_ticks = math.floor(height / 60)
|
||||||
y_tick_step = height/y_ticks
|
y_tick_step = height / y_ticks
|
||||||
|
|
||||||
for i in range(y_ticks):
|
for i in range(y_ticks):
|
||||||
y = self.bottomMargin + int(i * y_tick_step)
|
y = self.bottomMargin + int(i * y_tick_step)
|
||||||
|
@ -353,7 +359,8 @@ class TDRChart(Chart):
|
||||||
qp.setPen(Chart.color.text)
|
qp.setPen(Chart.color.text)
|
||||||
qp.drawText(3, y + 3, str(round(y_val, 1)))
|
qp.drawText(3, y + 3, str(round(y_val, 1)))
|
||||||
|
|
||||||
qp.drawText(3, self.topMargin + height + 3, str(round(min_impedance, 1)))
|
qp.drawText(3, self.topMargin + height + 3,
|
||||||
|
str(round(min_impedance, 1)))
|
||||||
|
|
||||||
pen = QtGui.QPen(Chart.color.sweep)
|
pen = QtGui.QPen(Chart.color.sweep)
|
||||||
pen.setWidth(self.dim.point)
|
pen.setWidth(self.dim.point)
|
||||||
|
@ -363,15 +370,17 @@ class TDRChart(Chart):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
x = self.leftMargin + int((i - min_index) / x_step)
|
x = self.leftMargin + int((i - min_index) / x_step)
|
||||||
y = (self.topMargin + height) - int(self.tdrWindow.td[i] / y_step)
|
y = (self.topMargin + height) - \
|
||||||
|
int(self.tdrWindow.td[i] / y_step)
|
||||||
if self.isPlotable(x, y):
|
if self.isPlotable(x, y):
|
||||||
pen.setColor(Chart.color.sweep)
|
pen.setColor(Chart.color.sweep)
|
||||||
qp.setPen(pen)
|
qp.setPen(pen)
|
||||||
qp.drawPoint(x, y)
|
qp.drawPoint(x, y)
|
||||||
|
|
||||||
x = self.leftMargin + int((i - min_index) / x_step)
|
x = self.leftMargin + int((i - min_index) / x_step)
|
||||||
y = (self.topMargin + height) -\
|
y = (self.topMargin + height) - int(
|
||||||
int((self.tdrWindow.step_response_Z[i]-min_impedance) / y_impedance_step)
|
(self.tdrWindow.step_response_Z[i] - min_impedance) /
|
||||||
|
y_impedance_step)
|
||||||
if self.isPlotable(x, y):
|
if self.isPlotable(x, y):
|
||||||
pen.setColor(Chart.color.sweep_secondary)
|
pen.setColor(Chart.color.sweep_secondary)
|
||||||
qp.setPen(pen)
|
qp.setPen(pen)
|
||||||
|
@ -403,7 +412,8 @@ class TDRChart(Chart):
|
||||||
2)) + "m")
|
2)) + "m")
|
||||||
|
|
||||||
if self.dragbox.state and self.dragbox.pos[0] != -1:
|
if self.dragbox.state and self.dragbox.pos[0] != -1:
|
||||||
dashed_pen = QtGui.QPen(Chart.color.foreground, 1, QtCore.Qt.DashLine)
|
dashed_pen = QtGui.QPen(
|
||||||
|
Chart.color.foreground, 1, QtCore.Qt.DashLine)
|
||||||
qp.setPen(dashed_pen)
|
qp.setPen(dashed_pen)
|
||||||
qp.drawRect(
|
qp.drawRect(
|
||||||
QtCore.QRect(
|
QtCore.QRect(
|
||||||
|
@ -415,7 +425,7 @@ class TDRChart(Chart):
|
||||||
qp.end()
|
qp.end()
|
||||||
|
|
||||||
def valueAtPosition(self, y):
|
def valueAtPosition(self, y):
|
||||||
if len(self.tdrWindow.td) > 0:
|
if self.tdrWindow.td.size:
|
||||||
height = self.height() - self.topMargin - self.bottomMargin
|
height = self.height() - self.topMargin - self.bottomMargin
|
||||||
absy = (self.height() - y) - self.bottomMargin
|
absy = (self.height() - y) - self.bottomMargin
|
||||||
if self.fixedValues:
|
if self.fixedValues:
|
||||||
|
@ -433,27 +443,24 @@ class TDRChart(Chart):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def lengthAtPosition(self, x, limit=True):
|
def lengthAtPosition(self, x, limit=True):
|
||||||
if not self.tdrWindow.td:
|
if not self.tdrWindow.td.size:
|
||||||
return 0
|
return 0
|
||||||
width = self.width() - self.leftMargin - self.rightMargin
|
width = self.width() - self.leftMargin - self.rightMargin
|
||||||
absx = x - self.leftMargin
|
absx = x - self.leftMargin
|
||||||
if self.fixedSpan:
|
min_length = self.minDisplayLength if self.fixedSpan else 0
|
||||||
max_length = self.maxDisplayLength
|
max_length = self.maxDisplayLength if self.fixedSpan else (
|
||||||
min_length = self.minDisplayLength
|
self.tdrWindow.distance_axis[
|
||||||
x_step = (max_length - min_length) / width
|
math.ceil(len(self.tdrWindow.distance_axis) / 2)
|
||||||
else:
|
] / 2)
|
||||||
min_length = 0
|
|
||||||
max_length = self.tdrWindow.distance_axis[
|
x_step = (max_length - min_length) / width
|
||||||
math.ceil(len(self.tdrWindow.distance_axis) / 2)] / 2
|
|
||||||
x_step = max_length / width
|
|
||||||
if limit and absx < 0:
|
if limit and absx < 0:
|
||||||
return min_length
|
return min_length
|
||||||
if limit and absx > width:
|
return max_length if limit and absx > width else absx * x_step + min_length
|
||||||
return max_length
|
|
||||||
return absx * x_step + min_length
|
|
||||||
|
|
||||||
def zoomTo(self, x1, y1, x2, y2):
|
def zoomTo(self, x1, y1, x2, y2):
|
||||||
logger.debug("Zoom to (x,y) by (x,y): (%d, %d) by (%d, %d)", x1, y1, x2, y2)
|
logger.debug(
|
||||||
|
"Zoom to (x,y) by (x,y): (%d, %d) by (%d, %d)", x1, y1, x2, y2)
|
||||||
val1 = self.valueAtPosition(y1)
|
val1 = self.valueAtPosition(y1)
|
||||||
val2 = self.valueAtPosition(y2)
|
val2 = self.valueAtPosition(y2)
|
||||||
|
|
||||||
|
|
|
@ -128,13 +128,30 @@ class NanoVNA_V2(VNA):
|
||||||
def readFrequencies(self) -> List[int]:
|
def readFrequencies(self) -> List[int]:
|
||||||
return [
|
return [
|
||||||
int(self.sweepStartHz + i * self.sweepStepHz)
|
int(self.sweepStartHz + i * self.sweepStepHz)
|
||||||
for i in range(self.datapoints)]
|
for i in range(self.datapoints)
|
||||||
|
]
|
||||||
|
|
||||||
|
def _read_pointstoread(self, pointstoread, arr) -> None:
|
||||||
|
freq_index = -1
|
||||||
|
|
||||||
|
for i in range(pointstoread):
|
||||||
|
(fwd_real, fwd_imag, rev0_real, rev0_imag, rev1_real,
|
||||||
|
rev1_imag, freq_index) = unpack_from(
|
||||||
|
"<iiiiiihxxxxxx", arr, i * 32)
|
||||||
|
fwd = complex(fwd_real, fwd_imag)
|
||||||
|
refl = complex(rev0_real, rev0_imag)
|
||||||
|
thru = complex(rev1_real, rev1_imag)
|
||||||
|
if i == 0:
|
||||||
|
logger.debug("Freq index from: %i", freq_index)
|
||||||
|
self._sweepdata[freq_index] = (refl / fwd, thru / fwd)
|
||||||
|
|
||||||
|
logger.debug("Freq index to: %i", freq_index)
|
||||||
|
|
||||||
def readValues(self, value) -> List[str]:
|
def readValues(self, value) -> List[str]:
|
||||||
# Actually grab the data only when requesting channel 0.
|
# Actually grab the data only when requesting channel 0.
|
||||||
# The hardware will return all channels which we will store.
|
# The hardware will return all channels which we will store.
|
||||||
if value == "data 0":
|
if value == "data 0":
|
||||||
s21hack = "S21 hack" in self.features
|
s21hack = 1 if "S21 hack" in self.features else 0
|
||||||
# reset protocol to known state
|
# reset protocol to known state
|
||||||
timeout = self.serial.timeout
|
timeout = self.serial.timeout
|
||||||
with self.serial.lock:
|
with self.serial.lock:
|
||||||
|
@ -146,7 +163,7 @@ class NanoVNA_V2(VNA):
|
||||||
sleep(WRITE_SLEEP)
|
sleep(WRITE_SLEEP)
|
||||||
# clear sweepdata
|
# clear sweepdata
|
||||||
self._sweepdata = [(complex(), complex())] * (
|
self._sweepdata = [(complex(), complex())] * (
|
||||||
self.datapoints + s21hack)
|
self.datapoints + s21hack)
|
||||||
pointstodo = self.datapoints + s21hack
|
pointstodo = self.datapoints + s21hack
|
||||||
# we read at most 255 values at a time and the time required empirically is
|
# we read at most 255 values at a time and the time required empirically is
|
||||||
# just over 3 seconds for 101 points or 7 seconds for 255 points
|
# just over 3 seconds for 101 points or 7 seconds for 255 points
|
||||||
|
@ -175,18 +192,7 @@ class NanoVNA_V2(VNA):
|
||||||
if nBytes != len(arr):
|
if nBytes != len(arr):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
freq_index = -1
|
self._read_pointstoread(pointstoread, arr)
|
||||||
for i in range(pointstoread):
|
|
||||||
(fwd_real, fwd_imag, rev0_real, rev0_imag, rev1_real,
|
|
||||||
rev1_imag, freq_index) = unpack_from(
|
|
||||||
"<iiiiiihxxxxxx", arr, i * 32)
|
|
||||||
fwd = complex(fwd_real, fwd_imag)
|
|
||||||
refl = complex(rev0_real, rev0_imag)
|
|
||||||
thru = complex(rev1_real, rev1_imag)
|
|
||||||
if i == 0:
|
|
||||||
logger.debug("Freq index from: %i", freq_index)
|
|
||||||
self._sweepdata[freq_index] = (refl / fwd, thru / fwd)
|
|
||||||
logger.debug("Freq index to: %i", freq_index)
|
|
||||||
|
|
||||||
pointstodo = pointstodo - pointstoread
|
pointstodo = pointstodo - pointstoread
|
||||||
self.serial.timeout = timeout
|
self.serial.timeout = timeout
|
||||||
|
@ -194,24 +200,17 @@ class NanoVNA_V2(VNA):
|
||||||
if s21hack:
|
if s21hack:
|
||||||
self._sweepdata = self._sweepdata[1:]
|
self._sweepdata = self._sweepdata[1:]
|
||||||
|
|
||||||
ret = [x[0] for x in self._sweepdata]
|
idx = 1 if value == "data 1" else 0
|
||||||
ret = [str(x.real) + ' ' + str(x.imag) for x in ret]
|
return [
|
||||||
return ret
|
f'{str(x[idx].real)} {str(x[idx].imag)}'
|
||||||
|
for x in self._sweepdata
|
||||||
if value == "data 1":
|
]
|
||||||
ret = [x[1] for x in self._sweepdata]
|
|
||||||
ret = [str(x.real) + ' ' + str(x.imag) for x in ret]
|
|
||||||
return ret
|
|
||||||
|
|
||||||
return []
|
|
||||||
|
|
||||||
def resetSweep(self, start: int, stop: int):
|
def resetSweep(self, start: int, stop: int):
|
||||||
self.setSweep(start, stop)
|
self.setSweep(start, stop)
|
||||||
|
|
||||||
def readVersion(self) -> 'Version':
|
def _read_version(self, cmd_0: int, cmd_1: int):
|
||||||
cmd = pack("<BBBB",
|
cmd = pack("<BBBB", _CMD_READ, cmd_0, _CMD_READ, cmd_1)
|
||||||
_CMD_READ, _ADDR_FW_MAJOR,
|
|
||||||
_CMD_READ, _ADDR_FW_MINOR)
|
|
||||||
with self.serial.lock:
|
with self.serial.lock:
|
||||||
self.serial.write(cmd)
|
self.serial.write(cmd)
|
||||||
sleep(WRITE_SLEEP)
|
sleep(WRITE_SLEEP)
|
||||||
|
@ -219,22 +218,17 @@ class NanoVNA_V2(VNA):
|
||||||
if len(resp) != 2:
|
if len(resp) != 2:
|
||||||
logger.error("Timeout reading version registers. Got: %s", resp)
|
logger.error("Timeout reading version registers. Got: %s", resp)
|
||||||
raise IOError("Timeout reading version registers")
|
raise IOError("Timeout reading version registers")
|
||||||
result = Version(f"{resp[0]}.0.{resp[1]}")
|
return Version(f"{resp[0]}.0.{resp[1]}")
|
||||||
|
|
||||||
|
def readVersion(self) -> 'Version':
|
||||||
|
result = self._read_version(_ADDR_FW_MAJOR,
|
||||||
|
_ADDR_FW_MINOR)
|
||||||
logger.debug("readVersion: %s", result)
|
logger.debug("readVersion: %s", result)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def read_board_revision(self) -> 'Version':
|
def read_board_revision(self) -> 'Version':
|
||||||
cmd = pack("<BBBB",
|
result = self._read_version(_ADDR_DEVICE_VARIANT,
|
||||||
_CMD_READ, _ADDR_DEVICE_VARIANT,
|
_ADDR_HARDWARE_REVISION)
|
||||||
_CMD_READ, _ADDR_HARDWARE_REVISION)
|
|
||||||
with self.serial.lock:
|
|
||||||
self.serial.write(cmd)
|
|
||||||
sleep(WRITE_SLEEP)
|
|
||||||
resp = self.serial.read(2)
|
|
||||||
if len(resp) != 2:
|
|
||||||
logger.error("Timeout reading version registers")
|
|
||||||
return None
|
|
||||||
result = Version(f"{resp[0]}.0.{resp[1]}")
|
|
||||||
logger.debug("read_board_revision: %s", result)
|
logger.debug("read_board_revision: %s", result)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,9 @@ import logging
|
||||||
import math
|
import math
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import scipy.signal as signal
|
from scipy import signal
|
||||||
from PyQt5 import QtWidgets, QtCore
|
|
||||||
|
|
||||||
|
from PyQt5 import QtWidgets, QtCore
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ class TDRWindow(QtWidgets.QWidget):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.app = app
|
self.app = app
|
||||||
|
|
||||||
self.td = []
|
self.td = np.array([])
|
||||||
self.distance_axis = []
|
self.distance_axis = []
|
||||||
self.step_response = []
|
self.step_response = []
|
||||||
self.step_response_Z = []
|
self.step_response_Z = []
|
||||||
|
@ -54,33 +54,47 @@ class TDRWindow(QtWidgets.QWidget):
|
||||||
self.tdr_velocity_dropdown.addItem("Pulp Insulation (0.72)", 0.72)
|
self.tdr_velocity_dropdown.addItem("Pulp Insulation (0.72)", 0.72)
|
||||||
self.tdr_velocity_dropdown.addItem("Foam or Cellular PE (0.78)", 0.78)
|
self.tdr_velocity_dropdown.addItem("Foam or Cellular PE (0.78)", 0.78)
|
||||||
self.tdr_velocity_dropdown.addItem("Semi-solid PE (SSPE) (0.84)", 0.84)
|
self.tdr_velocity_dropdown.addItem("Semi-solid PE (SSPE) (0.84)", 0.84)
|
||||||
self.tdr_velocity_dropdown.addItem("Air (Helical spacers) (0.94)", 0.94)
|
self.tdr_velocity_dropdown.addItem(
|
||||||
self.tdr_velocity_dropdown.insertSeparator(self.tdr_velocity_dropdown.count())
|
"Air (Helical spacers) (0.94)", 0.94)
|
||||||
|
self.tdr_velocity_dropdown.insertSeparator(
|
||||||
|
self.tdr_velocity_dropdown.count())
|
||||||
# Lots of cable types added by Larry Goga, AE5CZ
|
# Lots of cable types added by Larry Goga, AE5CZ
|
||||||
self.tdr_velocity_dropdown.addItem("RG-6/U PE 75\N{OHM SIGN} (Belden 8215) (0.66)", 0.66)
|
self.tdr_velocity_dropdown.addItem(
|
||||||
self.tdr_velocity_dropdown.addItem("RG-6/U Foam 75\N{OHM SIGN} (Belden 9290) (0.81)", 0.81)
|
"RG-6/U PE 75\N{OHM SIGN} (Belden 8215) (0.66)", 0.66)
|
||||||
self.tdr_velocity_dropdown.addItem("RG-8/U PE 50\N{OHM SIGN} (Belden 8237) (0.66)", 0.66)
|
self.tdr_velocity_dropdown.addItem(
|
||||||
self.tdr_velocity_dropdown.addItem("RG-8/U Foam (Belden 8214) (0.78)", 0.78)
|
"RG-6/U Foam 75\N{OHM SIGN} (Belden 9290) (0.81)", 0.81)
|
||||||
|
self.tdr_velocity_dropdown.addItem(
|
||||||
|
"RG-8/U PE 50\N{OHM SIGN} (Belden 8237) (0.66)", 0.66)
|
||||||
|
self.tdr_velocity_dropdown.addItem(
|
||||||
|
"RG-8/U Foam (Belden 8214) (0.78)", 0.78)
|
||||||
self.tdr_velocity_dropdown.addItem("RG-8/U (Belden 9913) (0.84)", 0.84)
|
self.tdr_velocity_dropdown.addItem("RG-8/U (Belden 9913) (0.84)", 0.84)
|
||||||
# Next one added by EKZ, KC3KZ, from measurement of actual cable
|
# Next one added by EKZ, KC3KZ, from measurement of actual cable
|
||||||
self.tdr_velocity_dropdown.addItem("RG-8/U (Shireen RFC®400 Low Loss) (0.86)", 0.86)
|
self.tdr_velocity_dropdown.addItem(
|
||||||
|
"RG-8/U (Shireen RFC®400 Low Loss) (0.86)", 0.86)
|
||||||
self.tdr_velocity_dropdown.addItem("RG-8X (Belden 9258) (0.82)", 0.82)
|
self.tdr_velocity_dropdown.addItem("RG-8X (Belden 9258) (0.82)", 0.82)
|
||||||
# Next three added by EKZ, KC3KZ, from measurement of actual cable
|
# Next three added by EKZ, KC3KZ, from measurement of actual cable
|
||||||
self.tdr_velocity_dropdown.addItem("RG-8X (Wireman \"Super 8\" CQ106) (0.81)", 0.81)
|
self.tdr_velocity_dropdown.addItem(
|
||||||
self.tdr_velocity_dropdown.addItem("RG-8X (Wireman \"MINI-8 Lo-Loss\" CQ118) (0.82)", 0.82)
|
"RG-8X (Wireman \"Super 8\" CQ106) (0.81)", 0.81)
|
||||||
|
self.tdr_velocity_dropdown.addItem(
|
||||||
|
"RG-8X (Wireman \"MINI-8 Lo-Loss\" CQ118) (0.82)", 0.82)
|
||||||
self.tdr_velocity_dropdown.addItem(
|
self.tdr_velocity_dropdown.addItem(
|
||||||
"RG-58 (Wireman \"CQ 58 Lo-Loss Flex\" CQ129FF) (0.79)", 0.79)
|
"RG-58 (Wireman \"CQ 58 Lo-Loss Flex\" CQ129FF) (0.79)", 0.79)
|
||||||
self.tdr_velocity_dropdown.addItem(
|
self.tdr_velocity_dropdown.addItem(
|
||||||
"RG-11/U 75\N{OHM SIGN} Foam HDPE (Belden 9292) (0.84)", 0.84)
|
"RG-11/U 75\N{OHM SIGN} Foam HDPE (Belden 9292) (0.84)", 0.84)
|
||||||
self.tdr_velocity_dropdown.addItem("RG-58/U 52\N{OHM SIGN} PE (Belden 9201) (0.66)", 0.66)
|
self.tdr_velocity_dropdown.addItem(
|
||||||
|
"RG-58/U 52\N{OHM SIGN} PE (Belden 9201) (0.66)", 0.66)
|
||||||
self.tdr_velocity_dropdown.addItem(
|
self.tdr_velocity_dropdown.addItem(
|
||||||
"RG-58A/U 54\N{OHM SIGN} Foam (Belden 8219) (0.73)", 0.73)
|
"RG-58A/U 54\N{OHM SIGN} Foam (Belden 8219) (0.73)", 0.73)
|
||||||
self.tdr_velocity_dropdown.addItem("RG-59A/U PE 75\N{OHM SIGN} (Belden 8241) (0.66)", 0.66)
|
self.tdr_velocity_dropdown.addItem(
|
||||||
|
"RG-59A/U PE 75\N{OHM SIGN} (Belden 8241) (0.66)", 0.66)
|
||||||
self.tdr_velocity_dropdown.addItem(
|
self.tdr_velocity_dropdown.addItem(
|
||||||
"RG-59A/U Foam 75\N{OHM SIGN} (Belden 8241F) (0.78)", 0.78)
|
"RG-59A/U Foam 75\N{OHM SIGN} (Belden 8241F) (0.78)", 0.78)
|
||||||
self.tdr_velocity_dropdown.addItem("RG-174 PE (Belden 8216)(0.66)", 0.66)
|
self.tdr_velocity_dropdown.addItem(
|
||||||
self.tdr_velocity_dropdown.addItem("RG-174 Foam (Belden 7805R) (0.735)", 0.735)
|
"RG-174 PE (Belden 8216)(0.66)", 0.66)
|
||||||
self.tdr_velocity_dropdown.addItem("RG-213/U PE (Belden 8267) (0.66)", 0.66)
|
self.tdr_velocity_dropdown.addItem(
|
||||||
|
"RG-174 Foam (Belden 7805R) (0.735)", 0.735)
|
||||||
|
self.tdr_velocity_dropdown.addItem(
|
||||||
|
"RG-213/U PE (Belden 8267) (0.66)", 0.66)
|
||||||
self.tdr_velocity_dropdown.addItem("RG316 (0.695)", 0.695)
|
self.tdr_velocity_dropdown.addItem("RG316 (0.695)", 0.695)
|
||||||
self.tdr_velocity_dropdown.addItem("RG402 (0.695)", 0.695)
|
self.tdr_velocity_dropdown.addItem("RG402 (0.695)", 0.695)
|
||||||
self.tdr_velocity_dropdown.addItem("LMR-240 (0.84)", 0.84)
|
self.tdr_velocity_dropdown.addItem("LMR-240 (0.84)", 0.84)
|
||||||
|
@ -88,7 +102,8 @@ class TDRWindow(QtWidgets.QWidget):
|
||||||
self.tdr_velocity_dropdown.addItem("LMR-400 (0.85)", 0.85)
|
self.tdr_velocity_dropdown.addItem("LMR-400 (0.85)", 0.85)
|
||||||
self.tdr_velocity_dropdown.addItem("LMR400UF (0.83)", 0.83)
|
self.tdr_velocity_dropdown.addItem("LMR400UF (0.83)", 0.83)
|
||||||
self.tdr_velocity_dropdown.addItem("Davis Bury-FLEX (0.82)", 0.82)
|
self.tdr_velocity_dropdown.addItem("Davis Bury-FLEX (0.82)", 0.82)
|
||||||
self.tdr_velocity_dropdown.insertSeparator(self.tdr_velocity_dropdown.count())
|
self.tdr_velocity_dropdown.insertSeparator(
|
||||||
|
self.tdr_velocity_dropdown.count())
|
||||||
self.tdr_velocity_dropdown.addItem("Custom", -1)
|
self.tdr_velocity_dropdown.addItem("Custom", -1)
|
||||||
|
|
||||||
self.tdr_velocity_dropdown.setCurrentIndex(1) # Default to PE (0.66)
|
self.tdr_velocity_dropdown.setCurrentIndex(1) # Default to PE (0.66)
|
||||||
|
@ -121,7 +136,8 @@ class TDRWindow(QtWidgets.QWidget):
|
||||||
self.tdr_velocity_input.setDisabled(False)
|
self.tdr_velocity_input.setDisabled(False)
|
||||||
else:
|
else:
|
||||||
self.tdr_velocity_input.setDisabled(True)
|
self.tdr_velocity_input.setDisabled(True)
|
||||||
self.tdr_velocity_input.setText(str(self.tdr_velocity_dropdown.currentData()))
|
self.tdr_velocity_input.setText(
|
||||||
|
str(self.tdr_velocity_dropdown.currentData()))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
v = float(self.tdr_velocity_input.text())
|
v = float(self.tdr_velocity_input.text())
|
||||||
|
@ -134,10 +150,7 @@ class TDRWindow(QtWidgets.QWidget):
|
||||||
logger.info("Cannot compute cable length at 0 span")
|
logger.info("Cannot compute cable length at 0 span")
|
||||||
return
|
return
|
||||||
|
|
||||||
s11 = []
|
s11 = [np.complex(d.re, d.im) for d in self.app.data.s11]
|
||||||
for d in self.app.data.s11:
|
|
||||||
s11.append(np.complex(d.re, d.im))
|
|
||||||
|
|
||||||
window = np.blackman(len(self.app.data.s11))
|
window = np.blackman(len(self.app.data.s11))
|
||||||
|
|
||||||
windowed_s11 = window * s11
|
windowed_s11 = window * s11
|
||||||
|
@ -145,18 +158,19 @@ class TDRWindow(QtWidgets.QWidget):
|
||||||
step = np.ones(FFT_POINTS)
|
step = np.ones(FFT_POINTS)
|
||||||
self.step_response = signal.convolve(self.td, step)
|
self.step_response = signal.convolve(self.td, step)
|
||||||
|
|
||||||
self.step_response_Z = 50 * (1 + self.step_response) / (1 - self.step_response)
|
self.step_response_Z = 50 * (
|
||||||
|
1 + self.step_response) / (1 - self.step_response)
|
||||||
|
|
||||||
time_axis = np.linspace(0, 1/step_size, FFT_POINTS)
|
time_axis = np.linspace(0, 1 / step_size, FFT_POINTS)
|
||||||
self.distance_axis = time_axis * v * c
|
self.distance_axis = time_axis * v * c
|
||||||
# peak = np.max(td)
|
# peak = np.max(td)
|
||||||
# We should check that this is an actual *peak*, and not just a vague maximum
|
# We should check that this is an actual *peak*, and not just a vague maximum
|
||||||
index_peak = np.argmax(self.td)
|
index_peak = np.argmax(self.td)
|
||||||
|
|
||||||
cable_len = round(self.distance_axis[index_peak]/2, 3)
|
cable_len = round(self.distance_axis[index_peak] / 2, 3)
|
||||||
feet = math.floor(cable_len / 0.3048)
|
feet = math.floor(cable_len / 0.3048)
|
||||||
inches = round(((cable_len / 0.3048) - feet)*12, 1)
|
inches = round(((cable_len / 0.3048) - feet) * 12, 1)
|
||||||
|
|
||||||
self.tdr_result_label.setText(f"{cable_len}m ({feet}ft {inches}in)")
|
self.tdr_result_label.setText(f"{cable_len}m ({feet}ft {inches}in)")
|
||||||
self.app.tdr_result_label.setText(str(cable_len) + " m")
|
self.app.tdr_result_label.setText(f"{cable_len}m")
|
||||||
self.updated.emit()
|
self.updated.emit()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
pyserial==3.5
|
pyserial==3.5
|
||||||
PyQt5==5.15.7
|
PyQt5==5.15.7
|
||||||
numpy==1.23.0
|
numpy==1.23.2
|
||||||
scipy==1.8.1
|
scipy==1.9.1
|
||||||
Cython==0.29.30
|
Cython==0.29.32
|
||||||
|
|
Ładowanie…
Reference in New Issue