control/Herramientas/Visualizador Aliasing/gui.py
2025-09-03 11:21:53 +02:00

129 lines
3.9 KiB
Python

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()