读取串行输入并打印到 Tkinter GUI



我正在尝试为Arduino打印传感器值制作一个基于Tkinter的GUI,并响应用户输入。

我试图用来消除 while 循环的代码是这样的,它不打印任何传感器信息,唯一的输出是"Trying.../dev/ttyACM0",然后是 tkinter 窗口打开。 导入串行 导入时间 从特金特进口 *

connected = False
write_to_file_path = "output.txt"
output_file = open(write_to_file_path, "w+")
locations=['/dev/ttyACM0','/dev/ttyACM1','/dev/ttyACM2','/dev/ttyACM3']
for device in locations:
try:
print "Trying...",device
ser = serial.Serial(device, 9600)
break
except:
print "Failed to connect on",device
## loop until the arduino tells us it is ready
while not connected:
serin = ser.read()
connected = True
time.sleep(0.1)
ser.flushInput()
time.sleep(1)
def serialRead():
if ser.inWaiting():
line = ser.readline()
data = line.decode("utf-8").split('t')
print(data)
output_file.write(line)
root.after(1000, serialRead)

root = Tk()
root.title("Temperature Control")
serialRead()
root.mainloop()

另一方面,除了没有 tkinter 窗口之外,这完美地工作。但它从缓冲区中删除旧输入并读取新输入。

import serial
import time
connected = False
write_to_file_path = "output.txt"
output_file = open(write_to_file_path, "w+")
serial_port = '/dev/ttyACM0'
baud_rate = 9600
ser = serial.Serial(serial_port, baud_rate, timeout=5)
time.sleep(0.1)
ser.flushInput()
time.sleep(1)
while True:
if ser.inWaiting():
line = ser.readline()
data = line.decode("utf-8").split('t') #ser.readline returns a binary, convert to string
print data[0] + 't' + data[1]
output_file.write(line)

这受到不久前另一个堆栈溢出帖子的启发:在 Tkinter 的背景中运行无限循环

我已经看过一些使用线程的例子,但我对python和线程了解不多,所以如果可能的话,我真的很想让它与root.after((一起工作。我也尝试了使用 root.after 的示例,所有这些示例都与我链接的示例非常相似,但我无法让它们中的任何一个工作。我是否做错了什么,或者以一种比它需要的困难得多的方式?如果有人能指出我正确的方向,我将不胜感激。

我在 TK 中制作了一个 UI 用于从 GPS 接收器读取数据,但我很难让 root.mainloop(( 运行,所以我在 TK 应用程序中放置了一个回调,最终调用了 root.update(( 而不是 mainloop。

代码如下所示:

class App:
def __init__(self, master):
self.sats = tk.StringVar()
self.satsnum = tk.Label(self.frame, textvariable=self.sats, bg="blue")
self.satsnum.pack()
def update_display(self, master):
while source:
self.sats.set(n_sats)
if n_sats < 10:
satsbgcolor = 'red'
else:
satsbgcolor = 'green'
self.satsnum.configure(bg = satsbgcolor)
master.update()
time.sleep(1)

with serial_link.get_base_args_driver(args) as driver:
with Handler(Framer(driver.read, driver.write, verbose=True)) as source:
root = tk.Tk()
app = App(root)
app.update_display(root)

注意, time.sleep(1( 在 MacOS 上是必需的,因为如果更新调用得太快,tk.update(( 会泄漏内存。

最新更新