diff --git a/NanoVNASaver/Hardware/NanoVNA.py b/NanoVNASaver/Hardware/NanoVNA.py index cf46e83..f165af0 100644 --- a/NanoVNASaver/Hardware/NanoVNA.py +++ b/NanoVNASaver/Hardware/NanoVNA.py @@ -40,25 +40,24 @@ class NanoVNA(VNA): super().__init__(iface) version_string = self.readVersion() self.version = Version(version_string) + self.sweep_method = "sweep" + self.start = 27000000 + self.stop = 30000000 + self._sweepdata = [] - logger.debug("Testing against 0.2.0") - if version_string.find("extended with scan") > 0: - logger.debug("Incompatible scan command detected.") - self.features.add("Incompatible scan command") - self.useScan = False + if self.version >= Version("0.7.1"): + self.features.add("Scan mask command") + self.sweep_method = "scan_mask" elif self.version >= Version("0.2.0"): logger.debug("Newer than 0.2.0, using new scan command.") - self.features.add("New scan command") - self.useScan = True - else: - logger.debug("Older than 0.2.0, using old sweep command.") - self.features.add("Original sweep method") - self.useScan = False + self.features.add("Scan command") + self.sweep_method = "scan" self.readFeatures() def isValid(self): return True + def _capture_data(self) -> bytes: with self.serial.lock: drain_serial(self.serial) @@ -101,8 +100,49 @@ class NanoVNA(VNA): self.writeSerial("resume") def setSweep(self, start, stop): - if self.useScan: - self.writeSerial(f"scan {start} {stop} {self.datapoints}") - else: + self.start = start + self.stop = stop + if self.sweep_method == "sweep": self.writeSerial(f"sweep {start} {stop} {self.datapoints}") - sleep(1) + elif self.sweep_method == "scan": + self.writeSerial(f"scan {start} {stop} {self.datapoints}") + + def readFrequencies(self) -> List[int]: + if self.sweep_method != "scan_mask": + return super().readFrequencies() + step = (self.stop - self.start) / (self.datapoints - 1.0) + return [round(self.start + i * step) for i in range(self.datapoints)] + + def readValues(self, value) -> List[str]: + if self.sweep_method != "scan_mask": + return super().readValues(value) + logger.debug("readValue with scan mask (%s)", value) + # Actually grab the data only when requesting channel 0. + # The hardware will return all channels which we will store. + if value == "data 0": + self._sweepdata = [] + try: + with self.serial.lock: + drain_serial(self.serial) + self.serial.write( + (f"scan {self.start} {self.stop}" + f' {self.datapoints} 0b110\r' + ).encode("ascii")) + self.serial.readline() + sleep(0.6) + logger.info("reading values") + for line in self.serial.readlines(): + line = line.decode("ascii").strip() + if line.startswith("ch>"): + break + logger.debug("Line: %s", line) + data = line.split() + self._sweepdata.append(( + f"{data[0]} {data[1]}", + f"{data[2]} {data[3]}")) + except IOError as exc: + logger.error("Error readValues: %s", exc) + if value == "data 0": + return [x[0] for x in self._sweepdata] + if value == "data 1": + return [x[1] for x in self._sweepdata] diff --git a/NanoVNASaver/Hardware/NanoVNA_V2.py b/NanoVNASaver/Hardware/NanoVNA_V2.py index dc323d1..bbea8e5 100644 --- a/NanoVNASaver/Hardware/NanoVNA_V2.py +++ b/NanoVNASaver/Hardware/NanoVNA_V2.py @@ -77,7 +77,7 @@ class NanoVNAV2(VNA): self.features.add("Multi data points") # firmware major version of 0xff indicates dfu mode - if self.firmware.major == 0xff: + if self.firmware.data["major"] == 0xff: raise IOError('Device is in DFU mode') self.sweepStartHz = 200e6 diff --git a/NanoVNASaver/NanoVNASaver.py b/NanoVNASaver/NanoVNASaver.py index efcc776..c38c2f5 100644 --- a/NanoVNASaver/NanoVNASaver.py +++ b/NanoVNASaver/NanoVNASaver.py @@ -25,7 +25,6 @@ from time import sleep, strftime, localtime from typing import List from PyQt5 import QtWidgets, QtCore, QtGui -from serial import SerialException from .Windows import ( AboutWindow, AnalysisWindow, CalibrationWindow, @@ -617,14 +616,12 @@ class NanoVNASaver(QtWidgets.QWidget): if not self.interface.isOpen(): logger.error("Unable to open port %s", self.interface) return - - sleep(0.05) - + sleep(0.1) try: self.vna = get_VNA(self.interface) except IOError as exc: logger.error("Unable to connect to VNA: %s", exc) - + self.vna.validateInput = self.settings.value("SerialInputValidation", True, bool) self.worker.setVNA(self.vna)