V2 300 point scan

features now of type set
pull/185/head
Holger Müller 2020-06-10 12:28:51 +02:00 zatwierdzone przez Holger Mueller
rodzic 6cfb08a251
commit 5c4c04e19e
4 zmienionych plików z 56 dodań i 31 usunięć

Wyświetl plik

@ -26,14 +26,11 @@ logger = logging.getLogger(__name__)
class AVNA(VNA):
name = "AVNA"
datapoints = 101
def __init__(self, app, serial_port):
super().__init__(app, serial_port)
self.version = Version(self.readVersion())
self.features = []
self.features.append("Customizable data points")
self.features.add("Customizable data points")
def isValid(self):
return True

Wyświetl plik

@ -30,7 +30,6 @@ logger = logging.getLogger(__name__)
class NanoVNA(VNA):
name = "NanoVNA"
datapoints = 101
screenwidth = 320
screenheight = 240
@ -38,20 +37,18 @@ class NanoVNA(VNA):
super().__init__(app, serial_port)
self.version = Version(self.readVersion())
self.features = []
logger.debug("Testing against 0.2.0")
if self.version.version_string.find("extended with scan") > 0:
logger.debug("Incompatible scan command detected.")
self.features.append("Incompatible scan command")
self.features.add("Incompatible scan command")
self.useScan = False
elif self.version >= Version("0.2.0"):
logger.debug("Newer than 0.2.0, using new scan command.")
self.features.append("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.append("Original sweep method")
self.features.add("Original sweep method")
self.useScan = False
self.features.extend(self.readFeatures())

Wyświetl plik

@ -16,6 +16,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import logging
import platform
from struct import pack
from typing import List
from NanoVNASaver.Hardware.VNA import VNA, Version
@ -25,6 +26,30 @@ if platform.system() != 'Windows':
logger = logging.getLogger(__name__)
_CMD_NOP = 0x00
_CMD_INDICATE = 0x0d
_CMD_READ = 0x10
_CMD_READ2 = 0x11
_CMD_READ4 = 0x12
_CMD_READFIFO = 0x18
_CMD_WRITE = 0x20
_CMD_WRITE2 = 0x21
_CMD_WRITE4 = 0x22
_CMD_WRITE8 = 0x23
_CMD_WRITEFIFO = 0x28
_ADDR_SWEEP_START = 0x00
_ADDR_SWEEP_STEP = 0x10
_ADDR_SWEEP_POINTS = 0x20
_ADDR_SWEEP_VALS_PER_FREQ = 0x22
_ADDR_RAW_SAMPLES_MODE = 0x26
_ADDR_VALUES_FIFO = 0x30
_ADDR_DEVICE_VARIANT = 0xf0
_ADDR_PROTOCOL_VERSION = 0xf1
_ADDR_HARDWARE_REVISION = 0xf2
_ADDR_FW_MAJOR = 0xf3
_ADDR_FW_MINOR = 0xf4
def _unpackSigned32(b):
return int.from_bytes(b[0:4], 'little', signed=True)
@ -34,7 +59,7 @@ def _unpackUnsigned16(b):
class NanoVNAV2(VNA):
name = "NanoVNA-V2"
datapoints = 255
DEFAULT_DATAPOINTS = 300
screenwidth = 320
screenheight = 240
@ -43,13 +68,17 @@ class NanoVNAV2(VNA):
if platform.system() != 'Windows':
tty.setraw(self.serial.fd)
self.serial.timeout = 6 # for this much data we need a longer timeout
# reset protocol to known state
self.serial.write([0, 0, 0, 0, 0, 0, 0, 0])
self.serial.write(pack("<Q", 0))
self.version = self.readVersion()
self.firmware = self.readFirmware()
self.features.add("Customizable data points")
# TODO: more than one dp per freq
self.features.add("Multi data points")
self.datapoints = NanoVNAV2.DEFAULT_DATAPOINTS
# firmware major version of 0xff indicates dfu mode
if self.firmware.major == 0xff:
@ -62,7 +91,6 @@ class NanoVNAV2(VNA):
self.sweepData = [(0, 0)] * self.datapoints
self._updateSweep()
def isValid(self):
if self.isDFU():
return False
@ -77,7 +105,7 @@ class NanoVNAV2(VNA):
def readFirmware(self) -> str:
# read register 0xf3 and 0xf4 (firmware major and minor version)
cmd = b"\x10\xf3\x10\xf4"
cmd = pack("<BBBB", _CMD_READ, _ADDR_FW_MAJOR, _CMD_READ, _ADDR_FW_MINOR)
self.serial.write(cmd)
resp = self.serial.read(2)
@ -95,23 +123,24 @@ class NanoVNAV2(VNA):
def readValues(self, value) -> List[str]:
self.checkValid()
self.serial.timeout = round(self.datapoints / 40)
# Actually grab the data only when requesting channel 0.
# The hardware will return all channels which we will store.
if value == "data 0":
# reset protocol to known state
self.serial.write([0, 0, 0, 0, 0, 0, 0, 0])
self.serial.write(pack("<Q", 0))
# cmd: write register 0x30 to clear FIFO
self.serial.write([0x20, 0x30, 0x00])
self.serial.write(pack("<BBB", _CMD_WRITE, _ADDR_VALUES_FIFO, 0))
pointstodo = self.datapoints
while pointstodo > 0 :
while pointstodo > 0:
logger.info("reading values")
pointstoread = min(255, pointstodo)
# cmd: read FIFO, addr 0x30
self.serial.write([0x18, 0x30, pointstoread])
self.serial.write(pack("<BBB", _CMD_READFIFO, _ADDR_VALUES_FIFO, pointstoread))
# each value is 32 bytes
nBytes = pointstoread * 32
@ -178,8 +207,8 @@ class NanoVNAV2(VNA):
def _updateSweep(self):
self.checkValid()
cmd = b"\x23\x00" + int.to_bytes(int(self.sweepStartHz), 8, 'little')
cmd += b"\x23\x10" + int.to_bytes(int(self.sweepStepHz), 8, 'little')
cmd += b"\x21\x20" + int.to_bytes(int(self.datapoints), 2, 'little')
cmd += b"\x21\x22" + int.to_bytes(1, 2, 'little') # number of samples
cmd = pack("<BBQ", _CMD_WRITE8, _ADDR_SWEEP_START, int(self.sweepStartHz))
cmd += pack("<BBQ", _CMD_WRITE8, _ADDR_SWEEP_STEP, int(self.sweepStepHz))
cmd += pack("<BBH", _CMD_WRITE2, _ADDR_SWEEP_POINTS, self.datapoints)
cmd += pack("<BBH", _CMD_WRITE2, _ADDR_SWEEP_VALS_PER_FREQ, 1)
self.serial.write(cmd)

Wyświetl plik

@ -27,26 +27,25 @@ logger = logging.getLogger(__name__)
class VNA:
name = "VNA"
validateInput = True
features = []
datapoints = 101
def __init__(self, app: QtWidgets.QWidget, serial_port: serial.Serial):
self.app = app
self.serial = serial_port
self.version: Version = Version("0.0.0")
self.features = set()
self.validateInput = True
self.datapoints = 101
def readFeatures(self) -> List[str]:
features = []
raw_help = self.readFromCommand("help")
logger.debug("Help command output:")
logger.debug(raw_help)
# Detect features from the help command
if "capture" in raw_help:
features.append("Screenshots")
self.features.add("Screenshots")
return features
return self.features
def readFrequencies(self) -> List[str]:
pass
@ -177,7 +176,10 @@ class VNA:
class InvalidVNA(VNA):
name = "Invalid"
datapoints = 0
def __init__(self, app: QtWidgets.QWidget, serial_port: serial.Serial):
super().__init__(app, serial_port)
self.datapoints = 0
def setSweep(self, start, stop):
return