forked from zietzm/Helmholtz_Test_Bench
Changed csv plots to show instantaneous field changes
This commit is contained in:
+3
-3
@@ -30,7 +30,7 @@ SMALL_BUTTON_FONT = ("Arial", 9)
|
||||
|
||||
|
||||
class HelmholtzGUI(Tk):
|
||||
# main application window, almost everything else here es called from this class
|
||||
# main application window, almost everything else here is called from this class
|
||||
# Inherited base class: Tk(), main application window class
|
||||
def __init__(self):
|
||||
Tk.__init__(self)
|
||||
@@ -84,7 +84,7 @@ class TopMenu:
|
||||
window.config(menu=menu) # put menu at the top of the window
|
||||
|
||||
ModeSelector = Menu(menu) # create a submenu object
|
||||
menu.add_cascade(label="Mode", menu=ModeSelector) # add a dropdown with the submenu object
|
||||
menu.add_cascade(label="Menu", menu=ModeSelector) # add a dropdown with the submenu object
|
||||
# create the different options in the dropdown:
|
||||
ModeSelector.add_command(label="Static Manual Input", command=lambda: self.manual_mode(window))
|
||||
ModeSelector.add_command(label="Execute CSV Sequence", command=lambda: self.execute_csv_mode(window))
|
||||
@@ -451,7 +451,7 @@ class ExecuteCSVMode(Frame):
|
||||
self.stop_button["state"] = "normal"
|
||||
self.reinit_button["state"] = "disabled"
|
||||
|
||||
# setup thread for running the sequence:
|
||||
# setup thread for running the sequence
|
||||
# More info: https://www.tutorialspoint.com/python/python_multithreading.htm
|
||||
g.threadLock = threading.Lock() # create thread locking object, used to ensure all devices switch at once later
|
||||
# create thread object:
|
||||
|
||||
+4
-3
@@ -22,7 +22,7 @@ class Axis:
|
||||
def __init__(self, index, device, PSU_channel, arduino_pin):
|
||||
# static information
|
||||
self.index = index # index of this axis, 0->X, 1->Y, 2->Z
|
||||
self.device = device # power supply object for this axis (PS2000B class)
|
||||
self.device = device # power supply object for this axis (PS2000B class object)
|
||||
self.channel = PSU_channel # power supply unit channel (0 or 1)
|
||||
self.ardPin = arduino_pin # output pin on the arduino for switching polarity on this axis
|
||||
|
||||
@@ -94,7 +94,7 @@ class Axis:
|
||||
else: # no communications error
|
||||
self.connected = "Connected" # PSU is connected
|
||||
|
||||
def print_status(self): # print out the current status of the device (not used at the moment)
|
||||
def print_status(self): # print out the current status of the PSU channel (not used at the moment)
|
||||
ui_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)))
|
||||
@@ -235,7 +235,8 @@ def setup_all(): # main test stand initialization function
|
||||
# this throws an exception, which can be ignored
|
||||
|
||||
g.ARDUINO = ArduinoCtrl() # initialize the arduino object from the control class, connects and sets up
|
||||
except Exception as e: # some unforeseen error occurred
|
||||
|
||||
except Exception as e: # some unforeseen error occurred (not connected issue handled in ArduinoCtrl class)
|
||||
# show error messages to alert user
|
||||
ui_print("Arduino setup failed:", e)
|
||||
ui_print(traceback.print_exc())
|
||||
|
||||
+17
-4
@@ -4,6 +4,7 @@
|
||||
# import packages:
|
||||
import time
|
||||
import pandas
|
||||
import numpy as np
|
||||
from threading import *
|
||||
from tkinter import messagebox
|
||||
import matplotlib.pyplot as plt
|
||||
@@ -13,6 +14,7 @@ import User_Interface as ui
|
||||
import cage_func as func
|
||||
import globals as g
|
||||
|
||||
import traceback # ToDo: remove!
|
||||
|
||||
class ExecCSVThread(Thread):
|
||||
# main class for executing a CSV sequence
|
||||
@@ -28,7 +30,7 @@ class ExecCSVThread(Thread):
|
||||
self.__stop_event = Event() # event which can be set to stop the thread execution if needed
|
||||
|
||||
def run(self): # called to start the execution of the thread
|
||||
ui.ui_print("Starting Sequence Execution...")
|
||||
ui.ui_print("\nStarting Sequence Execution...")
|
||||
self.execute_sequence(self.array, 0.1, self.parent, self.controller) # run sequence
|
||||
# when the sequence has ended, reset buttons on the UI:
|
||||
if not g.exitFlag: # main window is open
|
||||
@@ -130,7 +132,6 @@ def check_array_ok(array):
|
||||
|
||||
def plot_field_sequence(array, width, height): # create plot of fixed size (pixels) from array
|
||||
# ToDo (optional): polar plots, plots of angle...
|
||||
# ToDo (optional): show graphs as steps (as performed by test stand)
|
||||
fig_dpi = 100 # set figure resolution (dots per inch)
|
||||
px = 1/fig_dpi # get pixel to inch size conversion
|
||||
figure = plt.Figure(figsize=(width*px, height*px), dpi=fig_dpi) # create figure with correct size
|
||||
@@ -140,9 +141,21 @@ def plot_field_sequence(array, width, height): # create plot of fixed size (pix
|
||||
|
||||
figure.suptitle("Magnetic Field Sequence") # set figure title
|
||||
|
||||
t = array[:, 0] # extract time column
|
||||
# modify data to show instantaneous jumps in field to reflect test stand operation
|
||||
new_array = np.array([[0, 0, 0, 0]], dtype=float) # initialize modified array, zeros to show start from no fields
|
||||
|
||||
last_vals = [0, 0, 0] # [x,y,z] field values from last data point (zero here), used to create step in data
|
||||
for row in array[:, 0:4]: # go through each row in the original array
|
||||
# create extra datapoint at current timestamp, with field values from last, this creates "step" in plot:
|
||||
new_array = np.append(new_array, [[row[0], *last_vals]], axis=0)
|
||||
new_array = np.append(new_array, [row], axis=0) # add actual datapoint for current timestamp
|
||||
last_vals = row[1:4] # save values from current timestamp for next
|
||||
new_array = np.append(new_array, [[new_array[-1, 0], 0, 0, 0]], axis=0) # append last datapoint with 0 fields
|
||||
|
||||
# extract data and plot:
|
||||
t = new_array[:, 0] # extract time column
|
||||
for i in [0, 1, 2]: # go through all three axes
|
||||
data = array[:, i + 1] * 1e6 # extract field column of this axis and convert to microtesla
|
||||
data = new_array[:, i + 1] * 1e6 # extract field column of this axis and convert to microtesla
|
||||
max_val = g.AXES[i].max_comp_field[1] * 1e6 # get limits of achievable field
|
||||
min_val = g.AXES[i].max_comp_field[0] * 1e6
|
||||
plot = axes[i] # get appropriate subplot
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ exitFlag = True # False when main window is open, True otherwise
|
||||
|
||||
# Create dictionaries with default Constants and maximum/minimum values
|
||||
# Used to create default configs and to check if user inputs are within safe limits
|
||||
# ToDo: check actual maximum ratings (or refine after testing)
|
||||
# ToDo: check actual maximum ratings / refine after testing
|
||||
# ToDo: put this into a config file
|
||||
|
||||
# Dictionary for numerical values:
|
||||
|
||||
Reference in New Issue
Block a user