From 67b21d27b768891bf02e9d0978a78162085a02cb Mon Sep 17 00:00:00 2001 From: jupfi Date: Thu, 7 Dec 2023 20:13:34 +0100 Subject: [PATCH] Implemented stepper select and homing. --- src/nqrduck_autotm/controller.py | 30 +++++++++++- src/nqrduck_autotm/model.py | 20 ++++++++ src/nqrduck_autotm/resources/autotm_widget.ui | 48 ++++++++++++------- src/nqrduck_autotm/view.py | 30 ++++++++++++ src/nqrduck_autotm/widget.py | 36 ++++++++------ 5 files changed, 132 insertions(+), 32 deletions(-) diff --git a/src/nqrduck_autotm/controller.py b/src/nqrduck_autotm/controller.py index a65fd2f..555f7a1 100644 --- a/src/nqrduck_autotm/controller.py +++ b/src/nqrduck_autotm/controller.py @@ -98,7 +98,7 @@ class AutoTMController(ModuleController): MAX_FREQUENCY = 200e6 # Hz try: - start_frequence = start_frequency.replace(",", ".") + start_frequency = start_frequency.replace(",", ".") stop_frequency = stop_frequency.replace(",", ".") start_frequency = float(start_frequency) * 1e6 stop_frequency = float(stop_frequency) * 1e6 @@ -264,6 +264,16 @@ class AutoTMController(ModuleController): self.module.view.add_info_text("ATM Error: " + text[1:]) elif text.startswith("v"): self.process_voltage_sweep_result(text) + elif text.startswith("p"): + # Format is pm + text = text[1:].split("m") + tuning_position, matching_position = map(int, text) + self.module.model.tuning_stepper.position = tuning_position + self.module.model.matching_stepper.position = matching_position + self.module.model.tuning_stepper.homed = True + self.module.model.matching_stepper.homed = True + logger.debug("Tuning position: %s, Matching position: %s", tuning_position, matching_position) + self.module.view.on_active_stepper_changed() def on_short_calibration( @@ -609,3 +619,21 @@ class AutoTMController(ModuleController): """ logger.debug("Homing") self.send_command("h") + + @pyqtSlot(str) + def on_stepper_changed(self, stepper: str) -> None: + """This method is called when the stepper position is changed. + It sends the command to the atm system to change the stepper position. + + Args: + stepper (str): The stepper that is being changed. Either 'tuning' or 'matching'. + """ + logger.debug("Stepper %s changed", stepper) + stepper = stepper.lower() + if stepper == "tuning": + self.module.model.active_stepper = self.module.model.tuning_stepper + elif stepper == "matching": + self.module.model.active_stepper = self.module.model.matching_stepper + + + diff --git a/src/nqrduck_autotm/model.py b/src/nqrduck_autotm/model.py index 1e407ca..fdd356a 100644 --- a/src/nqrduck_autotm/model.py +++ b/src/nqrduck_autotm/model.py @@ -217,6 +217,12 @@ class LookupTable: # Round to closest integer return int(round((frequency - self.start_frequency) / self.frequency_step)) +class Stepper: + + def __init__(self) -> None: + self.homed = False + self.position = 0 + class ElectricalLookupTable(LookupTable): TYPE = "Electrical" @@ -260,6 +266,7 @@ class AutoTMModel(ModuleModel): available_devices_changed = pyqtSignal(list) serial_changed = pyqtSignal(QSerialPort) data_points_changed = pyqtSignal(list) + active_stepper_changed = pyqtSignal(Stepper) short_calibration_finished = pyqtSignal(S11Data) open_calibration_finished = pyqtSignal(S11Data) @@ -273,6 +280,10 @@ class AutoTMModel(ModuleModel): self.calibration = None self.serial = None + self.tuning_stepper = Stepper() + self.matching_stepper = Stepper() + self.active_stepper = self.tuning_stepper + @property def available_devices(self): return self._available_devices @@ -318,6 +329,15 @@ class AutoTMModel(ModuleModel): self._measurement = value self.measurement_finished.emit(value) + @property + def active_stepper(self): + return self._active_stepper + + @active_stepper.setter + def active_stepper(self, value): + self._active_stepper = value + self.active_stepper_changed.emit(value) + # Calibration properties @property diff --git a/src/nqrduck_autotm/resources/autotm_widget.ui b/src/nqrduck_autotm/resources/autotm_widget.ui index 1b46085..02852d3 100644 --- a/src/nqrduck_autotm/resources/autotm_widget.ui +++ b/src/nqrduck_autotm/resources/autotm_widget.ui @@ -152,7 +152,7 @@ - 1 + 0 @@ -160,8 +160,8 @@ - - + + Home @@ -181,6 +181,9 @@ + + + @@ -195,14 +198,14 @@ - + - - + + @@ -216,7 +219,14 @@ - + + + + Absolute: + + + + -1000 @@ -229,29 +239,33 @@ - + Step Size: - - - - Absolute: - - - - + Go - - + + + + Position: + + + + + + + 0 + + diff --git a/src/nqrduck_autotm/view.py b/src/nqrduck_autotm/view.py index fcd9124..dc5d9eb 100644 --- a/src/nqrduck_autotm/view.py +++ b/src/nqrduck_autotm/view.py @@ -39,6 +39,9 @@ class AutoTMView(ModuleView): # Disable the connectButton while no devices are selected self._ui_form.connectButton.setDisabled(True) + self._ui_form.decreaseButton.setEnabled(False) + self._ui_form.increaseButton.setEnabled(False) + self._ui_form.absoluteGoButton.setEnabled(False) # On clicking of the refresh button scan for available usb devices self._ui_form.refreshButton.clicked.connect(self.module.controller.find_devices) @@ -111,6 +114,12 @@ class AutoTMView(ModuleView): self._ui_form.startButton.setIcon(Logos.Play_16x16()) self._ui_form.startButton.setIconSize(self._ui_form.startButton.size()) + # Stepper selection + self._ui_form.stepperselectBox.currentIndexChanged.connect(lambda: self.module.controller.on_stepper_changed(self._ui_form.stepperselectBox.currentText())) + + # Active stepper changed + self.module.model.active_stepper_changed.connect(self.on_active_stepper_changed) + self.init_plot() self.init_labels() @@ -156,6 +165,10 @@ class AutoTMView(ModuleView): self._ui_form.connectButton.setEnabled(False) logger.debug("Updated available devices list") + def on_stepper_changed(): + """Update the stepper position label according to the current stepper position.""" + logger.debug("Updating stepper position label") + @pyqtSlot() def on_connect_button_clicked(self) -> None: """This method is called when the connect button is clicked. @@ -184,6 +197,23 @@ class AutoTMView(ModuleView): logger.debug("Updated serial connection label") + @pyqtSlot() + def on_active_stepper_changed(self) -> None: + """Update the stepper position label according to the current stepper position.""" + logger.debug("Updating stepper position label") + self._ui_form.stepperposLabel.setText(str(self.module.model.active_stepper.position)) + logger.debug("Updated stepper position label") + + # Only allow position change when stepper is homed + if self.module.model.active_stepper.homed: + self._ui_form.decreaseButton.setEnabled(True) + self._ui_form.increaseButton.setEnabled(True) + self._ui_form.absoluteGoButton.setEnabled(True) + else: + self._ui_form.decreaseButton.setEnabled(False) + self._ui_form.increaseButton.setEnabled(False) + self._ui_form.absoluteGoButton.setEnabled(False) + def plot_measurement(self, data: "S11Data") -> None: """Update the S11 plot with the current data points. diff --git a/src/nqrduck_autotm/widget.py b/src/nqrduck_autotm/widget.py index 5f4e4ae..5f3cbe6 100644 --- a/src/nqrduck_autotm/widget.py +++ b/src/nqrduck_autotm/widget.py @@ -99,7 +99,7 @@ class Ui_Form(object): self.gridLayout_4.setObjectName("gridLayout_4") self.homeButton = QtWidgets.QPushButton(parent=self.mechTab) self.homeButton.setObjectName("homeButton") - self.gridLayout_4.addWidget(self.homeButton, 4, 1, 1, 1) + self.gridLayout_4.addWidget(self.homeButton, 5, 1, 1, 1) self.label_16 = QtWidgets.QLabel(parent=self.mechTab) font = QtGui.QFont() font.setBold(True) @@ -107,6 +107,9 @@ class Ui_Form(object): self.label_16.setFont(font) self.label_16.setObjectName("label_16") self.gridLayout_4.addWidget(self.label_16, 0, 0, 1, 3) + self.absoluteposBox = QtWidgets.QSpinBox(parent=self.mechTab) + self.absoluteposBox.setObjectName("absoluteposBox") + self.gridLayout_4.addWidget(self.absoluteposBox, 6, 1, 1, 1) self.stepperselectBox = QtWidgets.QComboBox(parent=self.mechTab) self.stepperselectBox.setObjectName("stepperselectBox") self.stepperselectBox.addItem("") @@ -114,31 +117,34 @@ class Ui_Form(object): self.gridLayout_4.addWidget(self.stepperselectBox, 1, 1, 1, 1) self.decreaseButton = QtWidgets.QPushButton(parent=self.mechTab) self.decreaseButton.setObjectName("decreaseButton") - self.gridLayout_4.addWidget(self.decreaseButton, 4, 0, 1, 1) + self.gridLayout_4.addWidget(self.decreaseButton, 5, 0, 1, 1) self.increaseButton = QtWidgets.QPushButton(parent=self.mechTab) self.increaseButton.setObjectName("increaseButton") - self.gridLayout_4.addWidget(self.increaseButton, 4, 2, 1, 1) + self.gridLayout_4.addWidget(self.increaseButton, 5, 2, 1, 1) self.label_18 = QtWidgets.QLabel(parent=self.mechTab) self.label_18.setObjectName("label_18") self.gridLayout_4.addWidget(self.label_18, 1, 0, 1, 1) + self.label_20 = QtWidgets.QLabel(parent=self.mechTab) + self.label_20.setObjectName("label_20") + self.gridLayout_4.addWidget(self.label_20, 6, 0, 1, 1) self.stepsizeBox = QtWidgets.QSpinBox(parent=self.mechTab) self.stepsizeBox.setMinimum(-1000) self.stepsizeBox.setMaximum(1000) self.stepsizeBox.setProperty("value", 500) self.stepsizeBox.setObjectName("stepsizeBox") - self.gridLayout_4.addWidget(self.stepsizeBox, 2, 1, 1, 1) + self.gridLayout_4.addWidget(self.stepsizeBox, 3, 1, 1, 1) self.label_17 = QtWidgets.QLabel(parent=self.mechTab) self.label_17.setObjectName("label_17") - self.gridLayout_4.addWidget(self.label_17, 2, 0, 1, 1) - self.label_20 = QtWidgets.QLabel(parent=self.mechTab) - self.label_20.setObjectName("label_20") - self.gridLayout_4.addWidget(self.label_20, 5, 0, 1, 1) + self.gridLayout_4.addWidget(self.label_17, 3, 0, 1, 1) self.absoluteGoButton = QtWidgets.QPushButton(parent=self.mechTab) self.absoluteGoButton.setObjectName("absoluteGoButton") - self.gridLayout_4.addWidget(self.absoluteGoButton, 5, 2, 1, 1) - self.absoluteposBox = QtWidgets.QSpinBox(parent=self.mechTab) - self.absoluteposBox.setObjectName("absoluteposBox") - self.gridLayout_4.addWidget(self.absoluteposBox, 5, 1, 1, 1) + self.gridLayout_4.addWidget(self.absoluteGoButton, 6, 2, 1, 1) + self.label_4 = QtWidgets.QLabel(parent=self.mechTab) + self.label_4.setObjectName("label_4") + self.gridLayout_4.addWidget(self.label_4, 2, 0, 1, 1) + self.stepperposLabel = QtWidgets.QLabel(parent=self.mechTab) + self.stepperposLabel.setObjectName("stepperposLabel") + self.gridLayout_4.addWidget(self.stepperposLabel, 2, 1, 1, 1) self.verticalLayout.addLayout(self.gridLayout_4) self.positionButton = QtWidgets.QPushButton(parent=self.mechTab) self.positionButton.setObjectName("positionButton") @@ -277,7 +283,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): @@ -300,9 +306,11 @@ class Ui_Form(object): self.decreaseButton.setText(_translate("Form", "-")) self.increaseButton.setText(_translate("Form", "+")) self.label_18.setText(_translate("Form", "Stepper:")) - self.label_17.setText(_translate("Form", "Step Size:")) self.label_20.setText(_translate("Form", "Absolute:")) + self.label_17.setText(_translate("Form", "Step Size:")) self.absoluteGoButton.setText(_translate("Form", "Go")) + self.label_4.setText(_translate("Form", "Position:")) + self.stepperposLabel.setText(_translate("Form", "0")) self.positionButton.setText(_translate("Form", "Saved Positions")) self.mechLUTButton.setText(_translate("Form", "Generate LUT")) self.viewmechLUTButton.setText(_translate("Form", "View LUT"))