Reputation: 33
I'm trying to make a program that reads the serial of my arduino and shows the information in real time in a GUI. The problem is that I don't know how to make the data update in real time.
This is my current code:
import re
import serial
import PySimpleGUI as sg
class InterfaceGrafica:
def __init__(self):
layout = [[sg.Text('Interface gráfica para o controle do secador.')],
[sg.Text('Valor do controle PWM:'), sg.Text(Dados().pwm, key = 'pwm')],
[sg.Text('Valor da temperatura: '), sg.Text(Dados().temp, key = 'temp')],
[sg.Text('Peso: '), sg.Text(Dados().peso, key = 'peso')],
[sg.Text('Valor da umidade: '), sg.Text(Dados().um, key = 'um')],
[sg.Text('Temperatura setpoint: '), sg.Text(Dados().set, key = 'set')],
[sg.Button('Exit')]]
self.janela = sg.Window('Versão final', layout=layout, size=(600, 600))
def Iniciar(self):
while True:
self.event, self.values = self.janela.Read()
if self.event == sg.WIN_CLOSED or self.event == 'Exit':
break
conecao = serial.Serial("COM3", 9600)
for i in range(20):
leitura = conecao.readline()
leiturad = leitura.decode()
var = re.split(',', leiturad)
print(leiturad)
self.janela.Element('pwm').Update(values=var[0])
janela.Refresh
self.janela.Element('temp').Update(values=var[1])
self.janela.Element('peso').Update(values=var[2])
self.janela.Element('um').Update(values=var[3])
self.janela.Element('set').Update(values=var[4])
tela = InterfaceGrafica()
tela.Iniciar()
Upvotes: 3
Views: 3985
Reputation: 13061
Using multi-thread, or your GUI will be no respond when your code blocked at reading com port.
Following code not tested for no com port input, so somewhere maybe typo error or something wrong.
import serial # pip install PySerial
import threading
import PySimpleGUI as sg
class GUI:
def __init__(self):
sg.theme('DarkBlue3')
sg.set_options(font=("Courier New", 16))
layout = [
[self.center([[sg.Text('Controller of Dryer', font=("Courier New", 20, 'bold'))]])],
[sg.Text("")],
[sg.Text('PWM '), self.Text('PWM' )],
[sg.Text('TEMPERATURE'), self.Text('TEMP' )],
[sg.Text('WEIGHT '), self.Text('WEIGHT' )],
[sg.Text('MOISTURE '), self.Text('MOISTURE')],
[sg.Text('SETPOINT '), self.Text('SETPOINT')],
[sg.Text("")],
[self.center([[sg.Button('Exit')]])],
]
self.window = sg.Window('Final version', layout=layout, finalize=True)
self.running = True
self.com = serial.Serial("COM3", 9600)
threading.Thread(target=self.get_data, args=(window,), daemon=True).start()
self.start()
def center(self, layout):
return sg.Column(layout, element_justification='center', expand_x=True)
def Text(self, key):
return sg.Text('', size=(20, 1), text_color='white', background_color='blue', key=key)
def get_data(self):
while self.running:
data = com.readline().decode().split(",")
self.window.write_event_value("DATA", data)
def start(self):
while True:
event, values = self.window.read()
if event in (sg.WIN_CLOSED, 'Exit'):
break
elif event == 'DATA':
data = values[event]
self.update(data)
self.running = False
self.window.close()
def update(self, data):
for i, key in enumerate(('PWM', 'TEMP', 'WEIGHT', 'MOISTURE', 'SETPOINT')):
self.window[key].update(value=data[i])
GUI()
Upvotes: 0
Reputation: 2147
You need to set a timeout for self.janela.read( timeout=250 )
I created a fake Dados to test, (which you don't have to use), and it updates.
https://pysimplegui.readthedocs.io/en/latest/
#! /usr/bin/env python3
## pip3 install serial pysimplegui
## Python -m pip install serial pysimplegui
import re
import serial
import random
import PySimpleGUI as sg
class Singleton( object ):
def __new__( cls ):
if not hasattr( cls, 'instance' ):
cls .instance = super( Singleton, cls ) .__new__( cls )
return cls .instance
Dados = Singleton()
def update():
print( 'update' )
Dados .pwm = random .random()
Dados .temp = f'{ random .randint( 50, 100 ) } *F'
Dados .peso = f'$ { random .randint( 1, 30 ) }'
Dados .um = random .randint( 1, 100 )
Dados .set = random .randint( 1, 100 )
class InterfaceGrafica:
def __init__(self):
layout = [ [ sg .Text('Interface gráfica para o controle do secador.') ],
[ sg .Text('Valor do controle PWM:'), sg .Text( Dados .pwm, key='pwm' ) ],
[ sg .Text('Valor da temperatura: '), sg .Text( Dados .temp, key='temp' ) ],
[ sg .Text('Peso: '), sg .Text( Dados .peso, key='peso' ) ],
[ sg .Text('Valor da umidade: '), sg .Text( Dados .um, key='um' ) ],
[ sg .Text('Temperatura setpoint: '), sg .Text( Dados .set, key='set' ) ],
[ sg .Button('Exit') ] ]
self.janela = sg.Window( 'Versão final', layout=layout, size=(400, 300) )
while True:
self.event, self.values = self.janela.read( timeout=250 )
if self.event == sg.WIN_CLOSED or self.event == 'Exit':
break
'''
conecao = serial.Serial("COM3", 9600)
for i in range(20): leitura = conecao.readline() ## read 20 lines from serial
leiturad = leitura.decode() ## decode those 20 lines
var = re.split(',', leiturad) ## split CSV into list
print(var)
'''
self.janela['pwm']( Dados .pwm ) ## var[ 0 ]
self.janela['temp']( Dados .temp ) ## var[ 1 ]
self.janela['peso']( Dados .peso ) ## var[ 2 ]
self.janela['um']( Dados .um ) ## var[ 3 ]
self.janela['set']( Dados .set ) ## var[ 4 ]
self.janela.Refresh()
update()
update()
InterfaceGrafica()
Upvotes: 2