0

I am triyng to make a graphic interface to interact with my arduino uno, in order to generate graphs of temperature, humidity and weight sensors. I've already managed to generate the animated graphics that update every second, but I'd like them to stay inside the program's window, in their respective places. Is it possible to do that?

Thank you in advance for all your help.

Here is the program code:

import re
import serial
import PySimpleGUI as sg
from itertools import count
import matplotlib.pyplot as plt
from matplotlib.animation import  FuncAnimation
from prettytable import PrettyTable

#Serial arduino
conecao = serial.Serial("COM3", 9600)

#escala dos elementos da janela
scale = 3

#---Elementos do PySimpleGui---
controle = [[sg.Text('Temperatura alvo (C):')],
           [sg.Input(size = (12*scale,1*scale), key = 'setpoint'), sg.Button('Ajustar')],
           [sg.Button('Ligar',size = (12*scale,1*scale))],
           [sg.Button('Desligar',size = (12*scale,1*scale))],
           [sg.Button('Plotar temperatura',size = (12*scale,1*scale))],
           [sg.Button('Plotar peso', size = (12*scale,1*scale))],
           [sg.Button('Plotar umidade',size = (12*scale,1*scale))]]
dados = [[sg.Output(size = (30*scale,7*scale),key = 'output')]]
graf_temperatura = [[sg.Canvas(size = (120*scale,90*scale))]]
graf_massa = [[sg.Canvas(size = (120*scale,90*scale))]]
graf_umidade = [[sg.Canvas(size = (120*scale,90*scale))]]
layout = [[sg.Frame('Controle', controle, vertical_alignment = 't'), sg.Frame('Console', dados, vertical_alignment = 't'), sg.Button('Limpar console')],
          [sg.Frame('Temperatura', graf_temperatura), sg.Frame('Massa', graf_massa), sg.Frame('Umidade', graf_umidade)]]
layout = [[sg.Frame('', layout)]]
janela = sg.Window('Versão 1.0', layout=layout, size=(1200, 700))
#---Elementos do PySimpleGui---

#---Inicialização da janela---
while True:
    event, values = janela.read(timeout = 1000)


    if event == sg.WIN_CLOSED or event == 'Exit':
        break
    leitura = conecao.readline()
    leiturad = leitura.decode()
    var = re.split(',', leiturad)
    pwm = int(var[0])
    x_vals_t = []
    y_vals_t = []
    x_vals_p = []
    y_vals_p = []
    x_vals_u = []
    y_vals_u = []
    index = count()

    def animatet(i):
        leitura = conecao.readline()
        leiturad = leitura.decode()
        var = re.split(',', leiturad)
        temp = float(var[1])
        x_vals_t.append(next(index))
        y_vals_t.append(temp)
        plt.cla()
        plt.plot(x_vals_t, y_vals_t)

    def animatep(i):
        leitura = conecao.readline()
        leiturad = leitura.decode()
        var = re.split(',', leiturad)
        peso = var[2]
        x_vals_p.append(next(index))
        y_vals_p.append(peso)
        plt.cla()
        plt.plot(x_vals_p, y_vals_p)

    def animateu(i):
        leitura = conecao.readline()
        leiturad = leitura.decode()
        var = re.split(',', leiturad)
        um = var[3]
        x_vals_u.append(next(index))
        y_vals_u.append(um)
        plt.cla()
        plt.plot(x_vals_u, y_vals_u)


    if event == 'Ligar':
        conecao.write(b'r')
        if pwm > 0:
            print("O controle já está ligado!")
        else:
            print("O controle foi ligado.")
            janela['Ligar'].update(disabled=True)
            janela['Desligar'].update(disabled=False)

    if event == "Desligar":
        conecao.write(b's')
        print("O controle foi desligado.")
        janela['Ligar'].update(disabled=False)
        janela['Desligar'].update(disabled=True)

    if event == 'Ajustar':
        setpoint = values['setpoint']
        n = 't' + str(setpoint)
        conecao.write(n.encode())
        print('A temperatura  do setpoint foi ajustada para {} graus.'.format(setpoint))

    if event == 'Plotar temperatura':
        plt.style.use('fivethirtyeight')

        anit = FuncAnimation(plt.gcf(), animatet, interval=1000)
        plt.tight_layout()
        plt.show()
        tdados = PrettyTable(['Temperatura(*C)', 'Tempo(s)'])
        tdados.align['Temperatura(*C)'] = 'l'
        tdados.align['Tempo(s)'] = 'r'
        tdados.padding_width = 1
        for i in range(len(y_vals_t)):
            tdados.add_row([y_vals_t[i],x_vals_t[i]])
        print(tdados)

    if event == 'Plotar peso':
        plt.style.use('fivethirtyeight')

        anip = FuncAnimation(plt.gcf(), animatep, interval=1000)
        plt.tight_layout()
        plt.show()
        pdados = PrettyTable(['Peso(g)', 'Tempo(s)'])
        pdados.align['Peso(g)'] = 'l'
        pdados.align['Tempo(s)'] = 'r'
        pdados.padding_width = 1
        for i in range(len(y_vals_p)):
            pdados.add_row([y_vals_p[i], x_vals_p[i]])
        print(pdados)

    if event == 'Plotar umidade':
        plt.style.use('fivethirtyeight')

        aniu = FuncAnimation(plt.gcf(), animateu, interval=1000)
        plt.tight_layout()
        plt.show()
        udados = PrettyTable(['Umidade(%)', 'Tempo(s)'])
        udados.align['Umidade(%)'] = 'l'
        udados.align['Tempo(s)'] = 'r'
        udados.padding_width = 1
        for i in range(len(y_vals_u)):
            udados.add_row([y_vals_u[i], x_vals_u[i]])
        print(udados)

    if event == 'Limpar console':
        janela.FindElement('output').Update('')
  • Refer https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Matplotlib_Animated.py – Jason Yang Jun 28 '21 at 17:07
  • Thanks for the refer, but i still cant plot the graphics. is there a way to plot the graph using matplotlib.animation FuncAnimation library? – Pedro Augusto Boller Jun 30 '21 at 13:43
  • Maybe it can work by using `FuncAnimation` from `matplotlib.animation`, but it looks no one build one way for it at this moment. – Jason Yang Jun 30 '21 at 13:56

0 Answers0