forked from zietzm/Helmholtz_Test_Bench
reworked cage_func to use class for axes
This commit is contained in:
+1
-1
@@ -1,7 +1,7 @@
|
||||
# import platform
|
||||
import time as t
|
||||
import numpy as np
|
||||
import globals as g
|
||||
import settings as g
|
||||
import cage_func as func
|
||||
from pyps2000b import PS2000B
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
from tkinter import *
|
||||
from tkinter import ttk
|
||||
import globals
|
||||
import settings
|
||||
import cage_func
|
||||
import random as rand
|
||||
|
||||
|
||||
+83
-47
@@ -1,15 +1,81 @@
|
||||
from pyps2000b import PS2000B
|
||||
import globals as g
|
||||
import settings as g
|
||||
import pandas
|
||||
import time
|
||||
import numpy as np
|
||||
|
||||
|
||||
def set_devices(): # creates device objects for all PSUs
|
||||
class Axis:
|
||||
def __init__(self, device, PSU_channel, arduino_pin):
|
||||
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.resistance = 0 # [Ohm]
|
||||
# maximum allowable values to pass through this circuit
|
||||
self.max_watts = 0 # [W]
|
||||
self.max_amps = 0 # [A]
|
||||
self.max_volts = 0 # [V]
|
||||
|
||||
self.coil_constant = 0 # coil constant of this axis [T/A]
|
||||
self.ambient_field = 0 # ambient field in this axis [T]
|
||||
# ToDo: get this info from settings file
|
||||
|
||||
def print_status(self): # axis = axis control variable, stored in settings.py
|
||||
print("%s, %0.2f V, %0.2f A"
|
||||
% (self.device.get_device_status_information(self.channel),
|
||||
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.device.voltage1 = 0
|
||||
self.device.current1 = 0
|
||||
g.ARDUINO.digitalWrite(self.ardPin, "LOW")
|
||||
|
||||
def set_signed_current(self, value): # sets current with correct polarity on this axis
|
||||
device = self.device
|
||||
channel = self.channel
|
||||
ardPin = self.ardPin
|
||||
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))
|
||||
elif value >= 0: # switch polarity as needed
|
||||
g.ARDUINO.digitalWrite(ardPin, "LOW")
|
||||
elif value < 0:
|
||||
g.ARDUINO.digitalWrite(ardPin, "HIGH")
|
||||
else:
|
||||
raise Exception("This should be impossible.")
|
||||
device.set_current(abs(value), channel)
|
||||
maxVoltage = min(max(1.1 * self.max_amps * self.resistance, 8), self.max_volts) # limit voltage
|
||||
device.set_voltage(maxVoltage)
|
||||
|
||||
def set_field_simple(self, value): # forms magnetic field as specified by value, w/o cancelling ambient field
|
||||
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
|
||||
field = value - self.ambient_field
|
||||
current = field / self.coil_constant
|
||||
self.set_signed_current(current)
|
||||
|
||||
|
||||
def setup_axes(): # creates device objects for all PSUs and sets their values
|
||||
g.XY_DEVICE = PS2000B.PS2000B(g.XY_PORT)
|
||||
g.Z_DEVICE = PS2000B.PS2000B(g.Z_PORT)
|
||||
g.X_AXIS = (g.XY_DEVICE, 0, g.RELAY_PINS[0], 0) # (device, channel, arduino pin, axis index)
|
||||
g.Y_AXIS = (g.XY_DEVICE, 1, g.RELAY_PINS[1], 1)
|
||||
g.Z_AXIS = (g.Z_DEVICE, 0, g.RELAY_PINS[2], 2)
|
||||
g.X_AXIS = Axis(g.XY_DEVICE, 0, g.RELAY_PINS[0])
|
||||
g.Y_AXIS = Axis(g.XY_DEVICE, 1, g.RELAY_PINS[1])
|
||||
g.Z_AXIS = Axis(g.Z_DEVICE, 0, g.RELAY_PINS[2])
|
||||
|
||||
g.axes = [g.X_AXIS, g.Y_AXIS, g.Z_AXIS]
|
||||
i = 0
|
||||
for axis in g.AXES:
|
||||
axis.resistance = g.RESISTANCES[i]
|
||||
axis.max_watts = g.MAX_WATTS[i]
|
||||
axis.max_amps = np.sqrt(axis.max_watts / axis.resistance)
|
||||
axis.max_volts = g.MAX_VOLTS[i]
|
||||
|
||||
axis.coil_constant = g.COIL_CONST[i]
|
||||
axis.ambient_field = g.AMBIENT_FIELD[i]
|
||||
i = i+1
|
||||
|
||||
|
||||
def activate_all(): # enables remote control and output on all PSUs and channels
|
||||
@@ -33,20 +99,13 @@ def safe_arduino(): # sets output pins to low and closes serial connection
|
||||
g.ARDUINO.digitalWrite(pin, "LOW")
|
||||
|
||||
|
||||
def print_status(axis): # axis = axis control variable, stored in globals.py
|
||||
device = axis[0] # PSU
|
||||
channel = axis[1] # output channel on the PSU
|
||||
print("%s, %0.2f V, %0.2f A"
|
||||
% (device.get_device_status_information(channel), device.get_voltage(channel), device.get_current(channel)))
|
||||
|
||||
|
||||
def print_status_3():
|
||||
print("X-Axis:")
|
||||
print_status(g.X_AXIS)
|
||||
g.X_AXIS.print_status()
|
||||
print("Y-Axis:")
|
||||
print_status(g.Y_AXIS)
|
||||
g.Y_AXIS.print_status()
|
||||
print("Z-Axis:")
|
||||
print_status(g.Z_AXIS)
|
||||
g.Z_AXIS.print_status()
|
||||
|
||||
|
||||
def set_to_zero(device): # sets voltages and currents to 0
|
||||
@@ -56,13 +115,13 @@ def set_to_zero(device): # sets voltages and currents to 0
|
||||
device.current2 = 0
|
||||
|
||||
|
||||
def power_down(): # temporary, set all outputs to 0 but keep connections enabled
|
||||
def power_down_all(): # temporary, set all outputs to 0 but keep connections enabled
|
||||
set_to_zero(g.XY_DEVICE)
|
||||
set_to_zero(g.Z_DEVICE)
|
||||
safe_arduino()
|
||||
|
||||
|
||||
def shut_down(): # shutdown at program end, set outputs to 0 and disable connections
|
||||
def shut_down_all(): # shutdown at program end or on error, set outputs to 0 and disable connections
|
||||
set_to_zero(g.XY_DEVICE)
|
||||
set_to_zero(g.Z_DEVICE)
|
||||
deactivate_all()
|
||||
@@ -71,41 +130,18 @@ def shut_down(): # shutdown at program end, set outputs to 0 and disable connec
|
||||
|
||||
|
||||
def set_field_simple(vector): # forms magnetic field as specified by vector, w/o cancelling ambient field
|
||||
i_vec = vector/g.COIL_CONST
|
||||
set_current_vec(i_vec)
|
||||
for i in [0, 1, 2]:
|
||||
g.AXES[i].set_field_simple(vector[i])
|
||||
|
||||
|
||||
def set_field(vector): # forms magnetic field as specified by vector, corrected for ambient field
|
||||
field = vector - g.AMBIENT_FIELD
|
||||
i_vec = field/g.COIL_CONST
|
||||
set_current_vec(i_vec)
|
||||
for i in [0, 1, 2]:
|
||||
g.AXES[i].set_field(vector[i])
|
||||
|
||||
|
||||
def set_current_vec(i_vec): # sets needed currents on each axis for given vector
|
||||
set_axis_current(g.X_AXIS, i_vec[0])
|
||||
set_axis_current(g.Y_AXIS, i_vec[1])
|
||||
set_axis_current(g.Z_AXIS, i_vec[2])
|
||||
|
||||
|
||||
def set_axis_current(axis, value): # sets current with correct polarity on one axis
|
||||
device = axis[0]
|
||||
channel = axis[1]
|
||||
ardPin = axis[2]
|
||||
axisIndex = axis[3]
|
||||
if abs(value) > g.MAX_AMPS[axisIndex]: # prevent excessive currents
|
||||
set_to_zero(device) # set currents and voltages to 0
|
||||
device.disable_all() # disable outputs on PSU
|
||||
safe_arduino() # set arduino pins to low and close serial link
|
||||
raise ValueError("Invalid current value. Tried %0.2fA, max. %0.2fA allowed" % (value, g.MAX_AMPS[axisIndex]))
|
||||
elif value >= 0: # switch polarity as needed
|
||||
g.ARDUINO.digitalWrite(ardPin, "LOW")
|
||||
elif value < 0:
|
||||
g.ARDUINO.digitalWrite(ardPin, "HIGH")
|
||||
else:
|
||||
raise Exception("This should be impossible.")
|
||||
device.set_current(abs(value), channel)
|
||||
maxVoltage = min(max(1.1 * g.MAX_AMPS[axisIndex] * g.RESISTANCES[axisIndex], 12), g.MAX_VOLTS) # limit voltage
|
||||
device.set_voltage(maxVoltage)
|
||||
for i in [0, 1, 2]:
|
||||
g.AXES[i].set_signed_current(i_vec[i])
|
||||
|
||||
|
||||
def execute_csv(filepath, printing=0): # runs through csv file containing times and desired field vectors
|
||||
@@ -129,4 +165,4 @@ def execute_csv(filepath, printing=0): # runs through csv file containing times
|
||||
print_status_3()
|
||||
t_ref = t
|
||||
print("File executed, powering down channels.")
|
||||
power_down() # set currents and voltages to 0, set arduino pins to low
|
||||
power_down_all() # set currents and voltages to 0, set arduino pins to low
|
||||
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
global COIL_CONST
|
||||
global AMBIENT_FIELD
|
||||
|
||||
global XY_PORT
|
||||
global Z_PORT
|
||||
|
||||
global XY_DEVICE
|
||||
global Z_DEVICE
|
||||
|
||||
global X_AXIS # object structure: (device, channel, arduino pin, axis index)
|
||||
global Y_AXIS
|
||||
global Z_AXIS
|
||||
|
||||
global RESISTANCES
|
||||
global MAX_AMPS
|
||||
global MAX_WATTS
|
||||
global MAX_VOLTS
|
||||
|
||||
global ARDUINO
|
||||
|
||||
RELAY_PINS = [15, 16, 17] # pin on the Arduino for switching relay of each axis [x,y,z]
|
||||
|
||||
@@ -1,28 +1,10 @@
|
||||
import numpy as np
|
||||
import globals as g
|
||||
import settings as g
|
||||
from tkinter import *
|
||||
from Arduino import Arduino
|
||||
|
||||
import cage_func as func
|
||||
import User_Interface as ui
|
||||
|
||||
# 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
|
||||
|
||||
application = ui.HelmholtzGUI()
|
||||
application.mainloop()
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
import numpy as np
|
||||
import globals as g
|
||||
import settings as g
|
||||
import cage_func as func
|
||||
# from pyps2000b import PS2000B
|
||||
from Arduino import Arduino
|
||||
@@ -23,7 +23,7 @@ g.Z_PORT = "COM2"
|
||||
g.MAX_AMPS = np.sqrt(g.MAX_WATTS / g.RESISTANCES) # calculate maximum currents in each axis
|
||||
|
||||
print("Connecting to PSUs...")
|
||||
func.set_devices() # initiate communication, set handles
|
||||
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.")
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import numpy as np
|
||||
|
||||
global XY_DEVICE
|
||||
global Z_DEVICE
|
||||
|
||||
global X_AXIS # object structure: (device, channel, arduino pin, axis index)
|
||||
global Y_AXIS
|
||||
global Z_AXIS
|
||||
|
||||
global AXES # list containing [X_AXIS, Y_AXIS, Z_AXIS]
|
||||
|
||||
# Constants:
|
||||
COIL_CONST = np.array([38.6, 38.45, 37.9]) * 1e-9 # Coil constants [x,y,z] in T/A
|
||||
AMBIENT_FIELD = np.array([80]) * 1e-6 # ambient magnetic field in measurement area, to be cancelled out
|
||||
RESISTANCES = np.array([3.9, 1, 1]) # resistance of [x,y,z] circuits
|
||||
MAX_WATTS = np.array([8, 0, 0]) # 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 = "COM1" # placeholders
|
||||
Z_PORT = "COM2"
|
||||
|
||||
global ARDUINO
|
||||
|
||||
RELAY_PINS = [15, 16, 17] # pin on the Arduino for switching relay of each axis [x,y,z]
|
||||
|
||||
# ToDo: make proper settings file to read from and write to
|
||||
Reference in New Issue
Block a user