1

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?

  • Use wx's timer class to call a function periodically that updates the widget. http://wxpython.org/Phoenix/docs/html/TimerEvent.html –  Aug 18 '15 at 05:07
  • Polling will not work (will block), at least with ``pyserial``. – nepix32 Aug 18 '15 at 08:00
  • 1
    A wx.Timer() is the way to go, if you can read a given number of bytes from the serial device. I'd bet that the thermal controller can provide a fixed number of bytes containing the current temperature. So if you can restrict the read to a fixed number of bytes it shouldn't block – Rolf of Saxony Aug 18 '15 at 12:21

2 Answers2

2

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.

Community
  • 1
  • 1
nepix32
  • 3,012
  • 2
  • 14
  • 29
1

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()
Community
  • 1
  • 1
Rolf of Saxony
  • 21,661
  • 5
  • 39
  • 60
  • So the controller i'm using has a funky little protocol. I send it a the string _*01000021\r_ this queries the controller to return current temp(* represents message begin, _010000_ is the actual command to return current temp, _21_ is the checksum, _\r_ ends the command). it returns the following: _*00fa27\r_ where _00fa_ is the hex value(two's compliment) of the current temp, and _27_ is the checksum. – supremus_58 Aug 18 '15 at 13:35
  • Whilst that is indubitably "a funky protocol", I'm not clear on the reason for the comment, with regard to the problem. Unless, you are confirming that you do indeed receive fixed length messages. – Rolf of Saxony Aug 18 '15 at 14:31