diff --git a/.github/workflows/release_linux.yml b/.github/workflows/release_linux.yml index 91f4d49..b5b1d46 100644 --- a/.github/workflows/release_linux.yml +++ b/.github/workflows/release_linux.yml @@ -23,9 +23,9 @@ jobs: run: | python3.9 -m venv build . 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 PyInstaller==5.1 + pip install PyInstaller==5.3 - name: Build binary run: | . build/bin/activate diff --git a/.github/workflows/release_macos.yml b/.github/workflows/release_macos.yml index ba11d4f..4cefcd9 100644 --- a/.github/workflows/release_macos.yml +++ b/.github/workflows/release_macos.yml @@ -18,9 +18,9 @@ jobs: python-version: 3.9 - name: Install dependencies and pyinstall 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 PyInstaller=5.1 + pip install PyInstaller=5.3 - name: Build binary run: | pyinstaller --onefile -n nanovna-saver nanovna-saver.py diff --git a/.github/workflows/release_win.yml b/.github/workflows/release_win.yml index 8dcfacb..cd87834 100644 --- a/.github/workflows/release_win.yml +++ b/.github/workflows/release_win.yml @@ -22,9 +22,9 @@ jobs: architecture: ${{ matrix.arch }} - name: Install dependencies and pyinstall 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 PyInstaller==5.1 + pip install PyInstaller==5.3 - name: Build binary run: | pyinstaller --onefile -n nanovna-saver.exe nanovna-saver.py diff --git a/NanoVNASaver/Charts/TDR.py b/NanoVNASaver/Charts/TDR.py index 16d80bb..3e2fd22 100644 --- a/NanoVNASaver/Charts/TDR.py +++ b/NanoVNASaver/Charts/TDR.py @@ -109,11 +109,13 @@ class TDRChart(Chart): self.y_action_set_fixed_maximum = QtWidgets.QAction( 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( 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_minimum) @@ -143,7 +145,7 @@ class TDRChart(Chart): def isPlotable(self, x, y): 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): self.fixedSpan = False @@ -256,10 +258,12 @@ class TDRChart(Chart): return a0.accept() width = self.width() - self.leftMargin - self.rightMargin - if len(self.tdrWindow.td) > 0: + if self.tdrWindow.td.size: if self.fixedSpan: - max_index = np.searchsorted(self.tdrWindow.distance_axis, self.maxDisplayLength * 2) - min_index = np.searchsorted(self.tdrWindow.distance_axis, self.minDisplayLength * 2) + max_index = np.searchsorted( + 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 else: 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) self.drawTitle(qp) - if self.tdrWindow.td: + if self.tdrWindow.td.size: if self.fixedSpan: max_length = max(0.1, self.maxDisplayLength) - max_index = np.searchsorted(self.tdrWindow.distance_axis, max_length * 2) - min_index = np.searchsorted(self.tdrWindow.distance_axis, self.minDisplayLength * 2) + max_index = np.searchsorted( + 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 < len(self.tdrWindow.distance_axis) - 1: max_index += 1 @@ -343,7 +349,7 @@ class TDRChart(Chart): 1)) + "m") y_ticks = math.floor(height / 60) - y_tick_step = height/y_ticks + y_tick_step = height / y_ticks for i in range(y_ticks): y = self.bottomMargin + int(i * y_tick_step) @@ -353,7 +359,8 @@ class TDRChart(Chart): qp.setPen(Chart.color.text) 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.setWidth(self.dim.point) @@ -363,15 +370,17 @@ class TDRChart(Chart): continue 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): pen.setColor(Chart.color.sweep) qp.setPen(pen) qp.drawPoint(x, y) x = self.leftMargin + int((i - min_index) / x_step) - y = (self.topMargin + height) -\ - int((self.tdrWindow.step_response_Z[i]-min_impedance) / y_impedance_step) + y = (self.topMargin + height) - int( + (self.tdrWindow.step_response_Z[i] - min_impedance) / + y_impedance_step) if self.isPlotable(x, y): pen.setColor(Chart.color.sweep_secondary) qp.setPen(pen) @@ -403,7 +412,8 @@ class TDRChart(Chart): 2)) + "m") 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.drawRect( QtCore.QRect( @@ -415,7 +425,7 @@ class TDRChart(Chart): qp.end() def valueAtPosition(self, y): - if len(self.tdrWindow.td) > 0: + if self.tdrWindow.td.size: height = self.height() - self.topMargin - self.bottomMargin absy = (self.height() - y) - self.bottomMargin if self.fixedValues: @@ -433,27 +443,24 @@ class TDRChart(Chart): return 0 def lengthAtPosition(self, x, limit=True): - if not self.tdrWindow.td: + if not self.tdrWindow.td.size: return 0 width = self.width() - self.leftMargin - self.rightMargin absx = x - self.leftMargin - if self.fixedSpan: - max_length = self.maxDisplayLength - min_length = self.minDisplayLength - x_step = (max_length - min_length) / width - else: - min_length = 0 - max_length = self.tdrWindow.distance_axis[ - math.ceil(len(self.tdrWindow.distance_axis) / 2)] / 2 - x_step = max_length / width + min_length = self.minDisplayLength if self.fixedSpan else 0 + max_length = self.maxDisplayLength if self.fixedSpan else ( + self.tdrWindow.distance_axis[ + math.ceil(len(self.tdrWindow.distance_axis) / 2) + ] / 2) + + x_step = (max_length - min_length) / width if limit and absx < 0: return min_length - if limit and absx > width: - return max_length - return absx * x_step + min_length + return max_length if limit and absx > width else absx * x_step + min_length 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) val2 = self.valueAtPosition(y2) diff --git a/NanoVNASaver/Hardware/NanoVNA_V2.py b/NanoVNASaver/Hardware/NanoVNA_V2.py index d067564..c08eb36 100644 --- a/NanoVNASaver/Hardware/NanoVNA_V2.py +++ b/NanoVNASaver/Hardware/NanoVNA_V2.py @@ -128,13 +128,30 @@ class NanoVNA_V2(VNA): def readFrequencies(self) -> List[int]: return [ 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( + " List[str]: # Actually grab the data only when requesting channel 0. # The hardware will return all channels which we will store. 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 timeout = self.serial.timeout with self.serial.lock: @@ -146,7 +163,7 @@ class NanoVNA_V2(VNA): sleep(WRITE_SLEEP) # clear sweepdata self._sweepdata = [(complex(), complex())] * ( - self.datapoints + s21hack) + self.datapoints + s21hack) pointstodo = self.datapoints + s21hack # 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 @@ -175,18 +192,7 @@ class NanoVNA_V2(VNA): if nBytes != len(arr): return [] - freq_index = -1 - for i in range(pointstoread): - (fwd_real, fwd_imag, rev0_real, rev0_imag, rev1_real, - rev1_imag, freq_index) = unpack_from( - " 'Version': - cmd = pack(" 'Version': + result = self._read_version(_ADDR_FW_MAJOR, + _ADDR_FW_MINOR) logger.debug("readVersion: %s", result) return result def read_board_revision(self) -> 'Version': - cmd = pack("