Reputation: 57
I have a gui that I've written in wxPython, this is working as a software controller going to a PID type thermal controller. I need to get constant readings from the thermal controller to consistently output the current temperature of the device.
Let's say I have this function in another file:
def temp_read():
#this function will query a controller, then read the value
I import that function, and set it to the value of a TextCtrl widget:
out_current = wx.TextCtrl(self, pos=(250,8), size=(110,23), style=TE_READONLY)
out_temp = temp_read()#get value from function
out_current.SetValue(out_temp)#set value to widget
How do I set this up so that it constantly outputs, while leaving the gui functional to allow for the rest of control parameters(setting temperature and other items) to be set by the user?
Upvotes: 1
Views: 298
Reputation: 3177
You do not specify how you get the serial data. I suppose however you will use pyserial
. The principal problem in reading the serial is that reading it will block until the next character arrives. And because it will immediately try to read the next byte (and block again) the GUI will never become idle.
So essentially you have to spin off the serial reading in a separate thread and communicate the result back thread-safely.
For the purpose of reading out an Arduino I have created a small running example (which also explains in more detail why threading is required). When deleting the line for DRS/DTR, it will apply to any serial device.
EDIT: And if you further look in the pyserial library and look at the wxPython
example, it is using threading.
Upvotes: 2
Reputation: 22448
With regard to my comment:
This is from the pyserial manual:
>>> ser = serial.Serial('/dev/ttyS1', 19200, timeout=1)
>>> x = ser.read() # read one byte
>>> s = ser.read(10) # read up to ten bytes (timeout)
>>> line = ser.readline() # read a '\n' terminated line
>>> ser.close()
>>> ser = serial.Serial(1, 38400, timeout=0,
... parity=serial.PARITY_EVEN, rtscts=1)
>>> s = ser.read(100) # read up to one hundred bytes
... # or as much is in the buffer
If you find that you have to take the Thread route see the accepted answer written by Fredrik Haard here PySerial non-blocking read loop
His quick example is as follows:
import threading
connected = False
port = 'COM4'
baud = 9600
serial_port = serial.Serial(port, baud, timeout=0)
def handle_data(data):
print(data)
def read_from_port(ser):
while not connected:
#serin = ser.read()
connected = True
while True:
print("test")
reading = ser.readline().decode()
handle_data(reading)
thread = threading.Thread(target=read_from_port, args=(serial_port,))
thread.start()
Upvotes: 1