
ich hätte da mal eine Frage. Ich programmiere aktuell eine GUI mit Tkinter. Das ganze läuft auf einem Raspberry Pi 4.
In dieser GUI wird ein Fahrzyklus aus einer Excel Tabelle ausgelesen und in der GUI als Diagramm animiert. An dem Raspberry Pi ist einmal per USB ein OBD2 Adapter angeschlossen und über die GPIO PINS ein Adafruit Ultimate GPS Breakout.
Ich habe also 2-mal die Gleiche GUI, die immer wieder die gleiche Excel animiert abspult und je nach Code einmal die Ermittlung der IST Geschwindigkeit über OBD2 und einmal über GPS. Jetzt sollen Zyklen damit abgefahren werden. Nun habe ich leider 2 Probleme.
Einmal habe ich mit der threading Bibliothek die SOLL Geschwindigkeit anzeigen lassen, oben rechts im Bild(Digital-Anzeige als Hilfestellung). Das gefällt mir aber überhaupt nicht, da es sich mit tkinter beißt. Also er zieht sich separat die Daten der Excel Datei und spult diese parallel ab. Deswegen würde ich gerne eine Funktion erstellen, die immer den X= Wert bei y=0 des Graphen anzeigt. Gibt es da eine Möglichkeit? Habe mich durch mehrere Foren und Videos geklickt, aber nichts in der richtig gefunden.
Der 2. Punkt wäre, dass ich das Diagramm, welches von oben nach unten läuft und animiert ist, gerne fließend animiert hätte. Aktuell ist es so, dass die Sollwerte sich einmal die Sekunde aktualisieren und dadurch das Diagramm springt. Ich hätte gerne eine fließende Animation zwischen den Aktualisierungen.
Frames ändern in einem FuncAnimation hat es leider auch nicht gebracht.
Falls jemand Lösungen oder Ideen hat, wäre ich darüber sehr dankbar.
Mit freundlichen Grüßen
Code: Alles auswählen
import tkinter as tk
import pandas as pd
from matplotlib.animation import FuncAnimation
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import xlrd
import threading
from time import sleep
import obd
df = pd.read_excel('Fahrzyklen.xls', header=None, skiprows=[0])
df.columns = ['Zeit', 'Geschwindigkeit']
workbook = xlrd.open_workbook('Fahrzyklen.xls')
sheet = workbook.sheet_by_index(0)
connection = obd.OBD(portstr='/dev/ttyUSB0', baudrate=38400, protocol="6")
root = tk.Tk()
root.title("Geschwindigkeitsanzeige")
window_width = 1280
window_height = 720
root.geometry(f"{window_width}x{window_height}")
font_size = 16
fig = Figure(figsize=(window_width / 100, window_height / 100))
ax = fig.add_subplot(111)
fig.patch.set_facecolor('black')
ax.set_facecolor('black')
canvas = FigureCanvasTkAgg(fig, master=root)
canvas_widget = canvas.get_tk_widget()
canvas_widget.grid(row=0, column=0, columnspan=2)
soll_label = tk.Label(root, text="SOLL: N/A", font=("Helvetica", font_size), fg="white", bg="black")
soll_label.grid(row=0, column=1, sticky="ne")
ist_arrows = ax.annotate("<", (0, 0), fontsize=font_size, color="white")
def update_soll_label():
row = 1
while True:
soll = sheet.cell_value(row, 1)
soll_label.config(text=f'SOLL: {soll:.1f} km/h')
tol_upper = soll + 2.0
tol_lower = soll - 2.0
tol_upper_line.set_data([tol_upper] * 2, [df['Zeit'].min(), df['Zeit'].max()])
tol_lower_line.set_data([tol_lower] * 2, [df['Zeit'].min(), df['Zeit'].max()])
row += 1
sleep(1)
def init():
ax.set_xlim(0, 150)
ax.set_ylim(-2, 15)
ax.set_xlabel('Geschwindigkeit (km/h)', fontsize=font_size, color='white')
ax.set_ylabel('Zeit (s)', fontsize=font_size, color='white')
ax.set_xticks(range(0, 151, 20))
ax.set_yticks(range(-2, 16, 2))
ax.spines['bottom'].set_color('white')
ax.spines['top'].set_color('white')
ax.spines['right'].set_color('white')
ax.spines['left'].set_color('white')
ax.tick_params(axis='x', labelsize=font_size, colors='white')
ax.tick_params(axis='y', labelsize=font_size, colors='white')
x = df['Geschwindigkeit'].values
y = df['Zeit'].values
line.set_data(x, y)
tol_upper_line.set_data([], [])
tol_lower_line.set_data([], [])
return line, tol_upper_line, tol_lower_line, ist_arrows
def animate(i):
df['Zeit'] = df['Zeit'].apply(lambda x: x - 1)
x = df['Geschwindigkeit'].values
y = df['Zeit'].values
line.set_data(x, y)
ist_speed = read_ist_speed()
ist_arrows.set_text(f"< {ist_speed:.1f} km/h")
ist_arrows.xy = (ist_speed, 0)
ist_arrows.set_x(float(ist_speed))
canvas.draw()
return line, tol_upper_line, tol_lower_line, ist_arrows
def read_ist_speed():
cmd = obd.commands.SPEED
response = connection.query(cmd)
if response.is_null():
return 0.0
return float(response.value.magnitude)
line, = ax.plot([], [], color='blue')
tol_upper_line, = ax.plot([], [], color='green', linestyle='--')
tol_lower_line, = ax.plot([], [], color='red', linestyle='--')
ani = None
update_thread = threading.Thread(target=update_soll_label)
update_thread.daemon = True
def start_animation():
global ani
ani = FuncAnimation(fig, animate, init_func=init, frames=5000, interval=1000, blit=True)
ani.event_source.stop()
update_thread.start()
ani.event_source.start()
start_button.config(state=tk.DISABLED)
start_button = tk.Button(root, text="Start", command=start_animation, font=("Helvetica", font_size), fg="white", bg="green")
start_button.grid(row=0, column=0, sticky="nw", padx=10, pady=10)
root.mainloop()/code]