如何为pyserial读取运行线程
Posted
技术标签:
【中文标题】如何为pyserial读取运行线程【英文标题】:how to run thread for pyserial read 【发布时间】:2021-01-31 13:35:13 【问题描述】:我正在尝试创建一个 python 接口来向 arduino 发送帧并从 arduino 接收 can 帧并显示它。对于发送数据它工作正常,但对于接收我有点困惑如何处理它。 我试图创建一个在串行 com 建立后将启动的线程。 我有 2 个问题: 1 /它是创建线程的正确方法吗? 2/ 断开串行连接后如何停止线程运行 here's my GUI with an example of receiving random value from arduino
from tkinter import*
from tkinter import filedialog, Label, Entry, LabelFrame, Button, Tk
from tkinter import ttk
from db_class import up
import serial_tx_rx
from tkinter import messagebox
from diagservices import diag_services
import threading
import serial
import tkinter.scrolledtext as tkscrolledtext
class MainWindow():
def __init__(self, master):
self.master = master
self.title = self.master.title("CanSim")
self.size = self.master.geometry('950x200')
self.baudrate = 9600
self.com_port = ['COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'COM10']
self.isopen = False
self.receivedMessage = None
self.stop_thread = False
self.bConnect = ttk.Button(self.master, text="Connect", command = self.connectSerial)
self.bConnect.place(x=750, y=7)
self.bDisconnect = ttk.Button(self.master, text="Disconnect", command= self.disconnectSerial)
self.bDisconnect.place(x=750, y=30)
self.com_portCmb = ttk.Combobox(self.master, width=8, values =self.com_port )
self.com_portCmb.place(x=830, y=7)
self.Frame = Frame(self.master, bg= 'cyan')
self.Frame.place(x=10, y=30)
self.comStatusLabel = Label(master, text= "Disconnected ", font=("Helvetica", 8, "normal", "italic"))
self.comStatusLabel.place(x=830, y=33)
self.textbox = tkscrolledtext.ScrolledText(self.Frame, wrap='word',font=2, width=55, height=8)
self.textbox.pack(side='bottom', fill='y', expand=True, padx=0, pady=0)
self.textbox.config(font="bold")
self.textbox.yview_pickplace("end")
def connectSerial(self):
try:
self.ser = serial.Serial(self.com_portCmb.get(), self.baudrate)
self.comStatusLabel["text"] = "Connected"
self.isopen =True
self.t1 = threading.Thread(target=self.readSerial)
self.t1.start()
except:
messagebox.showerror("Error : Invalid COM ", "Fail to establish connection with the selected COM Port" )
def disconnectSerial(self):
self.t1.daemon()
self.ser.close()
self.comStatusLabel["text"] = "Disconnected"
def readSerial(self):
if self.isopen:
self.received_data = self.ser.read(2)
self.textbox.insert(END, str(self.received_data)+"\n")
print(self.received_data)
self.textbox.after(100, self.readSerial)
if __name__ == "__main__":
root = Tk()
ex = MainWindow(root)
root.mainloop()
【问题讨论】:
【参考方案1】:您不应在线程任务 (readSerial()
) 中使用 .after()
,而应使用 while 循环:
class MainWindow():
def __init__(self, master):
self.master = master
self.title = self.master.title("CanSim")
self.size = self.master.geometry('950x200')
self.ser = None
...
def disconnectSerial(self):
if self.ser and self.ser.is_open:
#self.t1.daemon() # daemon is an attribute, not function
self.ser.close()
self.comStatusLabel["text"] = "Disconnected"
def readSerial(self):
while self.ser.is_open:
self.received_data = self.ser.read(2)
self.textbox.insert(END, str(self.received_data)+"\n")
print(self.received_data)
【讨论】:
以上是关于如何为pyserial读取运行线程的主要内容,如果未能解决你的问题,请参考以下文章