[英]How can I write file line-by-line with pyserial to com0com?
I cannot write more than one line of data from a file to a virtual com port (com0com) using pyserial.我不能使用 pyserial 将文件中的多行数据写入虚拟 com 端口(com0com)。 I am attempting to write the file line-by-line so I can simultaneously update a progress bar in Tkinter.
我正在尝试逐行编写文件,以便同时更新 Tkinter 中的进度条。 I am running on Windows and have attempted to put the write operation in its own thread (per UART Controller with Tkinter and Python GUI ).
I am running on Windows and have attempted to put the write operation in its own thread (per UART Controller with Tkinter and Python GUI ). My program hangs after writing one line.
我的程序在写一行后挂起。
Relevant Code:相关代码:
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 Hangs: GUI挂起:
Terminal Output:端子 Output:
1: '@01\r\n'
2: '@02\r\n'
The fact that I'm able to read from program.txt
the second time around in the loop tells me the program might be hanging because the port is still stuck on the first write.我能够在循环中第二次从
program.txt
读取的事实告诉我,程序可能会挂起,因为端口仍然停留在第一次写入上。
Any help would be appreciated.任何帮助,将不胜感激。
Set timeout
and write_timeout
to 0
prevents blocking, which seems to fix the problem.将
timeout
和write_timeout
设置为0
可以防止阻塞,这似乎可以解决问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.