Update auf v3

This commit is contained in:
2024-07-12 10:34:05 +02:00
parent 5cfb0c7847
commit a92f04cfde
5 changed files with 375 additions and 0 deletions

251
main_v3.py Normal file
View 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()