import tkinter as tk from tkinter import ttk import numpy as np from scipy import signal import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg # Función para graficar def actualizar_grafico(*args): try: n_motor = rpm_var.get() cpr = int(entry_cpr.get()) fSampleo = float(entry_fs.get()) desfase = float(entry_desfase.get()) numCiclos = float(entry_ciclos.get()) except ValueError: return fEncoder = n_motor * cpr / 60 samples = 1000 if fEncoder == 0: ax.clear() ax.set_title("RPM = 0, no hay señal.") canvas.draw() return t = np.linspace(0, numCiclos / fEncoder, samples, endpoint=False) desfase_rad = desfase * np.pi / 180 ChnA = signal.square(2 * np.pi * fEncoder * t + desfase_rad) ChnB = signal.square(2 * np.pi * fEncoder * t + desfase_rad - np.pi/2) periodo = 1 / fSampleo puntos_verticales = np.arange(0, numCiclos / fEncoder, periodo) ax.clear() if var_sampleo.get(): for x in puntos_verticales: ax.axvline(x=x, color='red', linestyle='--', linewidth=1.2) if var_chnA.get(): ax.plot(t, ChnA, label='Canal A') if var_chnB.get(): ax.plot(t, ChnB, label='Canal B') ax.set_title(f"RPM={n_motor}, CPR={cpr}, fs={fSampleo/1000:.1f}kHz, desfase={desfase}°, ciclos={numCiclos}") ax.set_xlabel("Tiempo [s]") ax.set_ylabel("Amplitud") ax.legend() canvas.draw() # Crear ventana principal root = tk.Tk() root.title("Visualizador de Encoder y Sampleo") # Frame izquierdo con padding frame = ttk.Frame(root, padding=10) frame.pack(side=tk.LEFT, fill=tk.Y) font = ("Arial", 11) # Slider de RPM con paso de 10 ttk.Label(frame, text="RPM:", font=font).pack(anchor="w", pady=5) rpm_var = tk.DoubleVar(value=100) def actualizar_rpm_label(val): val = float(val) stepped_val = round(val / 10) * 10 rpm_var.set(stepped_val) label_rpm_val.config(text=f"{stepped_val:.0f}") actualizar_grafico() slider_rpm = ttk.Scale(frame, from_=10, to=3000, orient='horizontal', variable=rpm_var, command=actualizar_rpm_label) slider_rpm.pack(fill=tk.X, pady=2) label_rpm_val = ttk.Label(frame, text="100", font=font) label_rpm_val.pack(pady=(0, 10)) # Entrada CPR ttk.Label(frame, text="CPR:", font=font).pack(anchor="w", pady=5) entry_cpr = ttk.Entry(frame, font=font) entry_cpr.insert(0, "500") entry_cpr.pack(fill=tk.X) # Entrada Frecuencia de sampleo ttk.Label(frame, text="Frecuencia de sampleo (Hz):", font=font).pack(anchor="w", pady=5) entry_fs = ttk.Entry(frame, font=font) entry_fs.insert(0, "25000") entry_fs.pack(fill=tk.X) # Entrada Desfase ttk.Label(frame, text="Desfase (grados):", font=font).pack(anchor="w", pady=5) entry_desfase = ttk.Entry(frame, font=font) entry_desfase.insert(0, "0") entry_desfase.pack(fill=tk.X) # Entrada Número de ciclos ttk.Label(frame, text="Número de ciclos:", font=font).pack(anchor="w", pady=5) entry_ciclos = ttk.Entry(frame, font=font) entry_ciclos.insert(0, "3") entry_ciclos.pack(fill=tk.X) # Checkboxes var_chnA = tk.BooleanVar(value=True) chk_chnA = ttk.Checkbutton(frame, text="Mostrar Canal A", variable=var_chnA, command=actualizar_grafico) chk_chnA.pack(anchor="w", pady=5) var_chnB = tk.BooleanVar(value=True) chk_chnB = ttk.Checkbutton(frame, text="Mostrar Canal B", variable=var_chnB, command=actualizar_grafico) chk_chnB.pack(anchor="w", pady=5) var_sampleo = tk.BooleanVar(value=True) chk_sampleo = ttk.Checkbutton(frame, text="Mostrar líneas de sampleo", variable=var_sampleo, command=actualizar_grafico) chk_sampleo.pack(anchor="w", pady=5) # Botón actualizar ttk.Button(frame, text="Actualizar", command=actualizar_grafico).pack(pady=15) # Canvas matplotlib fig, ax = plt.subplots(figsize=(8.8, 4.4)) # Aumentado un 10% canvas = FigureCanvasTkAgg(fig, master=root) canvas.get_tk_widget().pack(side=tk.RIGHT, fill=tk.BOTH, expand=True) # Inicializar actualizar_grafico() root.mainloop()