163 lines
6.2 KiB
Python
163 lines
6.2 KiB
Python
|
#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()
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|