Implemented communication atm broadband module.

This commit is contained in:
jupfi 2023-12-07 17:15:08 +01:00
parent b3db05e279
commit 9bd1852532
2 changed files with 70 additions and 14 deletions

View file

@ -8,7 +8,7 @@ from PyQt6 import QtSerialPort
from PyQt6.QtCore import QThread, pyqtSignal, pyqtSlot, Qt from PyQt6.QtCore import QThread, pyqtSignal, pyqtSlot, Qt
from PyQt6.QtWidgets import QApplication from PyQt6.QtWidgets import QApplication
from nqrduck.module.module_controller import ModuleController from nqrduck.module.module_controller import ModuleController
from .model import S11Data, LookupTable from .model import S11Data, ElectricalLookupTable, MechanicalLookupTable
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -16,6 +16,25 @@ logger = logging.getLogger(__name__)
class AutoTMController(ModuleController): class AutoTMController(ModuleController):
BAUDRATE = 115200 BAUDRATE = 115200
@pyqtSlot(str, object)
def process_signals(self, key: str, value: object) -> None:
logger.debug("Received signal: %s", key)
if key == "set_tune_and_match":
self.tune_and_match(value)
def tune_and_match(self, frequency: float) -> None:
""" This method is called when this module already has a LUT table. It should then tune and match the probe coil to the specified frequency.
"""
if self.module.model.LUT is None:
logger.error("Could not tune and match. No LUT available.")
return
elif self.module.model.LUT.TYPE == "Electrical":
tunning_voltage, matching_voltage = self.module.model.LUT.get_voltages(frequency)
self.set_voltages(str(tunning_voltage), str(matching_voltage))
elif self.module.model.LUT.TYPE == "Mechanical":
pass
def find_devices(self) -> None: def find_devices(self) -> None:
"""Scan for available serial devices and add them to the model as available devices.""" """Scan for available serial devices and add them to the model as available devices."""
logger.debug("Scanning for available serial devices") logger.debug("Scanning for available serial devices")
@ -436,7 +455,11 @@ class AutoTMController(ModuleController):
) )
command = "v%sv%s" % (matching_voltage, tuning_voltage) command = "v%sv%s" % (matching_voltage, tuning_voltage)
self.send_command(command) confirmation = self.send_command(command)
if confirmation:
logger.debug("Voltages set successfully")
# Emit nqrduck signal that T&M was successful
self.module.nqrduck_signal.emit("confirm_tune_and_match", None)
def generate_lut( def generate_lut(
self, self,
@ -482,7 +505,8 @@ class AutoTMController(ModuleController):
self.module.view.add_info_text(error) self.module.view.add_info_text(error)
return return
if frequency_step > (stop_frequency - start_frequency): # - 0.1 is to prevent float errors
if frequency_step - 0.1 > (stop_frequency - start_frequency):
error = "Could not generate LUT. Frequency step must be smaller than the frequency range" error = "Could not generate LUT. Frequency step must be smaller than the frequency range"
logger.error(error) logger.error(error)
self.module.view.add_info_text(error) self.module.view.add_info_text(error)
@ -496,7 +520,7 @@ class AutoTMController(ModuleController):
) )
# We create the lookup table # We create the lookup table
LUT = LookupTable( LUT = ElectricalLookupTable(
start_frequency, stop_frequency, frequency_step start_frequency, stop_frequency, frequency_step
) )

View file

@ -178,16 +178,6 @@ class LookupTable:
# This is the frequency at which the tuning and matching process was started # This is the frequency at which the tuning and matching process was started
self.started_frequency = None self.started_frequency = None
self.init_voltages()
def init_voltages(self) -> None:
"""Initialize the lookup table with default values."""
for frequency in np.arange(
self.start_frequency, self.stop_frequency, self.frequency_step
):
self.started_frequency = frequency
self.add_voltages(None, None)
def is_incomplete(self) -> bool: def is_incomplete(self) -> bool:
"""This method returns True if the lookup table is incomplete, """This method returns True if the lookup table is incomplete,
i.e. if there are frequencies for which no the tuning or matching voltage is none. i.e. if there are frequencies for which no the tuning or matching voltage is none.
@ -215,6 +205,33 @@ class LookupTable:
return None return None
def get_entry_number(self, frequency: float) -> int:
"""This method returns the entry number of the given frequency.
Args:
frequency (float): The frequency for which the entry number should be returned.
Returns:
int: The entry number of the given frequency.
"""
# Round to closest integer
return int(round((frequency - self.start_frequency) / self.frequency_step))
class ElectricalLookupTable(LookupTable):
TYPE = "Electrical"
def __init__(self, start_frequency: float, stop_frequency: float, frequency_step: float) -> None:
super().__init__(start_frequency, stop_frequency, frequency_step)
self.init_voltages()
def init_voltages(self) -> None:
"""Initialize the lookup table with default values."""
for frequency in np.arange(
self.start_frequency, self.stop_frequency, self.frequency_step
):
self.started_frequency = frequency
self.add_voltages(None, None)
def add_voltages(self, tuning_voltage: float, matching_voltage: float) -> None: def add_voltages(self, tuning_voltage: float, matching_voltage: float) -> None:
"""Add a tuning and matching voltage for the last started frequency to the lookup table. """Add a tuning and matching voltage for the last started frequency to the lookup table.
@ -223,7 +240,22 @@ class LookupTable:
matching_voltage (float): The matching voltage for the given frequency.""" matching_voltage (float): The matching voltage for the given frequency."""
self.data[self.started_frequency] = (tuning_voltage, matching_voltage) self.data[self.started_frequency] = (tuning_voltage, matching_voltage)
def get_voltages(self, frequency: float) -> tuple:
"""Get the tuning and matching voltage for the given frequency.
Args:
frequency (float): The frequency for which the tuning and matching voltage should be returned.
Returns:
tuple: The tuning and matching voltage for the given frequency.
"""
entry_number = self.get_entry_number(frequency)
key = list(self.data.keys())[entry_number]
return self.data[key]
class MechanicalLookupTable(LookupTable):
TYPE = "Mechanical"
pass
class AutoTMModel(ModuleModel): class AutoTMModel(ModuleModel):
available_devices_changed = pyqtSignal(list) available_devices_changed = pyqtSignal(list)
serial_changed = pyqtSignal(QSerialPort) serial_changed = pyqtSignal(QSerialPort)