From 8cf4961d99fc79e7b5c6c20ea6159455b712d610 Mon Sep 17 00:00:00 2001 From: Martin Zietz Date: Thu, 28 Jan 2021 17:28:38 +0100 Subject: [PATCH] implemented config file read and default write --- .gitignore | 1 + User_Interface.py | 2 +- cage_func.py | 51 ++++++++++++++++++++++++++++++++++------ globals.py | 59 ++++++++++++++++++++++------------------------- main.py | 13 +++++------ main_old.py | 36 ----------------------------- 6 files changed, 79 insertions(+), 83 deletions(-) delete mode 100644 main_old.py diff --git a/.gitignore b/.gitignore index 9c4f096..7395fe1 100644 --- a/.gitignore +++ b/.gitignore @@ -100,3 +100,4 @@ ENV/ .idea/Python-PS2000B.iml .idea/Python-PS2000B.iml .idea/misc.xml +config.ini diff --git a/User_Interface.py b/User_Interface.py index 0f68de0..cbc57e6 100644 --- a/User_Interface.py +++ b/User_Interface.py @@ -275,7 +275,7 @@ class StatusDisplay(Frame): for axis in g.AXES: if axis.device is not None: axis.update_status_info() - self.label_dict["PSU Serial Port:"][i].set(g.ports[i]) + self.label_dict["PSU Serial Port:"][i].set(g.PORTS[i]) self.label_dict["PSU Channel:"][i].set(axis.channel) self.label_dict["PSU Status:"][i].set(axis.connected) self.label_dict["Arduino Status:"][i].set(g.ARDUINO.connected) # ToDo (optional): make this multicolumn diff --git a/cage_func.py b/cage_func.py index 4e88973..f23105b 100644 --- a/cage_func.py +++ b/cage_func.py @@ -7,6 +7,7 @@ import numpy as np import serial import traceback # ToDo: remove from tkinter import * +from configparser import ConfigParser class Axis: @@ -18,15 +19,15 @@ class Axis: 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.port = g.PORTS[index] - self.resistance = g.RESISTANCES[index] - self.max_watts = g.MAX_WATTS[index] + self.resistance = float(read_config(self.name, "resistance")) + self.max_watts = float(read_config(self.name, "max_watts")) self.max_amps = np.sqrt(self.max_watts / self.resistance) - self.max_volts = g.MAX_VOLTS[index] + self.max_volts = float(read_config(self.name, "max_volts")) - self.coil_constant = g.COIL_CONST[index] - self.ambient_field = g.AMBIENT_FIELD[index] + self.coil_constant = float(read_config(self.name, "coil_const")) + self.ambient_field = float(read_config(self.name, "ambient_field")) max_field = self.max_amps * self.coil_constant # max field reachable in this axis self.max_field = np.array([-max_field, max_field]) @@ -171,6 +172,37 @@ class ArduinoCtrl(Arduino): self.digitalWrite(pin, "LOW") +def read_config(section, key): # attempt to read config file + # ToDo (optional) better error handling + file = g.CONFIG_FILE + config_object = ConfigParser() + try: + config_object.read(file) + section_obj = config_object[section] + return section_obj[key] + except KeyError as e: + ui_print("Error while reading config file: e") + raise KeyError("Could not find key", key, "in config file.") + + +def create_default_config(file): + config = ConfigParser() + + i = 0 + for axis_name in g.AXIS_NAMES: + config.add_section(axis_name) + for key in g.default_arrays.keys(): + config.set(axis_name, key, str(g.default_arrays[key][i])) + i += 1 + + config.add_section("PORTS") + for key in g.defaults.keys(): + config.set("PORTS", key, str(g.defaults[key])) + + with open(file, 'w') as conf: + config.write(conf) + + def ui_print(*content): # prints text to built in console output = "" for text in content: @@ -185,6 +217,7 @@ def ui_print(*content): # prints text to built in console def setup_axes(): # creates device objects for all PSUs and sets their values # Connect to Arduino: + arduino_pins = read_config("PORTS", "relay_pins") try: if g.ARDUINO is not None: # ui_print("\nClosing arduino link") @@ -198,13 +231,17 @@ def setup_axes(): # creates device objects for all PSUs and sets their values pass # when no Arduino is connected but g.ARDUINO has been initialized then there is nothing to close # this throws exception, which can be ignored - g.ARDUINO = ArduinoCtrl(g.RELAY_PINS) + g.ARDUINO = ArduinoCtrl(arduino_pins) except Exception as e: ui_print("Arduino setup failed:", e) ui_print(traceback.print_exc()) g.AXES = [] + g.XY_PORT = read_config("PORTS", "xy_port") + g.Z_PORT = read_config("PORTS", "z_port") + g.PORTS = [g.XY_PORT, g.XY_PORT, g.Z_PORT] + ui_print("\nConnecting to XY Device on %s..." % g.XY_PORT) try: if g.XY_DEVICE is not None: diff --git a/globals.py b/globals.py index bec9393..173f7c0 100644 --- a/globals.py +++ b/globals.py @@ -1,5 +1,4 @@ import numpy as np -from configparser import ConfigParser # global variables set in other files XY_DEVICE = None @@ -14,36 +13,32 @@ AXES = None # list containing [X_AXIS, Y_AXIS, Z_AXIS] app = None - -def read_config(file): # attempt to read config file - config_object = ConfigParser() - config_object.read(file) - print(config_object["X-Axis"]["coil_consthhh"]) - - -def create_config(file): - config = ConfigParser() - - config["X-Axis"] = { - "coil_const": str(38.6 * 1e-6) - } - - with open(file, 'w') as conf: - config.write(conf) - - -# Constants: -COIL_CONST = np.array([38.6, 38.45, 37.9]) * 1e-6 # Coil constants [x,y,z] in T/A -AMBIENT_FIELD = np.array([30, 30, 30]) * 1e-6 # ambient magnetic field in measurement area, to be cancelled out -RESISTANCES = np.array([1.7, 1.7, 1.7]) # resistance of [x,y,z] circuits -MAX_WATTS = np.array([15, 15, 15]) # max. allowed power for [x,y,z] circuits -MAX_VOLTS = [16, 16, 16] # max. allowed voltage, limited to 16V by used diodes! - -# COM-Ports for power supply units: -XY_PORT = "COM10" # placeholders -Z_PORT = "COM11" - AXIS_NAMES = ["X-Axis", "Y-Axis", "Z-Axis"] -ports = [XY_PORT, XY_PORT, Z_PORT] -RELAY_PINS = [15, 16, 17] # pin on the Arduino for switching relay of each axis [x,y,z] +global CONFIG_FILE + +'''global COIL_CONST +global RESISTANCES +global MAX_WATTS +global MAX_VOLTS +global AMBIENT_FIELD''' + +global XY_PORT +global Z_PORT +global RELAY_PINS + +global PORTS + +# Default Constants: +default_arrays = { + "coil_const": np.array([38.6, 38.45, 37.9]) * 1e-6, # Coil constants [x,y,z] [T/A] + "ambient_field": np.array([30, 30, 30]) * 1e-6, # ambient magnetic field in measurement area [T] + "resistance": np.array([1.7, 1.7, 1.7]), # resistance of [x,y,z] circuits [Ohm] + "max_watts": np.array([15, 15, 15], dtype=float), # max. allowed power for [x,y,z] circuits [W] + "max_volts": np.array([16, 16, 16], dtype=float), # max. allowed voltage, limited to 16V by used diodes! [V] +} +defaults = { + "xy_port": "COM1", # Serial port where PSU for X- and Y-Axes is connected + "z_port": "COM2", # Serial port where PSU for Z-Axis is connected + "relay_pins": [15, 16, 17] # pin on the arduino for reversing [x,y,z] polarity +} diff --git a/main.py b/main.py index 8547c2f..f4a8002 100644 --- a/main.py +++ b/main.py @@ -2,16 +2,15 @@ from User_Interface import HelmholtzGUI import cage_func as func import traceback import globals as g +from os.path import exists try: # start normal operations - print("Reading config file...") - config_file = 'config.ini' - try: - g.read_config(config_file) - except KeyError: - print("Error when reading config file, creating new.") - g.create_config(config_file) + g.CONFIG_FILE = 'config.ini' + + if not exists(g.CONFIG_FILE): + print("Config file not found, creating new from defaults.") + func.create_default_config(g.CONFIG_FILE) print("Starting setup...") func.setup_axes() # initiate communication, set handles diff --git a/main_old.py b/main_old.py deleted file mode 100644 index df82b87..0000000 --- a/main_old.py +++ /dev/null @@ -1,36 +0,0 @@ -import numpy as np -import globals as g -import cage_func as func -# from pyps2000b import PS2000B -from Arduino import Arduino - -# User Inputs/Configuration---------------------------------- -# Desired output: -mag_vec1 = np.array([10, 10, 5])*1e-6 - -# Constants: -g.COIL_CONST = np.array([38.6, 38.45, 37.9]) * 1e-9 # Coil constants [x,y,z] in T/A -g.AMBIENT_FIELD = np.array([80]) * 1e-6 # ambient magnetic field in measurement area, to be cancelled out -g.RESISTANCES = np.array([3.9, 1, 1]) # resistance of [x,y,z] circuits -g.MAX_WATTS = np.array([8, 0, 0]) # max. allowed power for [x,y,z] circuits -g.MAX_VOLTS = 16 # max. allowed voltage, limited to 16V by used diodes! - -# COM-Ports for power supply units: -g.XY_PORT = "COM1" # placeholders -g.Z_PORT = "COM2" - -# Code starts here------------------------------------------ -g.MAX_AMPS = np.sqrt(g.MAX_WATTS / g.RESISTANCES) # calculate maximum currents in each axis - -print("Connecting to PSUs...") -func.setup_axes() # initiate communication, set handles -print("Connecting to Arduino...") -g.ARDUINO = Arduino() # search for connected arduino and set handle -print("Arduino found, configuring pins.") -func.setup_arduino() -print("Activating PSU outputs...") -func.activate_all() # activate remote control and outputs on PSUs - -func.set_field_simple(mag_vec1) - -func.deactivate_all()