【问题标题】:python code for serial data to print on window.用于在窗口上打印串行数据的 python 代码。
【发布时间】:2013-06-05 11:24:05
【问题描述】:

我对 python 和 pyserial 还是很陌生。我的电脑安装了带有 pyserial 的 python 2.7.4,我想在我的电脑上的单独窗口上打印串行接收的数据。首先必须打开窗口,然后在该窗口上打印串行数据。这里窗口必须打开一次,串行数据必须连续打印在窗口上,直到设备停止传输数据。 我尝试使用此代码,但它毫无价值。 请有人帮我写代码。

import serial
import Tkinter
from Tkinter import *
s = serial.Serial('COM10',9600)    # open serial port
master = Tk()
master.geometry("1360x750")        # a window pop up with width (1360) and height(750)     which exatly fits my monitor screen..

while 1:
if s.inWaiting():
text = s.readline(s.inWaiting())
frameLabel = Frame( master, padx=40, pady =40)
frameLabel.pack()
w = Text( frameLabel, wrap='word', font="TimesNewRoman 37")
w.insert(12.0,text )
w.pack()
w.configure( bg=master.cget('bg'), relief='flat', state='Normal' )

mainloop()

【问题讨论】:

  • 您可能会查看此答案的第一部分 stackoverflow.com/a/14040516 。它展示了如何在 tkinter 循环中重复调用函数。这基本上是您想要做的,而不是 while True 循环。
  • 非常感谢您的快速答复。我将尝试使用 tkinter 循环中的函数。

标签: python-2.7 tkinter pyserial


【解决方案1】:

这里的问题是您有两个循环应该不断运行:GUI 的主循环和传输串行数据的循环。解决这个问题的方法是启动一个新线程来接收串口的内容,将其放入Queue,并在GUI线程中定期检查该队列的内容:

import serial
import threading
import time
import Queue
import Tkinter as tk


class SerialThread(threading.Thread):
    def __init__(self, queue):
        threading.Thread.__init__(self)
        self.queue = queue
    def run(self):
        s = serial.Serial('/dev/ttyS0',9600)
        s.write(str.encode('*00T%'))
        time.sleep(0.2)
        while True:
            if s.inWaiting():
                text = s.readline(s.inWaiting())
                self.queue.put(text)

class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.geometry("1360x750")
        frameLabel = tk.Frame(self, padx=40, pady =40)
        self.text = tk.Text(frameLabel, wrap='word', font='TimesNewRoman 37',
                            bg=self.cget('bg'), relief='flat')
        frameLabel.pack()
        self.text.pack()
        self.queue = Queue.Queue()
        thread = SerialThread(self.queue)
        thread.start()
        self.process_serial()

    def process_serial(self):
        value=True
        while self.queue.qsize():
            try:
                new=self.queue.get()
                if value:
                 self.text.delete(1.0, 'end')
                value=False
                 self.text.insert('end',new)
            except Queue.Empty:
                pass
        self.after(100, self.process_serial)

app = App()
app.mainloop()

这段代码是用我的 Pi3 ttyS0 串口和串口连接的 PC 和从设备测试的: 它 100% 使用串行连接的单个设备

【讨论】:

  • 串行对象不是提供了类似队列的api,因此足以用作队列吗?换句话说,检查inWaiting() 并直接从process_serial 循环读取就足够了吗?
  • @FabienAndre 问题不是从串口读取,而是您同时运行两个循环。队列(结合after方法)是在不冻结 GUI 的情况下通信两个线程的安全方式。
  • 我完全同意队列是处理两个线程的正确方式。我的问题是,在这种情况下,是否需要(以及为什么)使用第二个线程而不是从 Tkinter after loop 读取序列。作为一个更明确的尝试,为什么不将queue.qsize check 替换为serial.inWaiting 并将queue.get 替换为serial.read
  • @FabienAndre 您也可以这样做,但是每隔 100 毫秒会定期检索信息(因此除了 Tkinter 主循环之外,您没有任何循环),而使用另一种方法内容在发送的同时被读取。
  • 现在我正在接收打印在我的电脑屏幕上的串行数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多