|
|
@ -1,157 +1,168 @@ |
|
|
|
# -*- coding: utf-8 -*- |
|
|
|
""" |
|
|
|
Created on Wed Feb 15 10:44:49 2023 |
|
|
|
|
|
|
|
@author: david |
|
|
|
""" |
|
|
|
|
|
|
|
from threading import Thread |
|
|
|
import collections #Colección de datos para graficarlos |
|
|
|
import matplotlib.pyplot as plt #Gráficación de datos |
|
|
|
import matplotlib.animation as animation #Animar la gráfica |
|
|
|
import time |
|
|
|
import serial |
|
|
|
#import numpy as np |
|
|
|
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg #Crear una figura para insertar en tkinter |
|
|
|
import tkinter as tk #Para la interfaz |
|
|
|
#from matplotlib.lines import Line2D |
|
|
|
|
|
|
|
|
|
|
|
def leer_datos(): |
|
|
|
time.sleep(1.0) |
|
|
|
arduino.reset_input_buffer() |
|
|
|
print("leyendo") |
|
|
|
while(isRun): |
|
|
|
global isReceiving |
|
|
|
global dato1 |
|
|
|
print("RECIBIENDO...") |
|
|
|
dato1 = float(arduino.readline().decode("utf-8").strip()) |
|
|
|
print(dato1) |
|
|
|
var.set("TEMPERATURA: " + str(dato1) + " °C") |
|
|
|
isReceiving = True |
|
|
|
|
|
|
|
def iniciarGrafica(self, muestras,lines): |
|
|
|
global dato1 |
|
|
|
data.append(dato1) |
|
|
|
lines.set_data(range(muestras), data) |
|
|
|
global isRun |
|
|
|
isReceiving = False |
|
|
|
isRun = True |
|
|
|
dato1 = 0.0 |
|
|
|
serialPort = 'COM3' |
|
|
|
baudRate = 9600 |
|
|
|
|
|
|
|
def conectar_serial(): |
|
|
|
global arduino |
|
|
|
try: |
|
|
|
arduino = serial.Serial(serialPort, baudRate) |
|
|
|
arduino.timeout = 0.5 |
|
|
|
time.sleep(0.5) |
|
|
|
print("CONECTADO") |
|
|
|
btnStart.config(state = "normal") |
|
|
|
btnConectar.config(state = "disabled") |
|
|
|
except: |
|
|
|
print("Error de conexión") |
|
|
|
|
|
|
|
def iniciar_hilo(): |
|
|
|
global thread |
|
|
|
thread = Thread(target=leer_datos) |
|
|
|
thread.start() |
|
|
|
btnStart.config(state = "disabled") |
|
|
|
btnPause.config(state = "normal") |
|
|
|
|
|
|
|
def guardarGrafica(): |
|
|
|
plt.savefig('miFigura.png') |
|
|
|
|
|
|
|
def control1(): |
|
|
|
window2 = tk.Toplevel() |
|
|
|
window2.resizable(width = 0, height = 0) |
|
|
|
window2.title('Control Manual') |
|
|
|
window2.geometry('500x300') |
|
|
|
|
|
|
|
def control2(): |
|
|
|
window3 = tk.Toplevel() |
|
|
|
window3.resizable(width = 0, height = 0) |
|
|
|
window3.title('Control ON/OFF') |
|
|
|
window3.geometry('500x300') |
|
|
|
|
|
|
|
def pausar(): |
|
|
|
anim.event_source.stop() |
|
|
|
btnResume.config(state = "normal") |
|
|
|
btnPause.config(state = "disabled") |
|
|
|
|
|
|
|
def reanudar(): |
|
|
|
anim.event_source.start() |
|
|
|
btnResume.config(state = "disabled") |
|
|
|
btnPause.config(state = "normal") |
|
|
|
|
|
|
|
def desconectar_serial(): |
|
|
|
global isRun |
|
|
|
anim.event_source.stop() |
|
|
|
isRun = False |
|
|
|
arduino.close() |
|
|
|
btnPause.config(state = "disabled") |
|
|
|
btnResume.config(state = "disabled") |
|
|
|
|
|
|
|
|
|
|
|
muestras = 100 |
|
|
|
data = collections.deque([0] * muestras, maxlen = muestras) |
|
|
|
tiempoMuestreo = 100 |
|
|
|
|
|
|
|
fig = plt.figure(facecolor = '0.94') |
|
|
|
ax = plt.axes(xlim=(0,100), ylim=(-40, 150)) |
|
|
|
plt.title("Sensor 1 - Arduino") |
|
|
|
ax.set_xlabel("Muestras") |
|
|
|
ax.set_ylabel("Voltaje") |
|
|
|
lines = ax.plot([], [])[0] |
|
|
|
|
|
|
|
root= tk.Tk() |
|
|
|
root.title("Sistema de calentamiento") |
|
|
|
|
|
|
|
var = tk.StringVar() |
|
|
|
frame = tk.Frame(root, bd=2) |
|
|
|
frame.grid(column=0, row=3, columnspan=2, sticky="nsew") |
|
|
|
frame1 = tk.Frame(root) |
|
|
|
frame1.grid(column=0, row=1, columnspan=2, sticky="EW") |
|
|
|
frame2 = tk.Frame(root) |
|
|
|
frame2.grid(column=0, row=2, columnspan=2, sticky="EW") |
|
|
|
frame0 = tk.Frame(root) |
|
|
|
frame0.grid(column=0, row=0, columnspan=2, sticky="EW") |
|
|
|
|
|
|
|
root.columnconfigure(0, weight=1) |
|
|
|
root.columnconfigure(1, weight=1) |
|
|
|
#self.master.rowconfigure(0, weigh=1) |
|
|
|
#self.master.rowconfigure(1, weigh=1) |
|
|
|
#self.master.rowconfigure(2, weigh=1) |
|
|
|
root.rowconfigure(3, weigh=5) |
|
|
|
|
|
|
|
canvas = FigureCanvasTkAgg(fig, master=frame) |
|
|
|
canvas.get_tk_widget().pack(padx=0, pady=0, expand=True, fill='both') |
|
|
|
btnManual = tk.Button(frame2, text = "Manual", command = control1) |
|
|
|
btnManual.grid(row=0, column=0, pady=2, padx=10) |
|
|
|
btnOnOff = tk.Button(frame2, text = "ON/OFF", command = control2) |
|
|
|
btnOnOff.grid(row=0, column=1, pady=2, padx=10) |
|
|
|
btnConectar = tk.Button(frame1, text = "Connect", command = conectar_serial, bg="#00F1FC") |
|
|
|
btnConectar.grid(row=0, column=0, pady=2, padx=10) |
|
|
|
btnStart = tk.Button(frame1, text = "Start", command = iniciar_hilo, bg="#008C17", state="disabled") |
|
|
|
btnStart.grid(row=0, column=1, pady=2, padx=10) |
|
|
|
btnPause = tk.Button(frame1, text = "Pause", command = pausar, bg="#E2E200", state="disabled") |
|
|
|
btnPause.grid(row=0, column=2, pady=2, padx=10) |
|
|
|
btnResume = tk.Button(frame1, text = "Resume", command = reanudar, bg="#00F428", state="disabled") |
|
|
|
btnResume.grid(row=0, column=3, pady=2, padx=10) |
|
|
|
btnDesconectar = tk.Button(frame2, text='Disconnect', command = desconectar_serial, bg="#FE5E5E") |
|
|
|
btnDesconectar.grid(row=0, column=3, pady=2, padx=10) |
|
|
|
labelData = tk.Label(frame2, textvariable=var) |
|
|
|
labelData.grid(row=0, column=4, pady=2, padx=500) |
|
|
|
|
|
|
|
barraMenu = tk.Menu(frame0) |
|
|
|
barra1 = tk.Menu(barraMenu) |
|
|
|
barra1.add_command(label="Guardar gráfica", command=guardarGrafica) |
|
|
|
barraMenu.add_cascade(label="Archivo", menu=barra1) |
|
|
|
root.config(menu=barraMenu) |
|
|
|
|
|
|
|
anim = animation.FuncAnimation(fig, iniciarGrafica, fargs=(muestras, lines), interval = tiempoMuestreo) |
|
|
|
|
|
|
|
root.geometry('1000x600') |
|
|
|
root.mainloop() |
|
|
|
|
|
|
|
# -*- coding: utf-8 -*- |
|
|
|
""" |
|
|
|
Created on Wed Feb 15 10:44:49 2023 |
|
|
|
|
|
|
|
@author: david |
|
|
|
""" |
|
|
|
|
|
|
|
from threading import Thread #Funciones para hilos |
|
|
|
import collections #Colección de datos para graficarlos |
|
|
|
import matplotlib.pyplot as plt #Gráficación de datos |
|
|
|
import matplotlib.animation as animation #Animar la gráfica |
|
|
|
import time #Delays |
|
|
|
import serial #comunicación con el monitor serial de Arduino |
|
|
|
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg #Crear una figura para insertar en tkinter |
|
|
|
import tkinter as tk #Para la interfaz |
|
|
|
|
|
|
|
#Variables a utilizar |
|
|
|
global isRun #Valor booleano de programa corriendo |
|
|
|
isReceiving = False #Valor booleano de recibiendo datos |
|
|
|
isRun = True |
|
|
|
dato1 = 0.0 #Variable del dato a leer desde Arduino |
|
|
|
serialPort = 'COM3' #Puerto al que está conectado el Arduino |
|
|
|
baudRate = 9600 #Baudios configurados en Arduino |
|
|
|
|
|
|
|
|
|
|
|
#Función de lectura de datos en Arduino |
|
|
|
def leer_datos(): |
|
|
|
time.sleep(1.0) |
|
|
|
arduino.reset_input_buffer() #limpia el buffer de datos |
|
|
|
print("leyendo") |
|
|
|
while(isRun): |
|
|
|
global isReceiving #valor booleano de recibiendo datos |
|
|
|
global dato1 #dato a recibir desde Arduino |
|
|
|
print("RECIBIENDO...") |
|
|
|
dato1 = float(arduino.readline().decode("utf-8").strip()) #Lectura del dato y conversión a float |
|
|
|
print(dato1) |
|
|
|
var.set("TEMPERATURA: " + str(dato1) + " °C") #impresión del dato numérico en la interfaz |
|
|
|
isReceiving = True #Confirmación de que se ha recibido el dato |
|
|
|
|
|
|
|
#Función para iniciar la gráfica |
|
|
|
def iniciarGrafica(self, muestras,lines): |
|
|
|
global dato1 |
|
|
|
data.append(dato1) #Agrega el dato a la colección |
|
|
|
lines.set_data(range(muestras), data) #Se grafica en la línea la colección de datos |
|
|
|
|
|
|
|
#Establecer conexión con Arduino |
|
|
|
def conectar_serial(): |
|
|
|
global arduino #Variable que va aguardar la conexión |
|
|
|
try: |
|
|
|
arduino = serial.Serial(serialPort, baudRate) #Asignación del objeto a la variable |
|
|
|
arduino.timeout = 0.5 #Tiempo a esperar para que haya datos disponibles en el puerto serie |
|
|
|
time.sleep(0.5) #Tiempo muerto para permitir la conexión |
|
|
|
print("CONECTADO") |
|
|
|
btnStart.config(state = "normal") |
|
|
|
btnConectar.config(state = "disabled") |
|
|
|
except: |
|
|
|
print("Error de conexión") |
|
|
|
|
|
|
|
#Hilo para la lectura de datos constante |
|
|
|
def iniciar_hilo(): |
|
|
|
global thread #Variable donde guardar el hilo |
|
|
|
thread = Thread(target=leer_datos) #Creación del hilo con la función para leer los datos |
|
|
|
thread.start() #Inicio de la lectura |
|
|
|
btnStart.config(state = "disabled") |
|
|
|
btnPause.config(state = "normal") |
|
|
|
|
|
|
|
#Pestaña para guardar la gráfica |
|
|
|
def guardarGrafica(): |
|
|
|
plt.savefig('miFigura.png') |
|
|
|
|
|
|
|
#Ventana de control Manual (ON/OFF controlado por el usuario) |
|
|
|
def control1(): |
|
|
|
window2 = tk.Toplevel() |
|
|
|
window2.resizable(width = 0, height = 0) |
|
|
|
window2.title('Control Manual') |
|
|
|
window2.geometry('500x300') |
|
|
|
|
|
|
|
#Ventana para control según una temperatura dada (Automático) |
|
|
|
def control2(): |
|
|
|
window3 = tk.Toplevel() |
|
|
|
window3.resizable(width = 0, height = 0) |
|
|
|
window3.title('Control ON/OFF') |
|
|
|
window3.geometry('500x300') |
|
|
|
|
|
|
|
#Función para pausar la gráfica |
|
|
|
def pausar(): |
|
|
|
anim.event_source.stop() |
|
|
|
btnResume.config(state = "normal") |
|
|
|
btnPause.config(state = "disabled") |
|
|
|
|
|
|
|
#Función para continuar graficando |
|
|
|
def reanudar(): |
|
|
|
anim.event_source.start() |
|
|
|
btnResume.config(state = "disabled") |
|
|
|
btnPause.config(state = "normal") |
|
|
|
|
|
|
|
#Función para finaliar la conexión con Arduino |
|
|
|
def desconectar_serial(): |
|
|
|
global isRun |
|
|
|
anim.event_source.stop() |
|
|
|
isRun = False |
|
|
|
arduino.close() |
|
|
|
btnPause.config(state = "disabled") |
|
|
|
btnResume.config(state = "disabled") |
|
|
|
|
|
|
|
#Variables a graficar |
|
|
|
muestras = 100 #Número de datos a visualizar |
|
|
|
data = collections.deque([0] * muestras, maxlen = muestras) #Rango de datos |
|
|
|
tiempoMuestreo = 100 |
|
|
|
|
|
|
|
fig = plt.figure(facecolor = '0.94') #creación de la gráfica (figura) |
|
|
|
ax = plt.axes(xlim=(0,100), ylim=(-40, 150)) #Rango de ejes |
|
|
|
plt.title("Sensor 1 - Arduino") |
|
|
|
ax.set_xlabel("Muestras") |
|
|
|
ax.set_ylabel("Voltaje") |
|
|
|
lines = ax.plot([], [])[0] #Creación de la línea a graficar |
|
|
|
|
|
|
|
root= tk.Tk() |
|
|
|
root.title("Sistema de calentamiento") |
|
|
|
|
|
|
|
var = tk.StringVar() |
|
|
|
frame = tk.Frame(root, bd=2) |
|
|
|
frame.grid(column=0, row=3, columnspan=2, sticky="nsew") |
|
|
|
frame1 = tk.Frame(root) |
|
|
|
frame1.grid(column=0, row=1, columnspan=2, sticky="EW") |
|
|
|
frame2 = tk.Frame(root) |
|
|
|
frame2.grid(column=0, row=2, columnspan=2, sticky="EW") |
|
|
|
frame0 = tk.Frame(root) |
|
|
|
frame0.grid(column=0, row=0, columnspan=2, sticky="EW") |
|
|
|
|
|
|
|
root.columnconfigure(0, weight=1) |
|
|
|
root.columnconfigure(1, weight=1) |
|
|
|
#self.master.rowconfigure(0, weigh=1) |
|
|
|
#self.master.rowconfigure(1, weigh=1) |
|
|
|
#self.master.rowconfigure(2, weigh=1) |
|
|
|
root.rowconfigure(3, weigh=5) |
|
|
|
|
|
|
|
canvas = FigureCanvasTkAgg(fig, master=frame) |
|
|
|
canvas.get_tk_widget().pack(padx=0, pady=0, expand=True, fill='both') |
|
|
|
btnManual = tk.Button(frame2, text = "Manual", command = control1) |
|
|
|
btnManual.grid(row=0, column=0, pady=2, padx=10) |
|
|
|
btnOnOff = tk.Button(frame2, text = "ON/OFF", command = control2) |
|
|
|
btnOnOff.grid(row=0, column=1, pady=2, padx=10) |
|
|
|
btnConectar = tk.Button(frame1, text = "Connect", command = conectar_serial, bg="#00F1FC") |
|
|
|
btnConectar.grid(row=0, column=0, pady=2, padx=10) |
|
|
|
btnStart = tk.Button(frame1, text = "Start", command = iniciar_hilo, bg="#008C17", state="disabled") |
|
|
|
btnStart.grid(row=0, column=1, pady=2, padx=10) |
|
|
|
btnPause = tk.Button(frame1, text = "Pause", command = pausar, bg="#E2E200", state="disabled") |
|
|
|
btnPause.grid(row=0, column=2, pady=2, padx=10) |
|
|
|
btnResume = tk.Button(frame1, text = "Resume", command = reanudar, bg="#00F428", state="disabled") |
|
|
|
btnResume.grid(row=0, column=3, pady=2, padx=10) |
|
|
|
btnDesconectar = tk.Button(frame2, text='Disconnect', command = desconectar_serial, bg="#FE5E5E") |
|
|
|
btnDesconectar.grid(row=0, column=3, pady=2, padx=10) |
|
|
|
labelData = tk.Label(frame2, textvariable=var) |
|
|
|
labelData.grid(row=0, column=4, pady=2, padx=500) |
|
|
|
|
|
|
|
barraMenu = tk.Menu(frame0) |
|
|
|
barra1 = tk.Menu(barraMenu) |
|
|
|
barra1.add_command(label="Guardar gráfica", command=guardarGrafica) |
|
|
|
barraMenu.add_cascade(label="Archivo", menu=barra1) |
|
|
|
root.config(menu=barraMenu) |
|
|
|
|
|
|
|
#Animación de la gráfica (figura, función que grafica la línea, argumentos para graficar, rango de la figura) |
|
|
|
anim = animation.FuncAnimation(fig, iniciarGrafica, fargs=(muestras, lines), interval = tiempoMuestreo) |
|
|
|
|
|
|
|
root.geometry('1000x600') |
|
|
|
root.mainloop() |
|
|
|
|