Copyright notice on program startup.

LogMagChart now has frequency ticks and text.
File picker button using system file save dialog.
Reading data and frequencies is standardized, including basic error handling.
Removed a number of debugging statements.

Version 0.0.1
pull/1/head
Rune B. Broberg 2019-08-30 09:43:18 +02:00
rodzic 1a662bfe77
commit 8f2b33e9aa
5 zmienionych plików z 112 dodań i 84 usunięć

Wyświetl plik

@ -108,6 +108,20 @@ class LogMagChart(QtWidgets.QWidget):
qp.setPen(QtCore.Qt.black)
qp.drawText(3, 35, str(-min))
qp.drawText(3, self.chartHeight+20, str(-max))
# Draw frequency markers
fstart = self.data[0].freq
fstop = self.data[len(self.data)-1].freq
fspan = fstop-fstart
# At least 100 px between ticks
qp.drawText(self.leftMargin-20, 20 + self.chartHeight + 15, LogMagChart.shortenFrequency(fstart))
ticks = math.floor(self.chartWidth/100) # Number of ticks does not include the origin
for i in range(ticks):
x = self.leftMargin + round((i+1)*self.chartWidth/ticks)
qp.setPen(QtGui.QPen(QtGui.QColor("lightgray")))
qp.drawLine(x, 20, x, 20+self.chartHeight+5)
qp.setPen(QtCore.Qt.black)
qp.drawText(x-20, 20+self.chartHeight+15, LogMagChart.shortenFrequency(round(fspan/ticks*(i+1) + fstart)))
qp.setPen(pen)
for i in range(len(self.data)):
re = self.data[i].re
@ -138,15 +152,21 @@ class LogMagChart(QtWidgets.QWidget):
qp.drawPoint(int(x), int(y))
def setValues(self, values, frequencies):
print("### Updating values ###")
self.values = values
self.frequencies = frequencies
self.update()
def setData(self, data):
print("### Updating data ###")
self.data = data
self.update()
def setMarkers(self, markers):
self.markers = markers
self.markers = markers
@staticmethod
def shortenFrequency(frequency):
if frequency < 50000:
return frequency
if frequency < 5000000:
return str(round(frequency / 1000)) + "k"
return str(round(frequency / 1000000, 1)) + "M"

Wyświetl plik

@ -168,11 +168,17 @@ class NanoVNASaver(QtWidgets.QWidget):
file_control_layout = QtWidgets.QFormLayout(file_control_box)
self.fileNameInput = QtWidgets.QLineEdit("")
self.fileNameInput.setAlignment(QtCore.Qt.AlignRight)
btnFilePicker = QtWidgets.QPushButton("...")
btnFilePicker.setMaximumWidth(25)
btnFilePicker.clicked.connect(self.pickFile)
fileNameLayout = QtWidgets.QHBoxLayout()
fileNameLayout.addWidget(self.fileNameInput)
fileNameLayout.addWidget(btnFilePicker)
file_control_layout.addRow(QtWidgets.QLabel("Filename"), self.fileNameInput)
file_control_layout.addRow(QtWidgets.QLabel("Filename"), fileNameLayout)
self.btnExportFile = QtWidgets.QPushButton("Export data")
self.btnExportFile.clicked.connect(self.exportFile)
self.btnExportFile = QtWidgets.QPushButton("Export data S1P")
self.btnExportFile.clicked.connect(self.exportFileS11)
file_control_layout.addRow(self.btnExportFile)
left_column.addWidget(file_control_box)
@ -200,19 +206,37 @@ class NanoVNASaver(QtWidgets.QWidget):
self.worker.signals.updated.connect(self.dataUpdated)
self.worker.signals.finished.connect(self.sweepFinished)
def exportFile(self):
def pickFile(self):
filename, _ = QtWidgets.QFileDialog.getSaveFileName(directory=self.fileNameInput.text(), filter="Touchstone Files (*.s1p *.s2p);;All files (*.*)")
self.fileNameInput.setText(filename)
def exportFileS11(self):
print("Save file to " + self.fileNameInput.text())
if (len(self.data) == 0):
self.lister.appendPlainText("No data stored, nothing written.")
return
filename = self.fileNameInput.text()
# TODO: Make some proper file handling here?
file = open(filename, "w+")
self.lister.clear()
self.lister.appendPlainText("# Hz S RI R 50")
file.write("# Hz S RI R 50\n")
for i in range(len(self.values)):
if i > 0 and self.frequencies[i] != self.frequencies[i-1]:
self.lister.appendPlainText(self.frequencies[i] + " " + self.values[i])
file.write(self.frequencies[i] + " " + self.values[i] + "\n")
file.close()
if filename == "":
self.lister.appendPlainText("No filename entered.")
return
try:
file = open(filename, "w+")
self.lister.clear()
self.lister.appendPlainText("# Hz S RI R 50")
file.write("# Hz S RI R 50\n")
for i in range(len(self.values)):
if i > 0 and self.frequencies[i] != self.frequencies[i-1]:
self.lister.appendPlainText(self.frequencies[i] + " " + self.values[i])
file.write(self.frequencies[i] + " " + self.values[i] + "\n")
file.close()
except Exception as e:
print("Error during file export: " + str(e))
self.lister.appendPlainText("Error during file export: " + str(e))
return
self.lister.appendPlainText("")
self.lister.appendPlainText("File " + filename + " written.")
def serialButtonClick(self):
if self.serial.is_open:
@ -266,7 +290,7 @@ class NanoVNASaver(QtWidgets.QWidget):
return
def setSweep(self, start, stop):
print("Sending: " + "sweep " + str(start) + " " + str(stop) + " 101")
# print("Sending: " + "sweep " + str(start) + " " + str(stop) + " 101")
self.writeSerial("sweep " + str(start) + " " + str(stop) + " 101")
def sweep(self):
@ -281,7 +305,6 @@ class NanoVNASaver(QtWidgets.QWidget):
def readValues(self, value):
if self.serialLock.acquire():
print("### Reading " + str(value) + " ###")
try:
data = "a"
while data != "":
@ -290,16 +313,14 @@ class NanoVNASaver(QtWidgets.QWidget):
# Then send the command to read data
self.serial.write(str(value + "\r").encode('ascii'))
except serial.SerialException as exc:
print("Exception received")
print("Exception received: " + str(exc))
result = ""
data = ""
sleep(0.01)
while "ch>" not in data:
data = self.serial.readline().decode('ascii')
result += data
print("### Done reading ###")
values = result.split("\r\n")
print("Total values: " + str(len(values) - 2))
self.serialLock.release()
return values[1:102]
@ -345,4 +366,5 @@ class NanoVNASaver(QtWidgets.QWidget):
def sweepFinished(self):
self.sweepProgressBar.setValue(100)
self.btnSweep.setDisabled(False)
self.btnSweep.setDisabled(False)

Wyświetl plik

@ -108,13 +108,11 @@ class SmithChart(QtWidgets.QWidget):
qp.drawPoint(int(x), int(y))
def setValues(self, values, frequencies):
print("### Updating values ###")
self.values = values
self.frequencies = frequencies
self.update()
def setData(self, data):
print("### Updating data ###")
self.data = data
self.update()
@ -122,5 +120,4 @@ class SmithChart(QtWidgets.QWidget):
self.markers = markers
def heightForWidth(self, a0: int) -> int:
print("Asked about height")
return a0

Wyświetl plik

@ -40,7 +40,6 @@ class SweepWorker(QtCore.QRunnable):
@pyqtSlot()
def run(self):
print("I am thread")
self.percentage = 0
if not self.app.serial.is_open:
return
@ -48,7 +47,6 @@ class SweepWorker(QtCore.QRunnable):
if int(self.app.sweepCountInput.text()) > 0:
self.noSweeps = int(self.app.sweepCountInput.text())
print("### Updating... ### ")
if not self.app.sweepStartInput.text().isnumeric() or not self.app.sweepEndInput.text().isnumeric():
# We should handle the first startup by reading frequencies?
sweepFrom = 1000000
@ -70,69 +68,22 @@ class SweepWorker(QtCore.QRunnable):
self.app.setSweep(sweepFrom + i*101*stepsize, sweepFrom+(100+i*101)*stepsize)
sleep(0.8)
# S11
tmpdata = []
done = False
while not done:
done = True
tmpdata = self.app.readValues("data 0")
for d in tmpdata:
a, b = d.split(" ")
try:
if float(a) < -1.5 or float(a) > 1.5:
print("Warning: Got a non-float data value: " + d + " (" + a + ")")
done = False
if float(b) < -1.5 or float(b) > 1.5:
print("Warning: Got a non-float data value: " + d + " (" + b + ")")
done = False
except Exception:
done = False
values += tmpdata
values += self.readData("data 0")
# S12
tmpdata = []
done = False
while not done:
done = True
tmpdata = self.app.readValues("data 1")
for d in tmpdata:
a, b = d.split(" ")
try:
if float(a) < -1.5 or float(a) > 1.5:
print("Warning: Got a non-float data value: " + d + " (" + a + ")")
done = False
if float(b) < -1.5 or float(b) > 1.5:
print("Warning: Got a non-float data value: " + d + " (" + b + ")")
done = False
except Exception:
done = False
values12 += self.readData("data 1")
values12 += tmpdata
# TODO: Figure out why frequencies sometimes arrive as non-numbers
tmpfreq = []
done = False
while not done:
done = True
tmpfreq = self.app.readValues("frequencies")
for f in tmpfreq:
if not f.isdigit():
print("Warning: Got a non-digit frequency: " + f)
done = False
frequencies += tmpfreq
frequencies += self.readFreq()
self.percentage = (i+1)*100/self.noSweeps
self.saveData(frequencies, values, values12)
# Reset the device to show the full range
self.app.setSweep(self.app.sweepStartInput.text(), self.app.sweepEndInput.text())
else:
print("### Reading values ###")
values = self.app.readValues("data 0")
values12 = self.app.readValues("data 1")
print("### Reading frequencies ###")
frequencies = self.app.readValues("frequencies")
print("Read data, saving")
self.app.setSweep(sweepFrom, sweepTo)
sleep(0.8)
values = self.readData("data 0")
values12 = self.readData("data 1")
frequencies = self.readFreq()
self.saveData(frequencies, values, values12)
self.percentage = 100
@ -153,5 +104,35 @@ class SweepWorker(QtCore.QRunnable):
data += [Datapoint(freq, re, im)]
data12 += [Datapoint(freq, re12, im12)]
self.app.saveData(data, data12)
print("Saved data, emitting signal")
self.signals.updated.emit()
def readData(self, data):
done = False
while not done:
done = True
tmpdata = self.app.readValues(data)
for d in tmpdata:
a, b = d.split(" ")
try:
if float(a) < -1.5 or float(a) > 1.5:
print("Warning: Got a non-float data value: " + d + " (" + a + ")")
done = False
if float(b) < -1.5 or float(b) > 1.5:
print("Warning: Got a non-float data value: " + d + " (" + b + ")")
done = False
except Exception:
done = False
return tmpdata
def readFreq(self):
# TODO: Figure out why frequencies sometimes arrive as non-integers
tmpfreq = []
done = False
while not done:
done = True
tmpfreq = self.app.readValues("frequencies")
for f in tmpfreq:
if not f.isdigit():
print("Warning: Got a non-digit frequency: " + f)
done = False
return tmpfreq

Wyświetl plik

@ -18,7 +18,15 @@ from PyQt5 import QtWidgets
from NanoVNASaver import NanoVNASaver
version = "0.0.1"
if __name__ == '__main__':
print("NanoVNASaver " + version)
print("Copyright (C) 2019 Rune B. Broberg")
print("This program comes with ABSOLUTELY NO WARRANTY")
print("This program is licensed under the GNU General Public License version 3")
print("")
print("See https://github.com/mihtjel/nanovna-saver for further details")
# Main code goes here
app = QtWidgets.QApplication([])
window = NanoVNASaver()