diff --git a/.gitignore b/.gitignore index 0d0cc32..8c9e06e 100644 --- a/.gitignore +++ b/.gitignore @@ -103,3 +103,6 @@ ENV/ config.ini *.ini log.csv +.idea/misc.xml +.idea/misc.xml +.idea/Python-PS2000B.iml diff --git a/.idea/Python-PS2000B.iml b/.idea/Python-PS2000B.iml index 653cec9..edb294b 100644 --- a/.idea/Python-PS2000B.iml +++ b/.idea/Python-PS2000B.iml @@ -2,7 +2,7 @@ - + diff --git a/.idea/misc.xml b/.idea/misc.xml index 5ea737b..7ec378f 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/User_Interface.py b/User_Interface.py index 5e68e77..2b98a88 100644 --- a/User_Interface.py +++ b/User_Interface.py @@ -1,6 +1,7 @@ # This file contains classes to build all elements of the graphical user interface. # These classes also contain the methods that are executed when UI elements are activated. +# ToDo: optimize layout for smaller screen (like on IRS clean room PC) # import packages for user interface: from tkinter import * from tkinter import ttk @@ -561,7 +562,7 @@ class Configuration(Frame): row_counter += 1 - Label(self, text="", pady=0).grid(row=row_counter, column=0) # add spacer + # Label(self, text="", pady=0).grid(row=row_counter, column=0) # add spacer row_counter += 1 # setup main entry field for operational constants @@ -614,7 +615,7 @@ class Configuration(Frame): self.update_fields() # set current values from config file - Label(self, text="", pady=10).grid(row=row_counter, column=0) # add spacer + # Label(self, text="", pady=3).grid(row=row_counter, column=0) # add spacer row_counter += 1 # Setup buttons to implement and restore defaults @@ -635,7 +636,7 @@ class Configuration(Frame): restore_button.grid(row=0, column=1, padx=5) row_counter += 1 - Label(self, text="", pady=10).grid(row=row_counter, column=0) # add spacer + # Label(self, text="", pady=3).grid(row=row_counter, column=0) # add spacer def page_switch(self): # function that is called when switching to this window self.update_fields() # update values in the entry fields from config @@ -1082,7 +1083,7 @@ class StatusDisplay(Frame): i = 0 for axis in g.AXES: # go through all three axes if axis.device is not None: # there is a PSU for this axis connected - axis.update_status_info() # get latest status info from PSU + axis.update_status_info() # get latest status info from PSU (Takes very long...) # update all label variables with current values: # ToDo (optional): Use the central dictionary currently defined in csv_logging.py for this self.label_dict["PSU Serial Port:"][i].set(g.PORTS[i]) diff --git a/cage_func.py b/cage_func.py index 5a886e8..988322c 100644 --- a/cage_func.py +++ b/cage_func.py @@ -62,6 +62,7 @@ class Axis: def update_status_info(self): # Read out the values of the dynamic parameters stored in this object and update them try: # try to read out the data, this will fail on connection error to PSU + # ToDo: this takes a long time, try to improve performance self.device.update_device_information(self.channel) # update the information in the device object device_status = self.device.get_device_status_information(self.channel) # get object with new status info @@ -138,7 +139,9 @@ class Axis: if self.connected == "Connected": # only try to command the PSU if its actually connected self.device.set_current(abs(value), self.channel) # set desired current self.device.set_voltage(maxVoltage, self.channel) # set voltage limit - self.device.enable_output(self.channel) # activate the power output + if self.output_active == "Inactive": # don't send unnecessary commands to PSU + # ToDo: without calling update_status_info() output_active may be wrong + self.device.enable_output(self.channel) # activate the power output else: # the PSU is not connected ui_print(self.name, "not connected, can't set current.") @@ -312,6 +315,9 @@ def shut_down_all(): # safe shutdown at program end or on error try: # try to safe the PSU set_to_zero(g.XY_DEVICE) # set currents and voltages to 0 for both channels g.XY_DEVICE.disable_all() # disable power output on both channels + ui_print("Closing serial connection on XY PSU") + g.XY_DEVICE.serial.close() + g.XY_DEVICE = None except BaseException as e: # some error occurred, usually device has been disconnected ui_print("Error while deactivating XY PSU:", e) # print the problem in the console message += "\nError while deactivating XY PSU: %s" % e # append status to the message to show later @@ -328,6 +334,9 @@ def shut_down_all(): # safe shutdown at program end or on error try: set_to_zero(g.Z_DEVICE) g.Z_DEVICE.disable_all() + ui_print("Closing serial connection on Z PSU") + g.Z_DEVICE.serial.close() + g.Z_DEVICE = None except BaseException as e: ui_print("Error while deactivating Z PSU:", e) message += "\nError while deactivating Z PSU: %s" % e diff --git a/csv_threading.py b/csv_threading.py index 3abd05b..7793dcf 100644 --- a/csv_threading.py +++ b/csv_threading.py @@ -1,5 +1,6 @@ # tThis file contains code for executing a sequence of magnetic fields from a csv file. # To do this without crashing the UI it has to run in a separate thread using the threading module. +# ToDo!: apparently max. 1 thread can access PSU --> continuous update + csv thread crashes program. Find solution # import packages: import time @@ -75,6 +76,7 @@ class ExecCSVThread(Thread): % (time.time() - t_zero, array[i, 0]), field_vec * 1e6, "\u03BCT") func.set_field(field_vec) # send field vector to test bench controller.StatusDisplay.update_labels() # update status display after change + # ToDo: display update takes a long time, remove for performance? # log change to the log file if user has selected event logging in the Configure Logging window logger = controller.pages[ui.ConfigureLogging] # get object of logging configurator diff --git a/main.py b/main.py index 3428d40..2e8fb42 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,5 @@ # Main file of the program. Run this file to start the application. - +# ToDo: improve performance, communication to PSUs is way too slow for dynamic field changes # import packages: from os.path import exists import traceback @@ -56,7 +56,9 @@ try: # start normal operations g.app = HelmholtzGUI() # initialize user interface g.exitFlag = False # tell all functions that the user interface is now running g.app.state('zoomed') # open UI in maximized window - g.app.StatusDisplay.continuous_label_update(g.app, 500) # initiate regular Status Display updates (ms) + # g.app.StatusDisplay.continuous_label_update(g.app, 1000) # initiate regular Status Display updates (ms) + # ToDo: label update is very slow, commented out to save performance but should be implemented + # ToDo!: csv thread + continuous label update seems to exceed capacity of PSU communication ui_print("Program Initialized") config.check_config(config.CONFIG_OBJECT) # check config for values exceeding limits