Python 获取从串行到输出到TexCtrl的持续更新
我有一个我用wxPython编写的gui,它作为一个软件控制器工作,变成一个PID类型的热控制器。 我需要从热控制器获得恒定的读数,以一致地输出设备的当前温度 假设我在另一个文件中有此函数:Python 获取从串行到输出到TexCtrl的持续更新,python,python-2.7,wxpython,wxwidgets,Python,Python 2.7,Wxpython,Wxwidgets,我有一个我用wxPython编写的gui,它作为一个软件控制器工作,变成一个PID类型的热控制器。 我需要从热控制器获得恒定的读数,以一致地输出设备的当前温度 假设我在另一个文件中有此函数: def temp_read(): #this function will query a controller, then read the value 我导入该函数,并将其设置为TextCtrl小部件的值: out_current = wx.TextCtrl(self,
def temp_read():
#this function will query a controller, then read the value
我导入该函数,并将其设置为TextCtrl小部件的值:
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
我如何设置它,使其不断输出,同时让gui保持功能,以允许用户设置其余的控制参数(设置温度和其他项目) 您没有指定如何获取串行数据。不过,我想您将使用
pyserial
。读取序列的主要问题是,在下一个字符到达之前,读取序列会阻塞。而且,由于它将立即尝试读取下一个字节(并再次阻塞),GUI将永远不会空闲
因此,本质上,您必须在单独的线程中分离串行读取,并将结果安全地传递回线程
为了读出Arduino,我创建了一个(这也更详细地解释了为什么需要线程)。删除DRS/DTR的线路时,它将适用于任何串行设备
编辑:如果您进一步查看pyserial库并查看
wxPython
示例,它正在使用线程。关于我的评论:这来自pyserial手册:
>>> 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
如果您发现您必须走线程路线,请参阅Fredrik Haard在此处编写的公认答案
他的例子如下:
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()
使用wx的计时器类定期调用更新小部件的函数。轮询将不起作用(将被阻止),至少对于
pyserial
。如果您可以从串行设备读取给定数量的字节,那么wx.Timer()是一种方法。我敢打赌,热控制器可以提供包含当前温度的固定字节数。因此,如果您可以将读取限制为固定的字节数,它就不会阻塞,因此我使用的控制器有一个时髦的小协议。我向它发送一个字符串*01000021\r它查询控制器返回当前温度(*表示消息开始,010000是返回当前温度的实际命令,21是校验和,\r结束命令)。它返回以下内容:*00fa27\r其中00fa是当前temp的十六进制值(两个值的互补),27是校验和。虽然这无疑是一个“时髦的协议”,但关于这个问题,我不清楚评论的原因。除非您确认您确实收到了固定长度的邮件。