From 1144e5fae92e5968b632c72a54075c5e6abcd9e5 Mon Sep 17 00:00:00 2001 From: Leon Teichroeb Date: Sun, 24 Oct 2021 11:59:13 +0200 Subject: [PATCH] Added arduino com port to config file. Removed log spam --- main.py | 2 +- src/arduino_device.py | 6 ++---- src/config_handling.py | 19 +++++++++++-------- src/globals.py | 1 + src/helmholtz_cage_device.py | 35 ++++++++++++++++++++++++++--------- src/psu_device.py | 1 - src/user_interface.py | 13 ++++++++----- 7 files changed, 49 insertions(+), 28 deletions(-) diff --git a/main.py b/main.py index 66b82ff..479cc45 100644 --- a/main.py +++ b/main.py @@ -40,7 +40,7 @@ def program_start(): g.exit_flag = False # Connect hardware to HelmholtzCageDevice adapter object - g.CAGE_DEVICE.reconnect_hardware_async() + g.CAGE_DEVICE.connect_hardware_async() # check config for values exceeding limits config.check_config(config.CONFIG_OBJECT) diff --git a/src/arduino_device.py b/src/arduino_device.py index 4c744be..9d81e77 100644 --- a/src/arduino_device.py +++ b/src/arduino_device.py @@ -8,19 +8,17 @@ class ArduinoDevice(Arduino): """ Main class to control the electronics box (which means commanding the arduino inside). Inherits from the Arduino library. All axis indices are go from 0-2 for x,y and z respectively""" - def __init__(self): + def __init__(self, com_port): self.pins = [0, 0, 0] # initialize list with pins to switch relay of each axis for i in range(3): # get correct pins from the config self.pins[i] = int(config_handling.read_from_config(g.AXIS_NAMES[i], "relay_pin", config_handling.CONFIG_OBJECT)) - ui_print("\nConnecting to Arduino...") # try to set up the arduino. Exceptions are handled by caller # search for connected arduino and connect by initializing arduino library class - Arduino.__init__(self, port="COM4", timeout=2) + Arduino.__init__(self, port=com_port, timeout=2) for pin in self.pins: self.pinMode(pin, "Output") self.digitalWrite(pin, "LOW") - ui_print("Arduino ready.") def set_axis_polarity(self, axis_index, reverse): """Sets the polarity of the axis (indexed with 0-2). True is reverse polarity""" diff --git a/src/config_handling.py b/src/config_handling.py index f57ff5b..b69023c 100644 --- a/src/config_handling.py +++ b/src/config_handling.py @@ -86,8 +86,6 @@ def edit_config(section, key, value, override=False): # edit a specific value i def check_config(config_object): # check all numeric values in the config and see if they are within safe limits - ui_print("Checking config file for values exceeding limits:") - concerns = {} # initialize dictionary for found problems problem_counter = 0 # count the number of values that exceed limits i = 0 @@ -101,17 +99,22 @@ def check_config(config_object): # check all numeric values in the config and s if not min_value <= value <= max_value: # value is not in safe limits concerns[axis].append(key) # add this entry to the problem dictionary problem_counter += 1 - - if len(concerns[axis]) == 0: # no problems were found for this axis - concerns[axis].append("No problems detected.") - - ui_print(axis, ":", *concerns[axis]) # print out results for this axis i += 1 if problem_counter > 0: # some values are not ok - # shop pup-up warning message: + # Print errors to console + ui_print("Config file contains errors:") + for axis in g.AXIS_NAMES: + # print out results for each axis + ui_print(axis, ":", *concerns[axis]) + + # shop pop-up warning message: messagebox.showwarning("Warning!", "Found %i value(s) exceeding limits in config file. Check values " "to ensure correct operation and avoid equipment damage!" % problem_counter) g.app.show_frame(ui.HardwareConfiguration) # open configuration window so user can check values + else: + pass + # If everything is fine, don't generate log spam + # ui_print("Config file checked.") def reset_config_to_default(): # reset values in config object to defaults (set in globals.py) diff --git a/src/globals.py b/src/globals.py index 0fccb56..cfae625 100644 --- a/src/globals.py +++ b/src/globals.py @@ -42,6 +42,7 @@ default_arrays = { # Dictionary for PSU configuration: default_psu_config = { "supply_model": "ql355tp", + 'arduino_port': "COM", "xy_port": "COM", # Default serial port where PSU for X- and Y-Axes is connected "z_port": "COM", # Default serial port where PSU for Z-Axis is connected } diff --git a/src/helmholtz_cage_device.py b/src/helmholtz_cage_device.py index d27350e..4796f27 100644 --- a/src/helmholtz_cage_device.py +++ b/src/helmholtz_cage_device.py @@ -61,6 +61,7 @@ class HelmholtzCageDevice: # Com ports self.com_port_psu1 = None self.com_port_psu2 = None + self.com_port_arduino = None # PSU object used self.psu_type = None @@ -98,39 +99,49 @@ class HelmholtzCageDevice: with self.hardware_lock: # All devices are usable if the object exists. None indicates # the device is not connected/not working properly + + # Fetch config variables + self.com_port_psu1 = config_handling.read_from_config("Supplies", "xy_port", + config_handling.CONFIG_OBJECT) + self.com_port_psu2 = config_handling.read_from_config("Supplies", "z_port", + config_handling.CONFIG_OBJECT) + self.com_port_arduino = config_handling.read_from_config("Supplies", "arduino_port", + config_handling.CONFIG_OBJECT) + psu_type_string = config_handling.read_from_config("Supplies", "supply_model", + config_handling.CONFIG_OBJECT) + # Arduino setup try: - self.arduino = ArduinoDevice() + self.arduino = ArduinoDevice(self.com_port_arduino) + ui_print("Connected to Arduino on port {}".format(self.com_port_arduino)) except Exception as e: self.arduino = None # show error messages to alert user - ui_print("Arduino setup failed:", e) + ui_print("Error connecting to Arduino:\n{}".format(e)) # PSU setup - self.com_port_psu1 = config_handling.read_from_config("Supplies", "xy_port", config_handling.CONFIG_OBJECT) - self.com_port_psu2 = config_handling.read_from_config("Supplies", "z_port", config_handling.CONFIG_OBJECT) - psu_type_string = config_handling.read_from_config("Supplies", "supply_model", - config_handling.CONFIG_OBJECT) if psu_type_string == "ps2000b": self.psu_type = PSUDevicePS2000B elif psu_type_string == "ql355tp": self.psu_type = PSUDeviceQL355TP else: - raise Exception("Invalid psu model: {}".format(self.psu_type)) + raise Exception("Invalid psu model:\n{}".format(self.psu_type)) # psu1: controls xy axis try: self.psu1 = self.psu_type(self.com_port_psu1) + ui_print("Connected to PSU 1 on port {}".format(self.com_port_psu1)) except Exception as e: self.psu1 = None - ui_print("Error creating PSU device:\n{}".format(e)) + ui_print("Error connecting to PSU 1:\n{}".format(e)) # psu2: controls z axis try: self.psu2 = self.psu_type(self.com_port_psu2) + ui_print("Connected to PSU 2 on port {}".format(self.com_port_psu2)) except Exception as e: self.psu2 = None - ui_print("Error creating PSU device:\n{}".format(e)) + ui_print("Error connecting to PSU 2:\n{}".format(e)) # The axes may not be deleted, so a special method for reinitialization is provided. for axis in self.axes: @@ -145,6 +156,12 @@ class HelmholtzCageDevice: connect_hardware_thread = Thread(target=self.reconnect_hardware) connect_hardware_thread.start() + def connect_hardware_async(self): + """Connects devices in a non-blocking call. + Acquires hardware lock and blocks other cage operations.""" + connect_hardware_thread = Thread(target=self.connect_hardware) + connect_hardware_thread.start() + def idle(self): """ Zero and activate channels """ if self.psu1 is not None: diff --git a/src/psu_device.py b/src/psu_device.py index 955bb55..501fd9c 100644 --- a/src/psu_device.py +++ b/src/psu_device.py @@ -13,7 +13,6 @@ class PSUDevice(ABC): def __init__(self, com_port): """PSUDevice assumes a serial connection""" - ui_print("\nConnecting to power supply...") self.com_port = com_port self.cached_state = dict.fromkeys(self.valid_channels()) # Used for components that require state on demand diff --git a/src/user_interface.py b/src/user_interface.py index 0af033a..fa237dc 100644 --- a/src/user_interface.py +++ b/src/user_interface.py @@ -1172,17 +1172,18 @@ class HardwareConfiguration(Frame): port_frame.grid(row=row_counter, column=0, sticky=W) # text for the description labels: - entry_texts = ["XY PSU Serial Port:", "Z PSU Serial Port:"] + entry_texts = ["Arduino Serial Port:", "XY PSU Serial Port:", "Z PSU Serial Port:"] # create variables to store the port names and set to current names + self.arduino_port = StringVar(value=g.CAGE_DEVICE.com_port_arduino) self.XY_port = StringVar(value=g.CAGE_DEVICE.com_port_psu1) self.Z_port = StringVar(value=g.CAGE_DEVICE.com_port_psu2) - port_vars = [self.XY_port, self.Z_port] # list to store both port variables + port_vars = [self.arduino_port, self.XY_port, self.Z_port] # list to store both port variables row = 0 for text in entry_texts: # do this for both ports field = Entry(port_frame, textvariable=port_vars[row]) # create entry field field.grid(row=row, column=1, sticky=W) - axis_label = Label(port_frame, text=text, padx=5, pady=10) # create description label - axis_label.grid(row=row, column=0, sticky=W) + axis_label = Label(port_frame, text=text) # create description label + axis_label.grid(row=row, column=0, padx=5, pady=5, sticky=W) info_label = Label(port_frame, text="e.g. COM10") # add label with example of right format info_label.grid(row=row, column=2, sticky=W) row += 1 @@ -1278,6 +1279,7 @@ class HardwareConfiguration(Frame): # set values for PSU serial ports: self.XY_port.set(g.CAGE_DEVICE.com_port_psu1) self.Z_port.set(g.CAGE_DEVICE.com_port_psu2) + self.arduino_port.set(g.CAGE_DEVICE.com_port_arduino) for key in self.entries.keys(): # go through the main value table for i in range(3): # go through all three axes @@ -1300,6 +1302,7 @@ class HardwareConfiguration(Frame): # set serial ports for PSUs: config.edit_config("Supplies", "xy_port", self.XY_port.get()) config.edit_config("Supplies", "z_port", self.Z_port.get()) + config.edit_config("Supplies", "arduino_port", self.arduino_port.get()) # set numeric values for all axes for key in self.entries.keys(): # go through rows of entry table @@ -1786,7 +1789,7 @@ class OutputConsole(Frame): while True: msg = self.print_queue.get(block=False) # print to console - self.console.insert(END, "\n" + msg) + self.console.insert(END, msg + "\n") except Empty: pass self.console.see(END) # scroll console to bottom