fotobox_SPRT/Steuerung_Arduino.py

163 lines
6.2 KiB
Python
Raw Normal View History

2024-10-07 19:55:43 +02:00
#Erstellt die grafische Oberfläche und ermöglicht die serielle Kommunikation mit dem Arduino, um die Einstellungen für die Beleuchtung und Triggerhandhabung vorzunehmen
import tkinter as tk
from tkinter import messagebox
import serial
import os
class Entry:
def __init__(self, root):
self.root = root
root.title("Steuerung Arduino")
root.protocol("WM_DELETE_WINDOW", self.on_closing)
self.settings_file = "/home/pi/Arduino/einstellungen.txt"
settings_path = os.path.dirname(self.settings_file)
if not os.path.exists(settings_path):
os.makedirs(settings_path)
self.load_settings() #Einstellungen beim Start des Programms laden
try:
self.ser = serial.Serial("/dev/ttyUSB0", 9600, timeout = 2) #Serielle Verbindung zum Arduino aufbauen mit 2 Sekunden Timeout
except serial.SerialException as e:
messagebox.showerror("Fehler in der Kommunikation mit dem Arduino", e)
return
self.create_widgets()
root.geometry("400x500")
#Widgets für die GUI erstellen (Checkboxen, Eingabefelder, Beschriftungen)
def create_widgets(self):
self.entries = []
names = ["trigger", "vortrigger", "belichtung", "pwmFrequency", "dutyCycle"]
description = ["Impulse zum Auslösen des Kameratriggers", "Start der Beleuchtung vor dem Kameratrigger", "Belichtungsdauer", "Frequenz PWM", "Duty Cycle PWM"]
units = ["Imp", "Imp", "ms", "Hz", "%"]
extra = ["[250 Hz - 60 kHz]", "[0 - 100 %]"]
i = 0
for name in names:
frame = tk.Frame(self.root)
frame.pack(fill=tk.X, pady=5)
tk.Label(frame, text = description[i]).pack()
entry_frame = tk.Frame(frame)
entry_frame.pack(side=tk.TOP)
entry = tk.Entry(entry_frame, width = 7)
entry.pack(side=tk.LEFT)
unit = tk.Label(entry_frame, text=units[i]).pack(side=tk.LEFT)
entry.insert(0, self.settings.get(name, ''))
self.entries.append((name, entry))
i += 1
self.pwm_aktiv = tk.IntVar(value = self.settings.get("pwm_aktiv", 0))
tk.Checkbutton(self.root, text = "Beleuchtung einschalten", variable=self.pwm_aktiv).pack(pady=5)
tk.Button(self.root, text = "Einstellungen an Arduino senden", command = self.send_arduino_settings).pack(pady=5)
tk.Button(self.root, text = "Einstellungen aus Arduino laden", command = self.load_arduino_settings).pack(pady=5)
tk.Button(self.root, text='Einstellungen speichern', command=self.save_settings).pack(pady=5)
tk.Button(self.root, text='Einstellungen laden', command=self.load_settings).pack(pady=5)
#Funktion um die Einstellungen in der Textdatei zu speichern
def save_settings(self):
settings = [f"{name}:{entry.get()}\n" for name, entry in self.entries]
with open(self.settings_file, "w") as f:
f.writelines(settings)
#Funktion um Einstellungen aus Textdatei zu lesen
def load_settings(self):
if os.path.exists(self.settings_file):
with open(self.settings_file, "r") as f:
self.settings = {line.split(':')[0]: line.split(':')[1].strip() for line in f}
else:
self.settings = {}
#Einstellungen über serielle Verbindung vom Arduino laden
def load_arduino_settings(self):
if not self.ser.is_open:
messagebox.showerror("Fehler", "Keine Verbindung zum Arduino")
return
try:
self.ser.write(b'GET\n')
data = self.ser.readline().decode('utf-8').strip()
except serial.SerialException as e:
messagebox.showerror("Fehler in der Kommunikation mit dem Arduino", e)
return
settings = data.split(';')
for setting, (name, entry) in zip(settings, self.entries):
try:
value = setting.split(':')[1]
except IndexError:
messagebox.showerror("Fehler", "Unerwartete Daten vom Arduino erhalten, Kommunikation überprüfen")
return
if name == "pwm_aktiv":
self.pwm_aktiv.set(int(value))
if "." in value:
float_value = float(value)
if float_value.is_integer():
value = int(float_value)
entry.delete(0, tk.END) #Feld leeren
entry.insert(0, value) #Am Anfang des Feldes wird Value eingegeben
self.settings[name] = value #Werte in settings speichern
#Einstellungen über serielle Verbindung an Arduino senden
def send_arduino_settings(self):
if not self.ser.is_open:
messagebox.showerror("Fehler", "Keine Verbindung zum Arduino")
return
try:
for name, entry in self.entries:
value = entry.get()
if not value.isdigit() and name != "pwm_aktiv":
messagebox.showerror("Fehler", f"Ungültiger Wert für {name}")
return
if name == "pwmFrequency" and not (250 <= float(value) <= 60000):
messagebox.showerror("Fehler", f"Ungültiger Wert für PWM Frequenz. Der Wert muss zwischen 250 und 60000 liegen")
return
if name == "dutyCycle" and not (0 <= int(value) <= 100):
messagebox.showerror("Fehler", f"Ungültiger Wert für Duty Cycle. Der Wert muss zwischen 0 und 100 liegen")
return
command = f"SET {name} {value}"
self.ser.write((command + "\n").encode("utf-8"))
command = f"SET pwm_aktiv {self.pwm_aktiv.get()}"
self.ser.write((command + "\n").encode("utf-8"))
except serial.SerialException as e:
messagebox.showerror("Fehler in der Kommunikation mit dem Arduino", e)
return
def on_closing(self):
if self.ser.is_open:
self.ser.close()
self.root.destroy()
if __name__ == "__main__":
root = tk.Tk()
app = Entry(root)
root.mainloop()