This commit is contained in:
jupfi 2023-08-16 13:11:22 +02:00
commit 224417687b
4 changed files with 64 additions and 72 deletions

View file

@ -3,7 +3,7 @@ import numpy as np
import json
from serial.tools.list_ports import comports
from PyQt6 import QtSerialPort
from PyQt5.QtCore import QThread, pyqtSignal, pyqtSlot
from PyQt6.QtCore import QThread, pyqtSignal, pyqtSlot
from nqrduck.module.module_controller import ModuleController
from .model import S11Data
@ -51,6 +51,8 @@ class AutoTMController(ModuleController):
MAX_FREQUENCY = 300e6 # Hz
try:
start_frequence = start_frequency.replace(",", ".")
stop_frequency = stop_frequency.replace(",", ".")
start_frequency = float(start_frequency) * 1e6
stop_frequency = float(stop_frequency) * 1e6
except ValueError:
@ -286,6 +288,8 @@ class AutoTMController(ModuleController):
logger.debug("Setting voltages")
MAX_VOLTAGE = 5 # V
try:
tuning_voltage = tuning_voltage.replace(",", ".")
matching_voltage = matching_voltage.replace(",", ".")
tuning_voltage = float(tuning_voltage)
matching_voltage = float(matching_voltage)
except ValueError:

View file

@ -26,7 +26,6 @@
<widget class="QLabel" name="titleconnectionLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
@ -81,7 +80,6 @@
<widget class="QLabel" name="titletypeLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
@ -93,13 +91,13 @@
<item>
<widget class="QTabWidget" name="typeTab">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="mechTab">
<attribute name="title">
<string>Mechanical</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="verticalLayout" stretch="0">
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
@ -113,7 +111,7 @@
<attribute name="title">
<string>Electrical</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<layout class="QGridLayout" name="gridLayout_3" rowstretch="0,0,0,1">
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="matchingBox"/>
</item>
@ -159,7 +157,6 @@
<widget class="QLabel" name="titlefrequencyLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
@ -231,7 +228,6 @@
<widget class="QLabel" name="titleinfoLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
@ -250,8 +246,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>273</width>
<height>83</height>
<width>297</width>
<height>169</height>
</rect>
</property>
</widget>

View file

@ -1,18 +1,17 @@
import logging
from datetime import datetime
from pathlib import Path
import smithplot
from smithplot import SmithAxes
from PyQt6.QtGui import QMovie
from PyQt6.QtSerialPort import QSerialPort
from PyQt6.QtWidgets import QWidget, QLabel, QVBoxLayout, QApplication, QHBoxLayout, QLineEdit, QPushButton, QDialog, QFileDialog
from PyQt6.QtCore import pyqtSlot, Qt
from nqrduck.module.module_view import ModuleView
from nqrduck.contrib.mplwidget import MplWidget
from nqrduck.contrib.mplwidget import MplWidget
from .widget import Ui_Form
logger = logging.getLogger(__name__)
class AutoTMView(ModuleView):
def __init__(self, module):
@ -27,16 +26,19 @@ class AutoTMView(ModuleView):
self._ui_form.connectButton.setDisabled(True)
# On clicking of the refresh button scan for available usb devices
self._ui_form.refreshButton.clicked.connect(self.module.controller.find_devices)
self._ui_form.refreshButton.clicked.connect(
self.module.controller.find_devices)
# Connect the available devices changed signal to the on_available_devices_changed slot
self.module.model.available_devices_changed.connect(self.on_available_devices_changed)
self.module.model.available_devices_changed.connect(
self.on_available_devices_changed)
# Connect the serial changed signal to the on_serial_changed slot
self.module.model.serial_changed.connect(self.on_serial_changed)
# On clicking of the connect button call the connect method
self._ui_form.connectButton.clicked.connect(self.on_connect_button_clicked)
self._ui_form.connectButton.clicked.connect(
self.on_connect_button_clicked)
# On clicking of the start button call the start_frequency_sweep method
self._ui_form.startButton.clicked.connect(lambda: self.module.controller.start_frequency_sweep(
@ -51,15 +53,16 @@ class AutoTMView(ModuleView):
))
# On clicking of the calibration button call the on_calibration_button_clicked method
self._ui_form.calibrationButton.clicked.connect(self.on_calibration_button_clicked)
self._ui_form.calibrationButton.clicked.connect(
self.on_calibration_button_clicked)
# Connect the measurement finished signal to the plot_measurement slot
self.module.model.measurement_finished.connect(self.plot_measurement)
# Add a vertical layout to the info box
self._ui_form.scrollAreaWidgetContents.setLayout(QVBoxLayout())
self._ui_form.scrollAreaWidgetContents.layout().setAlignment(Qt.AlignmentFlag.AlignTop)
self._ui_form.scrollAreaWidgetContents.layout(
).setAlignment(Qt.AlignmentFlag.AlignTop)
self.init_plot()
self.init_labels()
@ -92,7 +95,7 @@ class AutoTMView(ModuleView):
self.calibration_window.show()
@pyqtSlot(list)
def on_available_devices_changed(self, available_devices : list) -> None:
def on_available_devices_changed(self, available_devices: list) -> None:
"""Update the available devices list in the view. """
logger.debug("Updating available devices list")
self._ui_form.portBox.clear()
@ -114,22 +117,22 @@ class AutoTMView(ModuleView):
self.module.controller.connect(selected_device)
@pyqtSlot(QSerialPort)
def on_serial_changed(self, serial : QSerialPort) -> None:
def on_serial_changed(self, serial: QSerialPort) -> None:
"""Update the serial 'connectionLabel' according to the current serial connection.
Args:
serial (serial.Serial): The current serial connection."""
logger.debug("Updating serial connection label")
if serial.isOpen():
if serial:
self._ui_form.connectionLabel.setText(serial.portName())
self.add_info_text("Connected to device %s" % serial.portName())
else:
self._ui_form.connectionLabel.setText("Disconnected")
logger.debug("Updated serial connection label")
def plot_measurement(self, data : "S11Data") -> None:
def plot_measurement(self, data: "S11Data") -> None:
"""Update the S11 plot with the current data points.
Args:
data_points (list): List of data points to plot.
@ -151,10 +154,10 @@ class AutoTMView(ModuleView):
ax.set_ylabel("Imaginary")
plt.show()
"""
self._ui_form.S11Plot.canvas.ax.clear()
magnitude_ax = self._ui_form.S11Plot.canvas.ax
magnitude_ax.clear()
phase_ax = self._ui_form.S11Plot.canvas.ax.twinx()
phase_ax.clear()
@ -168,7 +171,8 @@ class AutoTMView(ModuleView):
E_t = calibration[2]
# gamma_corr = [(data_point - e_00[i]) / (data_point * e11[i] - delta_e[i]) for i, data_point in enumerate(gamma)]
gamma_corr = [(data_point - E_D[i]) / (E_S[i] * (data_point - E_D[i]) + E_t[i]) for i, data_point in enumerate(gamma)]
gamma_corr = [(data_point - E_D[i]) / (E_S[i] * (data_point - E_D[i]) + E_t[i])
for i, data_point in enumerate(gamma)]
""" fig, ax = plt.subplots()
ax.plot([g.real for g in gamma_corr], [g.imag for g in gamma_corr])
ax.set_aspect('equal')
@ -177,23 +181,10 @@ class AutoTMView(ModuleView):
ax.set_xlabel("Real")
ax.set_ylabel("Imaginary")
plt.show() """
return_loss_db_corr = [-20 * cmath.log10(abs(g + 1e-12)) for g in gamma_corr]
return_loss_db_corr = [-20 *
cmath.log10(abs(g + 1e-12)) for g in gamma_corr]
magnitude_ax.plot(frequency, return_loss_db_corr, color="red")
""" open_calibration = self.module.model.open_calibration
short_calibration = self.module.model.short_calibration
load_calibration = self.module.model.load_calibration
phase_difference = short_calibration.phase_deg - open_calibration.phase_deg
phase = (phase - open_calibration.phase_deg) / phase_difference
amplitude_difference = open_calibration.return_loss_db - load_calibration.return_loss_db
amplitude = (return_loss_db - open_calibration.return_loss_db) / amplitude_difference
magnitude_ax.plot(frequency, amplitude, color="green")
phase_ax.plot(frequency, phase, color="orange", linestyle="--") """
phase_ax.set_ylabel("|Phase (deg)|")
phase_ax.plot(frequency, phase, color="orange", linestyle="--")
phase_ax.set_ylim(-180, 180)
@ -212,9 +203,9 @@ class AutoTMView(ModuleView):
# Wait for the signals to be processed before adding the info text
QApplication.processEvents()
def add_info_text(self, text : str) -> None:
def add_info_text(self, text: str) -> None:
""" Adds text to the info text box.
Args:
text (str): Text to add to the info text box.
"""
@ -224,11 +215,12 @@ class AutoTMView(ModuleView):
text_label = QLabel(text)
text_label.setStyleSheet("font-size: 25px;")
self._ui_form.scrollAreaWidgetContents.layout().addWidget(text_label)
self._ui_form.scrollArea.verticalScrollBar().setValue(self._ui_form.scrollArea.verticalScrollBar().maximum())
self._ui_form.scrollArea.verticalScrollBar().setValue(
self._ui_form.scrollArea.verticalScrollBar().maximum())
def add_error_text(self, text : str) -> None:
def add_error_text(self, text: str) -> None:
""" Adds text to the error text box.
Args:
text (str): Text to add to the error text box.
"""
@ -238,7 +230,8 @@ class AutoTMView(ModuleView):
text_label = QLabel(text)
text_label.setStyleSheet("font-size: 25px; color: red;")
self._ui_form.scrollAreaWidgetContents.layout().addWidget(text_label)
self._ui_form.scrollArea.verticalScrollBar().setValue(self._ui_form.scrollArea.verticalScrollBar().maximum())
self._ui_form.scrollArea.verticalScrollBar().setValue(
self._ui_form.scrollArea.verticalScrollBar().maximum())
def create_frequency_sweep_spinner_dialog(self) -> None:
"""Creates a frequency sweep spinner dialog. """
@ -265,7 +258,6 @@ class AutoTMView(ModuleView):
self.spinner_movie.start()
class CalibrationWindow(QWidget):
def __init__(self, module, parent=None):
@ -290,7 +282,7 @@ class AutoTMView(ModuleView):
frequency_layout.addWidget(stop_edit)
unit_label = QLabel("MHz")
frequency_layout.addWidget(unit_label)
# Add horizontal layout for the calibration type
type_layout = QHBoxLayout()
main_layout.addLayout(type_layout)
@ -350,24 +342,30 @@ class AutoTMView(ModuleView):
data_layout.addWidget(apply_button)
main_layout.addLayout(data_layout)
self.setLayout(main_layout)
# Connect the calibration finished signals to the on_calibration_finished slot
self.module.model.short_calibration_finished.connect(self.on_short_calibration_finished)
self.module.model.open_calibration_finished.connect(self.on_open_calibration_finished)
self.module.model.load_calibration_finished.connect(self.on_load_calibration_finished)
self.module.model.short_calibration_finished.connect(
self.on_short_calibration_finished)
self.module.model.open_calibration_finished.connect(
self.on_open_calibration_finished)
self.module.model.load_calibration_finished.connect(
self.on_load_calibration_finished)
def on_short_calibration_finished(self, short_calibration : "S11Data") -> None:
self.on_calibration_finished("short", self.short_plot, short_calibration)
def on_short_calibration_finished(self, short_calibration: "S11Data") -> None:
self.on_calibration_finished(
"short", self.short_plot, short_calibration)
def on_open_calibration_finished(self, open_calibration : "S11Data") -> None:
self.on_calibration_finished("open", self.open_plot, open_calibration)
def on_open_calibration_finished(self, open_calibration: "S11Data") -> None:
self.on_calibration_finished(
"open", self.open_plot, open_calibration)
def on_load_calibration_finished(self, load_calibration : "S11Data") -> None:
self.on_calibration_finished("load", self.load_plot, load_calibration)
def on_load_calibration_finished(self, load_calibration: "S11Data") -> None:
self.on_calibration_finished(
"load", self.load_plot, load_calibration)
def on_calibration_finished(self, type : str, widget: MplWidget, data :"S11Data") -> None:
def on_calibration_finished(self, type: str, widget: MplWidget, data: "S11Data") -> None:
"""This method is called when a calibration has finished.
It plots the calibration data on the given widget.
"""
@ -420,6 +418,3 @@ class AutoTMView(ModuleView):
self.module.controller.calculate_calibration()
# Close the calibration window
self.close()

View file

@ -1,6 +1,6 @@
# Form implementation generated from reading ui file '../Modules/nqrduck-autotm/src/nqrduck_autotm/resources/autotm_widget.ui'
#
# Created by: PyQt6 UI code generator 6.5.1
# Created by: PyQt6 UI code generator 6.4.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
@ -25,7 +25,6 @@ class Ui_Form(object):
self.titleconnectionLabel = QtWidgets.QLabel(parent=Form)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.titleconnectionLabel.setFont(font)
self.titleconnectionLabel.setObjectName("titleconnectionLabel")
self.verticalLayout_2.addWidget(self.titleconnectionLabel)
@ -54,7 +53,6 @@ class Ui_Form(object):
self.titletypeLabel = QtWidgets.QLabel(parent=Form)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.titletypeLabel.setFont(font)
self.titletypeLabel.setObjectName("titletypeLabel")
self.verticalLayout_2.addWidget(self.titletypeLabel)
@ -93,12 +91,12 @@ class Ui_Form(object):
self.resolutionBox = QtWidgets.QDoubleSpinBox(parent=self.elecTab)
self.resolutionBox.setObjectName("resolutionBox")
self.gridLayout_3.addWidget(self.resolutionBox, 3, 1, 1, 1)
self.gridLayout_3.setRowStretch(3, 1)
self.typeTab.addTab(self.elecTab, "")
self.verticalLayout_2.addWidget(self.typeTab)
self.titlefrequencyLabel = QtWidgets.QLabel(parent=Form)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.titlefrequencyLabel.setFont(font)
self.titlefrequencyLabel.setObjectName("titlefrequencyLabel")
self.verticalLayout_2.addWidget(self.titlefrequencyLabel)
@ -135,7 +133,6 @@ class Ui_Form(object):
self.titleinfoLabel = QtWidgets.QLabel(parent=Form)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.titleinfoLabel.setFont(font)
self.titleinfoLabel.setObjectName("titleinfoLabel")
self.verticalLayout_2.addWidget(self.titleinfoLabel)
@ -143,7 +140,7 @@ class Ui_Form(object):
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 273, 83))
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 297, 169))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.verticalLayout_2.addWidget(self.scrollArea)
@ -162,7 +159,7 @@ class Ui_Form(object):
self.horizontalLayout_2.setStretch(1, 1)
self.retranslateUi(Form)
self.typeTab.setCurrentIndex(1)
self.typeTab.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):