如何使用 pyserial 将文件逐行写入 com0com?
Posted
技术标签:
【中文标题】如何使用 pyserial 将文件逐行写入 com0com?【英文标题】:How can I write file line-by-line with pyserial to com0com? 【发布时间】:2019-10-19 20:31:19 【问题描述】:我不能使用 pyserial 将文件中的多行数据写入虚拟 com 端口 (com0com)。我正在尝试逐行编写文件,以便可以同时更新 Tkinter 中的进度条。我在 Windows 上运行,并试图将写操作放在它自己的线程中(每个UART Controller with Tkinter and Python GUI)。我的程序写完一行就挂了。
相关代码:
import os
import sys
from functools import partial
import re
import time
import threading
import serial
import serial.tools.list_ports
import tkinter as tk
from tkinter import ttk, filedialog
class MainApp(tk.Tk):
def __init__(self,
parent,
title = 'Main Application',
*args,
**kwargs):
self.parent = parent
#Set window title and size
self.parent.title(title)
#Create widget container
container = tk.Frame(self.parent)
#Add widgets
# --> Create load program widgets
load_frame = tk.LabelFrame(container,
text = 'Load Program',
width = 400,
height = 100)
port_dropdown = DropDown(load_frame,
label = 'Port:',
row = 0)
file_browser = Browser(load_frame,
path_type = 'file',
label = 'File:',
row = 1)
program_downloader = Downloader(load_frame,
port_dropdown,
file_browser,
row = 2)
# --> Layout load program widgets
load_frame.grid(row = 0,
column= 0,
padx = (5,5),
pady = (5,5))
#Layout widget container
container.pack(fill = tk.BOTH,
padx = 10,
pady = 5,
expand = True)
.
.
.
class Downloader(tk.Frame):
def __init__(self,
parent,
port_dropdown,
file_browser,
row = 0):
self.port_dropdown = port_dropdown
self.file_browser = file_browser
#Instantiate serial port object
self.serial_port = None
self.progress_bar = ttk.Progressbar(parent,
orient = 'horizontal',
mode = 'determinate')
self.progress_bar.grid(row = row,
column = 0,
columnspan = 2,
padx = (5,5),
pady = (5,5),
sticky = 'WE')
self.button = tk.Button(parent,
text = 'Download',
command = self.download_program)
self.button.grid(row = row,
column = 2,
padx = (5,5),
pady = (5,5),
sticky = 'W')
def download_program(self):
port_full_name = self.port_dropdown.combobox.get()
port_name = re.match('([^\s]+)', port_full_name).group(0)
baud_rate = 9600
program_path = self.file_browser.text.get()
self.connect(port_name,
baud_rate,
program_path)
def connect(self,
port_name,
baud_rate,
program_path):
self.serial_port = serial.Serial(port_name,
baud_rate,
timeout=1)
t1 = threading.Thread(target = self.transfer_data,
args = (program_path,))
t1.daemon = True
t1.start()
def transfer_data(self,
program_path):
line = 1
self.progress_bar['value'] = line
with open(program_path, 'r') as program:
max_lines = len(program.readlines())
self.progress_bar['maximum'] = max_lines
with open(program_path, 'r') as program:
while line < max_lines:
command = program.readline().replace('\n','\r\n')
print(str(line) + ': ' + repr(command))
self.serial_port.write(command.encode('ascii'))
line += 1
self.progress_bar['value'] = line
self.serial_port.flush()
print('done')
self.disconnect()
def disconnect(self):
self.serial_port.close()
if __name__ == '__main__':
#Initialize Tkinter
root = tk.Tk()
#Create GUI
gui = MainApp(root,
'Main Application')
#Run program
root.mainloop()
GUI 挂起:
终端输出:
1: '@01\r\n'
2: '@02\r\n'
我能够在循环中第二次从program.txt
读取的事实告诉我,程序可能会挂起,因为端口仍停留在第一次写入时。
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:将timeout
和write_timeout
设置为0
可以防止阻塞,这似乎可以解决问题。
【讨论】:
以上是关于如何使用 pyserial 将文件逐行写入 com0com?的主要内容,如果未能解决你的问题,请参考以下文章