diff --git a/concept.txt b/concept.txt new file mode 100644 index 0000000..e69de29 diff --git a/conf.txt b/conf.txt new file mode 100644 index 0000000..1d72e79 --- /dev/null +++ b/conf.txt @@ -0,0 +1,3 @@ +Kp=3.00 +Ki=0.02 +Kd=0.05 \ No newline at end of file diff --git a/main_v2.py b/main_v2.py new file mode 100644 index 0000000..c9e680e --- /dev/null +++ b/main_v2.py @@ -0,0 +1,121 @@ +import tkinter as tk +from tkinter import messagebox +import matplotlib.pyplot as plt +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg +from matplotlib.figure import Figure +import serial + +# Globale Variablen +Kp = 0.0 +Ki = 0.0 +Kd = 0.0 +arduino = None +root = None +torque_mode = None + +def open_serial_connection(): + global arduino + try: + arduino = serial.Serial(port="COM4", baudrate=115200, timeout=1) + print("Verbindung zu Arduino hergestellt.") + except Exception as e: + print(f"Fehler beim Öffnen der seriellen Verbindung: {e}") + +def close_application(): + if messagebox.askokcancel("Schließen", "Wollen Sie die Anwendung wirklich schließen?"): + if arduino and arduino.is_open: + arduino.close() + root.destroy() + +def create_diagram(plot, coordinates_text, canvas): + plot.clear() + plot.set_xlim(0, 90) + plot.set_ylim(0, 50) # Beispielgrenzen für Drehmoment + plot.set_xlabel('Drehwinkel in Grad') + plot.set_ylabel('Drehmoment in Nm') + + coordinates = coordinates_text.get("1.0", tk.END).strip().split("\n") + valid_coords = [coord for coord in coordinates if ',' in coord and len(coord.split(',')) == 2] + + if valid_coords: + x_coords, y_coords = zip(*(map(float, coord.split(',')) for coord in valid_coords)) + plot.plot(x_coords, y_coords, marker='o', linestyle='-') + else: + messagebox.showerror("Eingabefehler", "Bitte geben Sie gültige Koordinaten ein. Beispiel: '10,20'") + + canvas.draw() + + +def send_command_to_arduino(command): + if arduino and arduino.is_open: + try: + arduino.write(command.encode()) + response = arduino.readline().decode().strip() + print(f"Arduino Antwort: {response}") + except Exception as e: + print(f"Fehler beim Senden des Befehls {command}: {e}") + +def on_plot_button_click(torque_input, coordinates_text, plot, canvas): + if torque_mode.get(): + set_torque = float(torque_input.get()) + command = f's{int(set_torque * 1000000):08x}' + send_command_to_arduino(command) + else: + create_diagram(plot, coordinates_text, canvas) + +def setup_gui(): + global root, torque_mode + root = tk.Tk() + root.title("Drehmoment-Regelungssystem") + + main_frame = tk.Frame(root) + main_frame.pack(fill=tk.BOTH, expand=True) + + left_frame = tk.Frame(main_frame, borderwidth=2, relief=tk.GROOVE) + left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) + + right_frame = tk.Frame(main_frame, borderwidth=2, relief=tk.GROOVE) + right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True) + + coordinates_label = tk.Label(left_frame, text="Koordinaten (Drehwinkel, Drehmoment):") + coordinates_label.pack() + coordinates_text = tk.Text(left_frame, height=5) + coordinates_text.pack() + + torque_label = tk.Label(left_frame, text="Soll-Drehmoment in Nm:") + torque_label.pack() + torque_input = tk.Entry(left_frame) + torque_input.pack() + + toggle_button = tk.Button(left_frame, text="Wechsel Drehmomentmodus", command=lambda: toggle_torque_mode(torque_input, coordinates_text)) + toggle_button.pack() + + plot_button = tk.Button(left_frame, text="Eingaben übernehmen", command=lambda: on_plot_button_click(torque_input, coordinates_text, plot, canvas)) + plot_button.pack() + + close_button = tk.Button(left_frame, text="Schließen", command=close_application) + close_button.pack() + + figure = Figure(figsize=(5, 4), dpi=100) + plot = figure.add_subplot(111) + canvas = FigureCanvasTkAgg(figure, right_frame) + canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True) + + torque_mode = tk.BooleanVar() + torque_mode.set(False) + +def toggle_torque_mode(torque_input, coordinates_text): + if torque_mode.get(): + torque_input.config(state='normal') + coordinates_text.config(state='disabled') + else: + torque_input.config(state='disabled') + coordinates_text.config(state='normal') + +def main(): + setup_gui() + open_serial_connection() + root.mainloop() + +if __name__ == '__main__': + main() diff --git a/main_v3.py b/main_v3.py new file mode 100644 index 0000000..2a9b842 --- /dev/null +++ b/main_v3.py @@ -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() \ No newline at end of file diff --git a/src/logo1.png b/src/logo1.png new file mode 100644 index 0000000..63099b9 Binary files /dev/null and b/src/logo1.png differ