串口调试工具(Python2.7+pyserial+Tkinter)
需要与串口设备进行通讯,那么一个调试工具是必须的。
根据我自己的需要,写了个简易版本的串口调试工具:
预览图:
======================
项目结构:
COM
--SerialHelper.py
UI
--Adaptive.py
--SerialTool.py
--PyTkinter.py
main.py
======================
COM文件夹
SerialHelper.py 串口通讯帮助类
#! /usr/bin/env python
# -*- coding: utf-8 -*- '''
Serial设备通讯帮助类
'''
__author__ = "jakey.chen"
__version__ = "v1.0" import sys
import threading
import time
import serial
import binascii
import logging class SerialHelper(object):
def __init__(self, Port="COM6", BaudRate="", ByteSize="", Parity="N", Stopbits=""):
'''
初始化一些参数
'''
self.l_serial = None
self.alive = False
self.port = Port
self.baudrate = BaudRate
self.bytesize = ByteSize
self.parity = Parity
self.stopbits = Stopbits
self.thresholdValue = 64
self.receive_data = "" def start(self):
'''
开始,打开串口
'''
self.l_serial = serial.Serial()
self.l_serial.port = self.port
self.l_serial.baudrate = self.baudrate
self.l_serial.bytesize = int(self.bytesize)
self.l_serial.parity = self.parity
self.l_serial.stopbits = int(self.stopbits)
self.l_serial.timeout = 2 try:
self.l_serial.open()
if self.l_serial.isOpen():
self.alive = True
except Exception as e:
self.alive = False
logging.error(e) def stop(self):
'''
结束,关闭串口
'''
self.alive = False
if self.l_serial.isOpen():
self.l_serial.close() def read(self):
'''
循环读取串口发送的数据
'''
while self.alive:
try:
number = self.l_serial.inWaiting()
if number:
self.receive_data += self.l_serial.read(number).replace(binascii.unhexlify(""), "")
if self.thresholdValue <= len(self.receive_data):
self.receive_data = ""
except Exception as e:
logging.error(e) def write(self, data, isHex=False):
'''
发送数据给串口设备
'''
if self.alive:
if self.l_serial.isOpen():
if isHex:
# data = data.replace(" ", "").replace("\n", "")
data = binascii.unhexlify(data)
self.l_serial.write(data) if __name__ == '__main__':
import threading
ser = SerialHelper()
ser.start() ser.write("", isHex=False)
thread_read = threading.Thread(target=ser.read)
thread_read.setDaemon(True)
thread_read.start()
import time
time.sleep(25)
ser.stop()
======================
UI文件夹
Adaptive.py 防止错位
#! /usr/bin/env python
# -*- coding: utf-8 -*- import platform g_systemName = platform.system()
g_systemInfo = platform.platform()
g_pyVersion = platform.python_version()
size_dict = dict() # System will be Linux and python == 2.7
if g_systemName == "Linux" and g_pyVersion[:3] == "2.7":
if "Ubuntu" in g_systemInfo:
size_dict = {
"list_box_height": 20,
"send_text_height": 12,
"receive_text_height": 15,
"reset_label_width": 24,
"clear_label_width": 22
} # raspberry pi
elif "armv6l" in g_systemInfo:
size_dict = {
"list_box_height": 19,
"send_text_height": 12,
"receive_text_height": 15,
"reset_label_width": 24,
"clear_label_width": 22
}
else:
if g_systemInfo[:9]== "Windows-8":
size_dict = {
"list_box_height": 14,
"send_text_height": 6,
"receive_text_height": 18,
"reset_label_width": 7,
"clear_label_width": 5
} elif g_systemInfo[:9]== "Windows-7":
size_dict = {
"list_box_height": 13,
"send_text_height": 12,
"receive_text_height": 15,
"reset_label_width": 7,
"clear_label_width": 5
} elif g_systemInfo[:10]== "Windows-XP":
size_dict = {
"list_box_height": 20,
"send_text_height": 12,
"receive_text_height": 22,
"reset_label_width": 7,
"clear_label_width": 5
} # font
monaco_font = ('Monaco', 12)
PyTkinter.py 根据个人喜好来初始化一些Tkinter控件的颜色配置
#! /usr/bin/env python
# -*- coding: utf-8 -*- '''
Tkinter控件初始化配置(默认为深色)
'''
__author__ = "jakey.chen"
__version__ = "v1.0" import Tkinter as tk g_default_theme = "dark"
# g_default_theme = "default" class PyButton(tk.Button):
'''
Button
'''
def __init__(self, master, theme=g_default_theme, **kv):
self.theme = theme
self.kv = kv
self.temp = dict()
self.choose_theme()
tk.Button.__init__(self, master, self.temp) def choose_theme(self):
if self.theme == "dark":
dark_theme_dict = {
"activebackground": "#00B2EE",
"activeforeground": "#E0EEEE",
"bg": "#008B8B",
"fg": "#FFFFFF"
}
for key,value in dark_theme_dict.items():
self.temp[key] = value for key,value in self.kv.items():
self.temp[key] = value class PyLabel(tk.Label):
'''
Label
'''
def __init__(self, master, theme=g_default_theme, **kv):
self.theme = theme
self.kv = kv
self.temp = dict()
self.choose_theme()
tk.Label.__init__(self, master, self.temp) def choose_theme(self):
if self.theme == "dark":
dark_theme_dict = {
"bg": "#292929",
"fg": "#E0EEEE"
}
for key,value in dark_theme_dict.items():
self.temp[key] = value for key,value in self.kv.items():
self.temp[key] = value class PyLabelFrame(tk.LabelFrame):
'''
Frame
'''
def __init__(self, master, theme=g_default_theme, **kv):
self.theme = theme
self.kv = kv
self.temp = dict()
self.choose_theme()
tk.LabelFrame.__init__(self, master, self.temp) def choose_theme(self):
if self.theme == "dark":
dark_theme_dict = {
"bg": "#292929",
"fg": "#1E90FF"
}
for key,value in dark_theme_dict.items():
self.temp[key] = value for key,value in self.kv.items():
self.temp[key] = value class PyListbox(tk.Listbox):
'''
Listbox
'''
def __init__(self, master, theme=g_default_theme, **kv):
self.theme = theme
self.kv = kv
self.temp = dict()
self.choose_theme()
tk.Listbox.__init__(self, master, self.temp) def choose_theme(self):
if self.theme == "dark":
dark_theme_dict = {
"bg": "#292929",
"fg": "#1E90FF",
"selectbackground": "#00B2EE"
}
for key,value in dark_theme_dict.items():
self.temp[key] = value for key,value in self.kv.items():
self.temp[key] = value class PyText(tk.Text):
'''
Text
'''
def __init__(self, master, theme=g_default_theme, **kv):
self.theme = theme
self.kv = kv
self.temp = dict()
self.choose_theme()
tk.Text.__init__(self, master, self.temp) def choose_theme(self):
if self.theme == "dark":
dark_theme_dict = {
"bg": "#292929",
"fg": "#1E90FF"
}
for key,value in dark_theme_dict.items():
self.temp[key] = value for key,value in self.kv.items():
self.temp[key] = value class PyCheckbutton(tk.Checkbutton):
'''
Checkbutton
'''
def __init__(self, master, theme=g_default_theme, **kv):
self.theme = theme
self.kv = kv
self.temp = dict()
self.choose_theme()
tk.Checkbutton.__init__(self, master, self.temp) def choose_theme(self):
if self.theme == "dark":
dark_theme_dict = {
"bg": "#292929",
"fg": "#FFFFFF",
"activebackground": "#292929",
"activeforeground": "#FFFFFF",
"selectcolor": "#292929"
}
for key,value in dark_theme_dict.items():
self.temp[key] = value for key,value in self.kv.items():
self.temp[key] = value class PyRadiobutton(tk.Radiobutton):
'''
Radiobutton
'''
def __init__(self, master, theme=g_default_theme, **kv):
self.theme = theme
self.kv = kv
self.temp = dict()
self.choose_theme()
tk.Radiobutton.__init__(self, master, self.temp) def choose_theme(self):
if self.theme == "dark":
dark_theme_dict = {
"bg": "#292929",
"fg": "#FFFFFF",
"activebackground": "#292929",
"selectcolor": "#292929"
}
for key,value in dark_theme_dict.items():
self.temp[key] = value for key,value in self.kv.items():
self.temp[key] = value class PyEntry(tk.Entry):
'''
Entry
'''
def __init__(self, master, theme=g_default_theme, **kv):
self.theme = theme
self.kv = kv
self.temp = dict()
self.choose_theme()
tk.Entry.__init__(self, master, self.temp) def choose_theme(self):
if self.theme == "dark":
dark_theme_dict = {
"bg": "#292929",
"fg": "#E0EEEE",
"insertbackground": "#E0EEEE"
}
for key,value in dark_theme_dict.items():
self.temp[key] = value for key,value in self.kv.items():
self.temp[key] = value if __name__ == '__main__':
root = tk.Tk()
root.configure(bg="#292929")
PyButton(root, text="", font=("Monaco", 12)).pack()
PyLabel(root, text="", font=("Monaco", 15)).pack()
PyCheckbutton(root, text="", font=("Monaco", 15)).pack()
PyEntry(root, font=("Monaco", 15)).pack()
PyText(root, font=("Monaco", 15), height=2, width=20).pack()
listbox_0 = PyListbox(root, height=2, font=("Monaco", 15))
listbox_0.pack()
for i in range(2):
listbox_0.insert("end", i)
radio_intvar = tk.IntVar()
PyRadiobutton(root, text="", variable=radio_intvar, value=0, font=("Monaco", 15)).pack()
PyRadiobutton(root, text="", variable=radio_intvar, value=1, font=("Monaco", 15)).pack()
radio_intvar.set(1) root.mainloop()
SerialTool.py 主界面
#! /usr/bin/env python
# -*- coding: utf-8 -*- import Tkinter as tk
import ttk
import PyTkinter as pytk
import Adaptive font = Adaptive.monaco_font
size_dict = Adaptive.size_dict
g_default_theme = pytk.g_default_theme class SerialToolUI(object):
def __init__(self, master=None):
self.root = master
self.create_frame()
self.thresholdValue = 1 def create_frame(self):
'''
新建窗口,分为上下2个部分,下半部分为状态栏
'''
self.frm = pytk.PyLabelFrame(self.root)
self.frm_status = pytk.PyLabelFrame(self.root) self.frm.grid(row=0, column=0, sticky="wesn")
self.frm_status.grid(row=1, column=0, sticky="wesn") self.create_frm()
self.create_frm_status() def create_frm(self):
'''
上半部分窗口分为左右2个部分
'''
self.frm_left = pytk.PyLabelFrame(self.frm)
self.frm_right = pytk.PyLabelFrame(self.frm) self.frm_left.grid(row=0, column=0, padx=5, pady=5, sticky="wesn")
self.frm_right.grid(row=0, column=1, padx=5, pady=5, sticky="wesn") self.create_frm_left()
self.create_frm_right() def create_frm_left(self):
'''
上半部分左边窗口:
Listbox显示可用的COM口
Button按钮点击连接设备
'''
self.frm_left_label = pytk.PyLabel(self.frm_left,
text="Serial Ports",
font=font)
self.frm_left_listbox = pytk.PyListbox(self.frm_left,
height=size_dict["list_box_height"],
font=font)
self.frm_left_serial_set = pytk.PyLabelFrame(self.frm_left)
self.frm_left_btn = pytk.PyButton(self.frm_left,
text="Open",
font=font,
command=self.Toggle) self.frm_left_label.grid(row=0, column=0, padx=5, pady=5, sticky="w")
self.frm_left_listbox.grid(row=1, column=0, padx=5, pady=5, sticky="wesn")
self.frm_left_serial_set.grid(row=2, column=0, padx=5, pady=5, sticky="wesn")
self.frm_left_btn.grid(row=3, column=0, padx=5, pady=5, sticky="wesn") self.frm_left_listbox.bind("<Double-Button-1>", self.Open)
self.create_frm_left_serial_set() def create_frm_left_serial_set(self):
'''
串口配置,比如波特率,奇偶校验等
'''
setting_label_list = ["BaudRate :", "Parity :", "DataBit :", "StopBit :"]
baudrate_list = ["", "", "", "", "", "", "",
"", "", "", "", ""]
# PARITY_NONE, PARITY_EVEN, PARITY_ODD PARITY_MARK, PARITY_SPACE
parity_list = ["N", "E", "O", "M", "S"]
bytesize_list = ["", "", "", ""]
stopbits_list = ["", "1.5", ""]
for index,item in enumerate(setting_label_list):
frm_left_label_temp = pytk.PyLabel(self.frm_left_serial_set,
text=item,
font=('Monaco', 10))
frm_left_label_temp.grid(row=index, column=0, padx=1, pady=2, sticky="e")
self.frm_left_combobox_baudrate = ttk.Combobox(self.frm_left_serial_set,
width=15,
values=baudrate_list)
self.frm_left_combobox_parity = ttk.Combobox(self.frm_left_serial_set,
width=15,
values=parity_list)
self.frm_left_combobox_databit = ttk.Combobox(self.frm_left_serial_set,
width=15,
values=bytesize_list)
self.frm_left_combobox_stopbit = ttk.Combobox(self.frm_left_serial_set,
width=15,
values=stopbits_list)
self.frm_left_combobox_baudrate.grid(row=0, column=1, padx=2, pady=2, sticky="e")
self.frm_left_combobox_parity.grid(row=1, column=1, padx=2, pady=2, sticky="e")
self.frm_left_combobox_databit.grid(row=2, column=1, padx=2, pady=2, sticky="e")
self.frm_left_combobox_stopbit.grid(row=3, column=1, padx=2, pady=2, sticky="e") self.frm_left_combobox_baudrate.current(3)
self.frm_left_combobox_parity.current(0)
self.frm_left_combobox_databit.current(3)
self.frm_left_combobox_stopbit.current(0) def create_frm_right(self):
'''
上半部分右边窗口:
分为4个部分:
1、Label显示和重置按钮和发送按钮
2、Text显示(发送的数据)
3、Label显示和十六进制选择显示和清除接收信息按钮
4、Text显示接收到的信息
'''
self.frm_right_reset = pytk.PyLabelFrame(self.frm_right)
self.frm_right_send = pytk.PyText(self.frm_right,
width=50,
height=size_dict["send_text_height"],
font=("Monaco", 9))
self.frm_right_clear = pytk.PyLabelFrame(self.frm_right)
self.frm_right_receive = pytk.PyText(self.frm_right,
width=50,
height=size_dict["receive_text_height"],
font=("Monaco", 9)) self.frm_right_reset.grid(row=0, column=0, padx=1, sticky="wesn")
self.frm_right_send.grid(row=1, column=0, padx=1, sticky="wesn")
self.frm_right_clear.grid(row=2, column=0, padx=1, sticky="wesn")
self.frm_right_receive.grid(row=3, column=0, padx=1, sticky="wesn") self.frm_right_receive.tag_config("green", foreground="#228B22") self.create_frm_right_reset()
self.create_frm_right_clear() def create_frm_right_reset(self):
'''
1、Label显示和重置按钮和发送按钮
'''
self.frm_right_reset_label = pytk.PyLabel(self.frm_right_reset,
text="Data Send" + " "*size_dict["reset_label_width"],
font=font)
self.new_line_cbtn_var = tk.IntVar()
self.send_hex_cbtn_var = tk.IntVar()
self.frm_right_reset_newLine_checkbtn = pytk.PyCheckbutton(self.frm_right_reset,
text="New Line",
variable=self.new_line_cbtn_var,
font=font)
self.frm_right_reset_hex_checkbtn = pytk.PyCheckbutton(self.frm_right_reset,
text="Hex",
variable=self.send_hex_cbtn_var,
font=font)
self.frm_right_reset_btn = pytk.PyButton(self.frm_right_reset,
text="Reset",
width=10,
font=font,
command=self.Reset)
self.frm_right_send_btn = pytk.PyButton(self.frm_right_reset,
text="Send",
width=10,
font=font,
command=self.Send) self.frm_right_reset_label.grid(row=0, column=0, sticky="w")
self.frm_right_reset_newLine_checkbtn.grid(row=0, column=1, sticky="wesn")
self.frm_right_reset_hex_checkbtn.grid(row=0, column=2, sticky="wesn")
self.frm_right_reset_btn.grid(row=0, column=3, padx=5, pady=5, sticky="wesn")
self.frm_right_send_btn.grid(row=0, column=4, padx=5, pady=5, sticky="wesn") def create_frm_right_clear(self):
'''
3、Label显示和十六进制显示和清除接收信息按钮
'''
self.receive_hex_cbtn_var = tk.IntVar()
self.frm_right_clear_label = pytk.PyLabel(self.frm_right_clear,
text="Data Received"+ " "*size_dict["clear_label_width"],
font=font)
self.frm_right_threshold_label = pytk.PyLabel(self.frm_right_clear,
text="Threshold:",
font=font)
self.thresholdStr = tk.StringVar()
self.frm_right_threshold_entry = pytk.PyEntry(self.frm_right_clear,
textvariable=self.thresholdStr,
width=6,
font=font)
self.frm_right_hex_checkbtn = pytk.PyCheckbutton(self.frm_right_clear,
text="Hex",
variable=self.receive_hex_cbtn_var,
relief="flat",
font=font)
self.frm_right_clear_btn = pytk.PyButton(self.frm_right_clear,
text="Clear",
width=10,
font=font,
command=self.Clear) self.frm_right_clear_label.grid(row=0, column=0, padx=5, pady=5, sticky="w")
self.frm_right_threshold_label.grid(row=0, column=1, padx=5, pady=5, sticky="wesn")
self.frm_right_threshold_entry.grid(row=0, column=2, padx=5, pady=5, sticky="wesn")
self.frm_right_hex_checkbtn.grid(row=0, column=3, padx=5, pady=5, sticky="wesn")
self.frm_right_clear_btn.grid(row=0, column=4, padx=5, pady=5, sticky="wesn") self.thresholdStr.set(1)
self.thresholdStr.trace('w', self.GetThresholdValue) def create_frm_status(self):
'''
下半部分状态栏窗口
'''
self.frm_status_label = pytk.PyLabel(self.frm_status,
text="Ready",
font=font)
self.frm_status_label.grid(row=0, column=0, padx=5, pady=5, sticky="wesn") def Toggle(self):
pass def Open(self, event):
pass def Reset(self):
self.frm_right_send.delete("0.0", "end") def Send(self):
pass def Clear(self):
self.frm_right_receive.delete("0.0", "end") def GetThresholdValue(self, *args):
try:
self.thresholdValue = int(self.thresholdStr.get())
except:
pass if __name__ == '__main__':
'''
main loop
'''
root = tk.Tk()
if g_default_theme == "dark":
root.configure(bg="#292929")
combostyle = ttk.Style()
combostyle.theme_use('alt')
combostyle.configure("TCombobox", selectbackground="#292929", fieldbackground="#292929",
background="#292929", foreground="#FFFFFF")
root.title("Serial-Tool")
SerialToolUI(master=root)
root.resizable(False, False)
root.mainloop()
======================
界面逻辑主程序
main.py
#! /usr/bin/env python
# -*- coding: utf-8 -*- import time
import datetime
import threading
import binascii
import platform
import logging from UI import SerialTool
from COM import SerialHelper if platform.system() == "Windows":
from serial.tools import list_ports
elif platform.system() == "Linux":
import glob, os, re import Tkinter as tk
import ttk logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S') class MainSerialToolUI(SerialTool.SerialToolUI):
def __init__(self, master=None):
super(MainSerialToolUI, self).__init__()
self.ser = None
self.receive_count = 0
self.receive_data = ""
self.list_box_serial = list()
self.find_all_serial() def __del__(self):
if platform.system() == "Linux":
try:
self.ser.SetStopEvent()
except:
pass def find_all_serial(self):
'''
获取到串口列表
'''
if platform.system() == "Windows":
try:
self.temp_serial = list()
for com in list_ports.comports():
strCom = com[0] + ": " + com[1][:-7].decode("gbk").encode("utf-8")
self.temp_serial.append(strCom)
for item in self.temp_serial:
if item not in self.list_box_serial:
self.frm_left_listbox.insert("end", item)
for item in self.list_box_serial:
if item not in self.temp_serial:
index = list(self.frm_left_listbox.get(0, self.frm_left_listbox.size())).index(item)
self.frm_left_listbox.delete(index) self.list_box_serial = self.temp_serial self.thread_findserial = threading.Timer(1, self.find_all_serial)
self.thread_findserial.setDaemon(True)
self.thread_findserial.start()
except Exception as e:
logging.error(e)
elif platform.system() == "Linux":
try:
self.temp_serial = list()
self.temp_serial = self.find_usb_tty()
for item in self.temp_serial:
if item not in self.list_box_serial:
self.frm_left_listbox.insert("end", item)
for item in self.list_box_serial:
if item not in self.temp_serial:
index = list(self.frm_left_listbox.get(0, self.frm_left_listbox.size())).index(item)
self.frm_left_listbox.delete(index)
self.list_box_serial = self.temp_serial self.thread_findserial = threading.Timer(1, self.find_all_serial)
self.thread_findserial.setDaemon(True)
self.thread_findserial.start()
except Exception as e:
logging.error(e) def Toggle(self):
'''
打开关闭串口
'''
if self.frm_left_btn["text"] == "Open":
try:
self.currentStrCom = self.frm_left_listbox.get(self.frm_left_listbox.curselection())
if platform.system() == "Windows":
self.port = self.currentStrCom.split(":")[0]
elif platform.system() == "Linux":
self.port = self.currentStrCom
self.baudrate = self.frm_left_combobox_baudrate.get()
self.parity = self.frm_left_combobox_parity.get()
self.databit = self.frm_left_combobox_databit.get()
self.stopbit = self.frm_left_combobox_stopbit.get()
self.ser = SerialHelper.SerialHelper(Port=self.port,
BaudRate=self.baudrate,
ByteSize=self.databit,
Parity=self.parity,
Stopbits=self.stopbit)
self.ser.start()
if self.ser.alive:
self.frm_status_label["text"] = "Open [{0}] Successful!".format(self.currentStrCom)
self.frm_status_label["fg"] = "#66CD00"
self.frm_left_btn["text"] = "Close"
self.frm_left_btn["bg"] = "#F08080" self.thread_read = threading.Thread(target=self.SerialRead)
self.thread_read.setDaemon(True)
self.thread_read.start() except Exception as e:
logging.error(e)
try:
self.frm_status_label["text"] = "Open [{0}] Failed!".format(self.currentStrCom)
self.frm_status_label["fg"] = "#DC143C"
except Exception as ex:
logging.error(ex) elif self.frm_left_btn["text"] == "Close":
try:
self.ser.stop()
self.receive_count = 0
except Exception as e:
logging.error(e)
self.frm_left_btn["text"] = "Open"
self.frm_left_btn["bg"] = "#008B8B"
self.frm_status_label["text"] = "Close Serial Successful!"
self.frm_status_label["fg"] = "#8DEEEE" def Open(self, event):
'''
双击列表打开/关闭串口
'''
self.Toggle() def Clear(self):
self.frm_right_receive.delete("0.0", "end")
self.receive_count = 0 def Send(self):
'''
向已打开的串口发送数据
如果为Hex发送,示例:"31 32 33" [即为字符串 "123"]
'''
if self.ser:
try:
# 发送新行
if self.new_line_cbtn_var.get() == 0:
send_data = str(self.frm_right_send.get("0.0", "end").encode("gbk")).strip()
else:
send_data = str(self.frm_right_send.get("0.0", "end")).strip() + "\r\n" # 是否十六进制发送
if self.send_hex_cbtn_var.get() == 1:
self.ser.write(send_data, isHex=True)
else:
self.ser.write(send_data)
except Exception as e:
self.frm_right_receive.insert("end", str(e) + "\n")
logging.error(e) def SerialRead(self):
'''
线程读取串口发送的数据
'''
while self.ser.alive:
try:
n = self.ser.l_serial.inWaiting()
if n:
self.receive_data += self.ser.l_serial.read(n).replace(binascii.unhexlify(""), "")
if self.thresholdValue <= len(self.receive_data):
self.receive_count += 1 # 接收显示是否为Hex
if self.receive_hex_cbtn_var.get() == 1:
self.receive_data = self.space_b2a_hex(self.receive_data)
self.frm_right_receive.insert("end", "[" + str(datetime.datetime.now()) + " - "
+ str(self.receive_count) + "]:\n", "green")
self.frm_right_receive.insert("end", self.receive_data + "\n")
self.frm_right_receive.see("end")
self.receive_data = "" except Exception as e:
logging.error(e)
self.receive_data = ""
self.ser.stop()
self.ser = None def find_usb_tty(self, vendor_id=None, product_id=None):
'''
发现串口设备
'''
tty_devs = list()
for dn in glob.glob('/sys/bus/usb/devices/*') :
try:
vid = int(open(os.path.join(dn, "idVendor" )).read().strip(), 16)
pid = int(open(os.path.join(dn, "idProduct")).read().strip(), 16)
if ((vendor_id is None) or (vid == vendor_id)) and ((product_id is None) or (pid == product_id)) :
dns = glob.glob(os.path.join(dn, os.path.basename(dn) + "*"))
for sdn in dns :
for fn in glob.glob(os.path.join(sdn, "*")) :
if re.search(r"\/ttyUSB[0-9]+$", fn) :
tty_devs.append(os.path.join("/dev", os.path.basename(fn)))
except Exception as ex:
pass
return tty_devs def space_b2a_hex(self, data):
'''
格式化接收到的数据字符串
示例:123 --> 31 32 33
'''
new_data_list = list()
new_data = "" hex_data = binascii.b2a_hex(data)
temp_data = ""
for index,value in enumerate(hex_data):
temp_data += value
if len(temp_data) == 2:
new_data_list.append(temp_data)
temp_data = ""
for index,value in enumerate(new_data_list):
if index%25 == 0 and index != 0:
new_data += "\n"
new_data += value
new_data += " " return new_data if __name__ == '__main__':
'''
main loop
'''
root = tk.Tk()
root.title("Serial Tool")
if SerialTool.g_default_theme == "dark":
root.configure(bg="#292929")
combostyle = ttk.Style()
combostyle.theme_use('alt')
combostyle.configure("TCombobox", selectbackground="#292929", fieldbackground="#292929",
background="#292929", foreground="#FFFFFF")
MainSerialToolUI(master=root)
root.resizable(False, False)
root.mainloop()
项目地址:Serial-Tool
仅根据自己需要写的串口工具,需要其他功能的话请自行添加,或者告知我添加。
串口调试工具(Python2.7+pyserial+Tkinter)的更多相关文章
- 痞子衡嵌入式:串口调试工具Jays-PyCOM诞生记(1)- 环境搭建(Python2.7.14 + pySerial3.4 + wxPython4.0.3)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是串口调试工具Jays-PyCOM诞生之环境搭建. 在写Jays-PyCOM时需要先搭好开发和调试环境,下表列出了开发过程中会用到的所有软 ...
- 痞子衡嵌入式:串口调试工具Jays-PyCOM诞生记(3)- 串口功能实现(pySerial)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是串口调试工具Jays-PyCOM诞生之串口功能实现. 串口调试助手是最核心的当然是串口数据收发与显示的功能,Jays-PyCOM借助的是 ...
- 痞子衡嵌入式:串口调试工具Jays-PyCOM诞生记 - 索引
大家好,我是痞子衡,是正经搞技术的痞子.本系列痞子衡给大家介绍的是串口调试工具Jays-PyCOM诞生. 串口调试助手是嵌入式开发里非常常用的小工具,市面上有非常多流行的串口调试工具,比如TeraTe ...
- 痞子衡嵌入式:串口调试工具Jays-PyCOM诞生记(6)- 打包发布(PyInstaller3.3.1)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是串口调试工具Jays-PyCOM诞生之打包发布. 经过上一篇软件优化之后,Jays-PyCOM已经初长成,该到了出去历练的时候了,只有经 ...
- 做自己的串口调试工具-MFC
之前一共说了几个软件库,串口通讯的,xml加载的,还有动态提示的,通过这三个库就可以实现一个自己的串口调试工具,成品如下 动态加载配置文件之后如下 软件可以在xml中配置发送的字符串,不算是大工程,但 ...
- 串口调试者v2.1------开源c#串口调试工具
第一步:上图 第二步:上代码 >>>>>>>>>>>源代码下载<<<<<<<<< ...
- 痞子衡嵌入式:串口调试工具Jays-PyCOM诞生记(2)- 界面构建(wxFormBuilder3.8.0)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是串口调试工具Jays-PyCOM诞生之界面构建. 一个软件的UI界面是非常重要的,这是软件与用户交互的接口,软件功能即使再强大,但如果没 ...
- 痞子衡嵌入式:串口调试工具Jays-PyCOM诞生记(4)- 联合调试(vspd, sscom, PyCharm2018.2)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是串口调试工具Jays-PyCOM诞生之联合调试. 软件开发离不开调试,调试手段分两种:一是黑盒调试,即直接从输入/输出角度测试软件功能是 ...
- 痞子衡嵌入式:串口调试工具Jays-PyCOM诞生记(5)- 软件优化
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是串口调试工具Jays-PyCOM诞生之软件优化. 前面痞子衡已经初步实现了Jays-PyCOM的串口功能,并且通过了最基本的测试,但目前 ...
随机推荐
- centos源码安装git
因为Centos上yum安装的话可能版本比较低,使用中会有一些难以预料的问题出现. 从源代码编译安装方法: #Centos执行: yum install curl-devel expat-devel ...
- Python修改文件名
Python批量修改文件名 # -*- coding: cp936 -*- import os from nt import chdir path="./files/" froms ...
- theos初探:ios越狱开发教程
开发环境搭建回顾 现在已经在windows上安装好了theos了.在上一篇中都已经讲了,开发环境主要部件就是: 1.theos,主要包含了使用make时的makefile模板文件.包含了各种库和框架的 ...
- python bottle 框架开发任务管理系统 V_1.0版
经过1-2个星期的开发,现在开发了个半成品(UI现在比较烂,因为我的前端本来就很差,将就下吧),大概功能如下:用户功能(添加.删除.修改),添加部门功能,任务管理功能(添加.删除.修改,详细).项目管 ...
- 分布式文件系统MooseFS安装步骤
1. 安装 1.1 准备安装环境 首先选择一台比较好的服务器做master,如果可以在选择一台做为master的备份服务器最好.然后其他的服务器当chunkserver. 为了方便说明问题,我这 ...
- SQL Server 2008空间数据应用系列十:使用存储过程生成GeoRSS聚合空间信息
原文:SQL Server 2008空间数据应用系列十:使用存储过程生成GeoRSS聚合空间信息 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server 2 ...
- kabina启动配置
启动 kibana # /usr/local/kibana-4.1.1-linux-x64/bin/kibana zjtest7-redis:/usr/local/kibana-4.5.3-linux ...
- hdu 3874 Necklace(bit树+事先对查询区间右端点排序)
Mery has a beautiful necklace. The necklace is made up of N magic balls. Each ball has a beautiful v ...
- ※数据结构※→☆非线性结构(tree)☆============二叉树 顺序存储结构(tree binary sequence)(十九)
二叉树 在计算机科学中,二叉树是每个结点最多有两个子树的有序树.通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree).二叉树常被用作二叉查找树和二叉堆或是 ...
- 分享几种Linux软件的安装方法
Linux软件安装由于不同的Linux分支,安装方法也互不相同,介绍几种常见的安装方法. 1. 源码安装, 对于本身具有开源血统的Linux系统来说,几乎所有的开源软件都支持在Linux平台运 ...