读取串行输入并打印到 Tkinter GUI [英] Reading serial input and printing to Tkinter GUI

查看:55
本文介绍了读取串行输入并打印到 Tkinter GUI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to make a Tkinter based GUI for an Arduino printing sensors value and responding to user input.

我试图用来消除 while 循环的代码是这样的,它不打印任何传感器信息,唯一的输出是正在尝试.../dev/ttyACM0",然后是 tkinter 窗口打开.导入序列导入时间从 Tkinter 导入 *

The code I'm trying to use to eliminate while loops is this, which doesn't print any sensor information, the only output is "Trying.../dev/ttyACM0" followed by the tkinter window opening. import serial import time from Tkinter import *

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 窗口之外,它可以完美运行.但它会从缓冲区中删除旧输入并读入新输入.

This, on the other hand, works perfectly with the exception of not having a tkinter window. But it removes old input from the buffer and reads in the new input.

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)

这受到了不久前不同的 stackoverflow 帖子的启发:在 Tkinter 的后台运行无限循环

This was inspired by a different stackoverflow post from a while ago: Run an infinite loop in the backgroung in Tkinter

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

I've seen some example using threading but I don't know much about python nor threading so I'd really like to get it to work with root.after() if that's possible. I've also tried the example using root.after, all of which are pretty similar to the one I linked, and I couldn't get any of them working. Am I doing anything obviously wrong or in a way that's much more difficult than it needs to be? I would appreciate it greatly if someone would point me in the right direction.

推荐答案

我在 TK 中制作了一个 UI 来从 GPS 接收器读取数据,但我在运行 root.mainloop() 时遇到了困难,所以我在里面放了一个回调最终调用 root.update() 而不是 mainloop 的 TK 应用程序.

I made a UI in TK for reading data from a GPS receiver and I had difficulties getting root.mainloop() to run, so instead I put a callback inside the TK app that ends up calling root.update() rather than 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)

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

Note, the time.sleep(1) is necessary on MacOS as tk.update() will leak memory if the update is called too fast.

这篇关于读取串行输入并打印到 Tkinter GUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆