Update auf v3
This commit is contained in:
251
main_v3.py
Normal file
251
main_v3.py
Normal file
@@ -0,0 +1,251 @@
|
||||
import tkinter as tk
|
||||
from tkinter import ttk, messagebox
|
||||
import serial
|
||||
import serial.tools.list_ports
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
||||
import threading
|
||||
import time
|
||||
import numpy as np
|
||||
|
||||
class ArduinoGUI:
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.root.title("Arduino GUI")
|
||||
|
||||
self.arduino = None
|
||||
self.ports = list(serial.tools.list_ports.comports())
|
||||
self.running = True
|
||||
self.current_point = None
|
||||
self.setpoints = []
|
||||
|
||||
# Flags for user actions
|
||||
self.setpoint_flag = False
|
||||
self.multi_setpoints_flag = False
|
||||
self.tare_flag = False
|
||||
self.demag_flag = False
|
||||
|
||||
self.create_widgets()
|
||||
|
||||
# Start the communication thread
|
||||
self.communication_thread = threading.Thread(target=self.communication_loop)
|
||||
self.communication_thread.start()
|
||||
|
||||
def create_widgets(self):
|
||||
self.com_label = tk.Label(self.root, text="Select COM Port:")
|
||||
self.com_label.grid(row=0, column=0)
|
||||
|
||||
self.combobox_value = tk.StringVar()
|
||||
self.combobox = ttk.Combobox(self.root, textvariable=self.combobox_value)
|
||||
self.combobox['values'] = [port.device for port in self.ports]
|
||||
self.combobox.grid(row=0, column=1)
|
||||
|
||||
self.connect_button = tk.Button(self.root, text="Connect", command=self.connect_arduino)
|
||||
self.connect_button.grid(row=0, column=2)
|
||||
|
||||
self.setpoint_label = tk.Label(self.root, text="Setpoint (Nm):")
|
||||
self.setpoint_label.grid(row=1, column=0)
|
||||
|
||||
self.setpoint_entry = tk.Entry(self.root)
|
||||
self.setpoint_entry.grid(row=1, column=1)
|
||||
|
||||
self.set_setpoint_button = tk.Button(self.root, text="Set", command=self.set_setpoint)
|
||||
self.set_setpoint_button.grid(row=1, column=2)
|
||||
|
||||
self.multi_setpoints_label = tk.Label(self.root, text="Setpoints (angle;torque):")
|
||||
self.multi_setpoints_label.grid(row=2, column=0)
|
||||
|
||||
self.multi_setpoints_text = tk.Text(self.root, height=5, width=20)
|
||||
self.multi_setpoints_text.grid(row=2, column=1)
|
||||
|
||||
self.send_multi_setpoints_button = tk.Button(self.root, text="Send Setpoints", command=self.send_multi_setpoints)
|
||||
self.send_multi_setpoints_button.grid(row=2, column=2)
|
||||
|
||||
self.tare_button = tk.Button(self.root, text="Tare Angle", command=self.tare_angle)
|
||||
self.tare_button.grid(row=3, column=2)
|
||||
|
||||
self.demag_button = tk.Button(self.root, text="Demagnetize", command=self.demagnetize)
|
||||
self.demag_button.grid(row=4, column=2)
|
||||
|
||||
self.exit_button = tk.Button(self.root, text="Exit", command=self.on_closing)
|
||||
self.exit_button.grid(row=5, column=2)
|
||||
|
||||
self.figure, self.ax = plt.subplots()
|
||||
self.canvas = FigureCanvasTkAgg(self.figure, self.root)
|
||||
self.canvas.get_tk_widget().grid(row=6, column=0, columnspan=3)
|
||||
|
||||
self.ax.set_title("Drehmoment-Drehwinkel-Kennlinie")
|
||||
self.ax.set_xlabel("Winkel (°)")
|
||||
self.ax.set_ylabel("Drehmoment (Nm)")
|
||||
self.ax.set_xlim(0, 90)
|
||||
self.ax.set_ylim(0, 50)
|
||||
|
||||
self.current_angle = 0
|
||||
self.current_torque = 0
|
||||
|
||||
self.angle_label_var = tk.StringVar()
|
||||
self.angle_label_var.set("Current Angle: 0")
|
||||
self.angle_label = tk.Label(self.root, textvariable=self.angle_label_var)
|
||||
self.angle_label.grid(row=7, column=0)
|
||||
|
||||
self.torque_label_var = tk.StringVar()
|
||||
self.torque_label_var.set("Current Torque: 0")
|
||||
self.torque_label = tk.Label(self.root, textvariable=self.torque_label_var)
|
||||
self.torque_label.grid(row=7, column=1)
|
||||
|
||||
def connect_arduino(self):
|
||||
com_port = self.combobox_value.get()
|
||||
if com_port:
|
||||
try:
|
||||
self.arduino = serial.Serial(com_port, 115200, timeout=1)
|
||||
messagebox.showinfo("Info", "Connected to Arduino on " + com_port)
|
||||
except Exception as e:
|
||||
messagebox.showerror("Error", str(e))
|
||||
else:
|
||||
messagebox.showwarning("Warning", "Please select a COM port")
|
||||
|
||||
def set_setpoint(self):
|
||||
if self.arduino:
|
||||
try:
|
||||
self.setpoint = float(self.setpoint_entry.get()) * 1000
|
||||
self.setpoint_flag = True
|
||||
except ValueError:
|
||||
messagebox.showerror("Error", "Invalid setpoint value.")
|
||||
else:
|
||||
messagebox.showwarning("Warning", "Arduino not connected")
|
||||
|
||||
def send_multi_setpoints(self):
|
||||
if self.arduino:
|
||||
setpoints = self.multi_setpoints_text.get("1.0", tk.END).strip().split("\n")
|
||||
coordinates = []
|
||||
for point in setpoints:
|
||||
try:
|
||||
angle, torque = map(float, point.split(";"))
|
||||
coordinates.append((angle, torque))
|
||||
except ValueError:
|
||||
messagebox.showerror("Error", f"Invalid input: {point}")
|
||||
return
|
||||
|
||||
coordinates.sort()
|
||||
self.setpoints = coordinates
|
||||
self.plot_coordinates(coordinates)
|
||||
self.multi_setpoints_flag = True
|
||||
else:
|
||||
messagebox.showwarning("Warning", "Arduino not connected")
|
||||
|
||||
def plot_coordinates(self, coordinates):
|
||||
angles, torques = zip(*coordinates)
|
||||
self.ax.clear()
|
||||
self.ax.plot(angles, torques, 'bo-', label="Setpoints")
|
||||
self.ax.set_title("Drehmoment-Drehwinkel-Kennlinie")
|
||||
self.ax.set_xlabel("Winkel (°)")
|
||||
self.ax.set_ylabel("Drehmoment (Nm)")
|
||||
self.ax.set_xlim(0, 90)
|
||||
self.ax.set_ylim(0, 50)
|
||||
self.ax.legend()
|
||||
self.canvas.draw()
|
||||
|
||||
def interpolate_coordinates(self, coordinates):
|
||||
interpolated_points = []
|
||||
for i in range(len(coordinates) - 1):
|
||||
start_angle, start_torque = coordinates[i]
|
||||
end_angle, end_torque = coordinates[i + 1]
|
||||
num_points = int((end_angle - start_angle) * 2)
|
||||
angles = np.linspace(start_angle, end_angle, num_points + 1)
|
||||
torques = np.linspace(start_torque, end_torque, num_points + 1)
|
||||
interpolated_points.extend(zip(angles, torques))
|
||||
|
||||
full_interpolated_points = [(angle, 0) for angle in np.arange(0, 90.5, 0.5)]
|
||||
for angle, torque in interpolated_points:
|
||||
index = int(angle * 2)
|
||||
full_interpolated_points[index] = (angle, torque)
|
||||
|
||||
return full_interpolated_points
|
||||
|
||||
def send_interpolated_points(self):
|
||||
if self.arduino:
|
||||
setpoints_command = "u"
|
||||
for angle, torque in self.setpoints:
|
||||
torque_mnm = torque * 1000
|
||||
setpoints_command += f"{int(angle * 2)},{torque_mnm:.1f};"
|
||||
setpoints_command = setpoints_command.rstrip(';') + "u\n"
|
||||
self.arduino.write(setpoints_command.encode())
|
||||
|
||||
timeout_ctr = time.time()
|
||||
while(self.arduino.in_waiting == 0 and time.time() - timeout_ctr < 2):
|
||||
pass
|
||||
|
||||
try:
|
||||
print(self.arduino.readline())
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def tare_angle(self):
|
||||
if self.arduino:
|
||||
self.tare_flag = True
|
||||
else:
|
||||
messagebox.showwarning("Warning", "Arduino not connected")
|
||||
|
||||
def demagnetize(self):
|
||||
if self.arduino:
|
||||
self.demag_flag = True
|
||||
else:
|
||||
messagebox.showwarning("Warning", "Arduino not connected")
|
||||
|
||||
def communication_loop(self):
|
||||
while self.running:
|
||||
if self.arduino:
|
||||
self.arduino.read_all()
|
||||
if self.setpoint_flag:
|
||||
self.arduino.write(f"s{self.setpoint:.0f},0\n".encode())
|
||||
self.setpoint_flag = False
|
||||
time.sleep(0.1)
|
||||
if self.multi_setpoints_flag:
|
||||
self.send_interpolated_points()
|
||||
self.multi_setpoints_flag = False
|
||||
time.sleep(0.1)
|
||||
if self.tare_flag:
|
||||
self.arduino.write(b'w\n')
|
||||
self.tare_flag = False
|
||||
time.sleep(0.1)
|
||||
if self.demag_flag:
|
||||
self.arduino.write(b'e\n')
|
||||
self.demag_flag = False
|
||||
time.sleep(0.1)
|
||||
|
||||
self.arduino.write(b'a\n')
|
||||
timeout_ctr = time.time()
|
||||
while(self.arduino.in_waiting == 0 and time.time() - timeout_ctr < 2):
|
||||
pass
|
||||
|
||||
try:
|
||||
data = self.arduino.readline().decode(errors='ignore').strip().split(";")
|
||||
self.current_angle = float(data[0]) / 1000
|
||||
self.current_torque = float(data[1]) / 1000
|
||||
print(data[2])
|
||||
|
||||
self.angle_label_var.set(f"Current Angle: {self.current_angle}")
|
||||
self.torque_label_var.set(f"Current Torque: {self.current_torque}")
|
||||
|
||||
if self.current_point is not None:
|
||||
self.current_point.remove()
|
||||
self.current_point, = self.ax.plot([self.current_angle], [self.current_torque], 'ro')
|
||||
self.canvas.draw()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
time.sleep(0.1)
|
||||
|
||||
def on_closing(self):
|
||||
self.running = False
|
||||
if self.arduino:
|
||||
self.arduino.close()
|
||||
self.root.quit()
|
||||
self.root.destroy()
|
||||
|
||||
if __name__ == "__main__":
|
||||
root = tk.Tk()
|
||||
app = ArduinoGUI(root)
|
||||
root.protocol("WM_DELETE_WINDOW", app.on_closing)
|
||||
root.mainloop()
|
||||
Reference in New Issue
Block a user