From 03e37595255d9f8a130bce2579d9be4141f968bd Mon Sep 17 00:00:00 2001 From: Martin Zietz Date: Fri, 22 Jan 2021 16:47:01 +0100 Subject: [PATCH] implemented readouts in status display --- User_Interface.py | 23 +++++++++++++---- cage_func.py | 63 ++++++++++++++++++++++++++++++++++++----------- main.py | 9 ++++--- 3 files changed, 72 insertions(+), 23 deletions(-) diff --git a/User_Interface.py b/User_Interface.py index 0801e7d..e597394 100644 --- a/User_Interface.py +++ b/User_Interface.py @@ -81,7 +81,10 @@ class StatusDisplay(Frame): col = col + 1 # move to next column rowCounter = rowCounter + 1 # increase row counter to place future stuff below header - TextLabels = ["Port:", "Channel:", "Output:"] # define content of row entries + # define content of row entries + TextLabels = ["Serial Port:", "PSU Channel:", "Connection Status:", "Output:", "Remote Control:", + "Voltage Setpoint:", "Actual Voltage:", "Current Setpoint:", "Actual Current:", " ", + "Target Field:", "Trgt. Field Raw:", "Target Current:", "Inverted:"] self.rowNo = len(TextLabels) # get number of label rows self.columnNo = 6 # number of label columns @@ -98,7 +101,7 @@ class StatusDisplay(Frame): col = 0 for LabelCol in self.Labels: # place row entries in grid layout for all columns for row in range(self.rowNo): # place row entries - LabelCol[row].grid(row=row+rowCounter, column=col, sticky="w") + LabelCol[row].grid(row=row+rowCounter, column=col, sticky="w", padx=10) col = col + 1 rowCounter = rowCounter + self.rowNo # increase row counter to place future stuff below this @@ -106,12 +109,22 @@ class StatusDisplay(Frame): def update_labels(self, controller): i = 0 - for axis in g.AXES: # ToDo: switch to proper axes when PSU connected + for axis in g.AXES: if axis.device is not None: axis.update_values() - self.label_dict["Port:"][i].set(g.ports[i]) - self.label_dict["Channel:"][i].set(axis.channel) + self.label_dict["Serial Port:"][i].set(g.ports[i]) + self.label_dict["PSU Channel:"][i].set(axis.channel) + self.label_dict["Connection Status:"][i].set(axis.connected) self.label_dict["Output:"][i].set(axis.output_active) + self.label_dict["Remote Control:"][i].set(axis.remote_ctrl_active) + self.label_dict["Voltage Setpoint:"][i].set("%0.3f V" % axis.voltage_setpoint) + self.label_dict["Actual Voltage:"][i].set("%0.3f V" % axis.voltage) + self.label_dict["Current Setpoint:"][i].set("%0.3f A" % axis.current_setpoint) + self.label_dict["Actual Current:"][i].set("%0.3f A" % axis.current) + self.label_dict["Target Field:"][i].set("%0.3f \u03BCT" % (axis.target_field*1e6)) + self.label_dict["Trgt. Field Raw:"][i].set("%0.3f \u03BCT" % (axis.target_field_comp*1e6)) + self.label_dict["Target Current:"][i].set("%0.3f A" % axis.target_current) + self.label_dict["Inverted:"][i].set(axis.polarity_switched) i = i+1 controller.after(2000, lambda: self.update_labels(controller)) diff --git a/cage_func.py b/cage_func.py index 71887a4..da98df8 100644 --- a/cage_func.py +++ b/cage_func.py @@ -9,11 +9,15 @@ import serial class Axis: def __init__(self, index, device, PSU_channel, arduino_pin): + # static information self.index = index self.device = device # power supply object (PS2000B class) self.channel = PSU_channel # power supply unit channel (1 or 2) self.ardPin = arduino_pin # output pin on the arduino for switching polarity on this axis + self.name = g.AXIS_NAMES[index] + self.port = g.ports[index] + self.resistance = 0 # [Ohm] # maximum allowable values to pass through this circuit self.max_watts = 0 # [W] @@ -24,32 +28,54 @@ class Axis: self.ambient_field = 0 # ambient field in this axis [T] # ToDo: get this info from settings file - self.output_active = 0 # power output on the PSU enabled? - self.remote_ctrl_active = 0 # remote control on the PSU enabled? + # dynamic information + self.connected = "Not Connected" + self.output_active = "Unknown" # power output on the PSU enabled? + self.remote_ctrl_active = "Unknown" # remote control on the PSU enabled? self.voltage_setpoint = 0 # target voltage on PSU [V] self.voltage = 0 # actual voltage on PSU [V] self.current_setpoint = 0 # target current on PSU [A] self.current = 0 # actual current on PSU [A] - self.polarity_switched = 0 # polarity switched on the Arduino? + self.polarity_switched = "Unknown" # polarity switched on the Arduino? + + self.target_field_comp = 0.0 # field to be created by coil pair (this is sent to the coils) [T] + self.target_field = 0.0 # field that should occur in measurement area (ambient still needs to be compensated) [T] + self.target_current = 0 # signed current that should pass through coil pair [A] if self.device is not None: self.update_status_info() - self.name = g.AXIS_NAMES[index] - def update_status_info(self): # Read out the values of the parameters stored in this class and update them - self.device.update_device_information(self.channel) - device_status = self.device.get_device_status_information(self.channel) - self.output_active = device_status.output_active - self.remote_ctrl_active = device_status.remote_control_active + try: + self.device.update_device_information(self.channel) + device_status = self.device.get_device_status_information(self.channel) + if device_status.output_active: + self.output_active = "Active" + else: self.output_active = "Inactive" + if device_status.remote_control_active: + self.remote_ctrl_active = "Active" + else: self.remote_ctrl_active = "Inactive" - self.voltage = self.device.get_voltage(self.channel) - self.voltage_setpoint = self.device.get_voltage_setpoint(self.channel) - self.current = self.device.get_current(self.channel) - self.current_setpoint = self.device.get_current_setpoint(self.channel) + self.voltage = self.device.get_voltage(self.channel) + self.voltage_setpoint = self.device.get_voltage_setpoint(self.channel) + self.current = self.device.get_current(self.channel) + self.current_setpoint = self.device.get_current_setpoint(self.channel) + except serial.serialutil.SerialException: + # print("Connection Error with %s PSU on %s" % (self.name, self.port)) + self.connected = "Connection Error" + self.output_active = "Unknown" + self.remote_ctrl_active = "Unknown" + else: + self.connected = "Connected" - self.polarity_switched = g.ARDUINO.digitalRead(self.ardPin) # ToDo: Test if this actually works + try: + if g.ARDUINO.digitalRead(self.ardPin): # ToDo: Test if this actually works + self.polarity_switched = "True" + else: self.polarity_switched = "False" + except serial.serialutil.SerialException: + # print("Connection Error with Arduino") + self.polarity_switched = "Unknown" def print_status(self): # axis = axis control variable, stored in settings.py print("%s, %0.2f V, %0.2f A" @@ -57,6 +83,9 @@ class Axis: self.device.get_voltage(self.channel), self.device.get_current(self.channel))) def power_down(self): # temporary powerdown, set outputs to 0 but keep connections enabled + self.target_current = 0 + self.target_field = 0 + self.target_field_comp = 0 self.device.voltage1 = 0 self.device.current1 = 0 g.ARDUINO.digitalWrite(self.ardPin, "LOW") @@ -65,6 +94,7 @@ class Axis: device = self.device channel = self.channel ardPin = self.ardPin + self.target_current = value if abs(value) > self.max_amps: # prevent excessive currents shut_down_all() # safe all devices raise ValueError("Invalid current value. Tried %0.2fA, max. %0.2fA allowed" % (value, self.max_amps)) @@ -79,11 +109,15 @@ class Axis: device.set_voltage(maxVoltage) def set_field_simple(self, value): # forms magnetic field as specified by value, w/o cancelling ambient field + self.target_field = value + self.target_field_comp = value current = value / self.coil_constant self.set_signed_current(current) def set_field(self, value): # forms magnetic field as specified by value, corrected for ambient field + self.target_field = value field = value - self.ambient_field + self.target_field_comp = field current = field / self.coil_constant self.set_signed_current(current) @@ -180,6 +214,7 @@ def power_down_all(): # temporary, set all outputs to 0 but keep connections en def shut_down_all(): # shutdown at program end or on error, set outputs to 0 and disable connections + # ToDo: better messages print("\nAttempting to safely shut down all devices. Check equipment to confirm.") try: set_to_zero(g.XY_DEVICE) except: diff --git a/main.py b/main.py index 8b5af55..f64f2a0 100644 --- a/main.py +++ b/main.py @@ -3,7 +3,7 @@ import cage_func as func import traceback import settings as g -try: +try: # start normal operations print("Connecting to PSUs...") func.setup_axes() # initiate communication, set handles @@ -19,9 +19,10 @@ try: application = ui.HelmholtzGUI() application.mainloop() -except: - print("\nAn error occurred. Shutting down.") +except BaseException as e: # if there is an error, print what happened + print("\nAn error occurred, Shutting down.") + print(e) print(traceback.print_exc()) -finally: +finally: # safely shut everything down at the end func.shut_down_all()