Python Tkinter - WiFi WL Test 上位机 (自动搜索Uart、执行exe/Bat)
目录
- Python Tkinter - WiFi WL Test 上位机开发
- 特点:
- 先上图:
- 自动查找可用串口,如果电脑未连接串口,会打印提示信息:
- 连接串口后,即可执行WL 命令和测试通讯:
- 连接以及执行WL CMD过程:
- 执行Bat过程Gif:
- 源码解析 - 获取电脑可用串口
- 源码解析 - 执行WL指令:
- 源码解析 - 执行Bat:
- 全部源码
- Tkinter 官方文档:
- 博主热门文章推荐:
Python Tkinter - WiFi WL Test 上位机开发
WiFi 通过WL命令进行射频性能测试是一个比较繁琐的过程,我在之前做这个的时候,单独测Cmd需要手动输入各类参数(这里使用Cypress的芯片,官方没有提供上位机),让人感觉不爽。。。
为提升效率,就在用Tkinter简单做了个图形化测试上位机,在这里分享一下下~~
特点:
- 自动搜索/选择电脑可用串口,用于WL Test
- 自动组包WiFi WL Commands,减少手动输入
- 收发数据Log显示
- 执行Bat文件,因为有些WL 命令是通过bat文件组合在一起的,所以增加该功能
先上图:
自动查找可用串口,如果电脑未连接串口,会打印提示信息:
连接串口后,即可执行WL 命令和测试通讯:
连接以及执行WL CMD过程:
执行Bat过程Gif:
源码解析 - 获取电脑可用串口
通过 Serial包的 serial.tools.list_ports.comports() 来获取电脑目前所有链接的串口号
使用前需要import serial
def GetComPortList():port_list = list(serial.tools.list_ports.comports())if len(port_list) == 0:print('找不到串口')#port_list[0] = '找不到串口'else:for i in range(0,len(port_list)):# print(port_list[i])passreturn port_list
获取的串口,通过Tkinter的Combobox显示和选择COM,同时绑定选中的callback函数OnCmSelected,在选中相应COM后,显示到CportLable_text上:
def OnCmSelected(*args): global portCmdStrCurSelected = comboxlist.get()portCmdStr = CurSelected[3:4]CportLable_text.set("COM Select:" + portCmdStr)print("ComPortSelect: " + CurSelected) #Combobox
comvalue = StringVar()
comboxlist = ttk.Combobox(root, textvariable=comvalue, width =20) # 初始化
comboxlist.place(relx=0.25, rely=0.03, relwidth=0.25, relheight=0.05)#refresh
OnRefreshCom()
comboxlist.bind("<<ComboboxSelected>>", OnCmSelected)
最后在启动tkinter时调用OnRefreshCom,获取uart数据并显示
def OnRefreshCom():PortList = GetComPortList()if len(PortList) != 0:comboxlist["values"] = PortListcomboxlist.current(0)CurSelected = comboxlist.get()print("CurSelected:" + CurSelected)ComPortSelected = CurSelected[3:4]print("ComPortSelected:" + ComPortSelected)global portCmdStrportCmdStr = ComPortSelectedCportLable_text.set("COM Select:" + portCmdStr)else:CportLable_text.set("COM Not Found")inputData.insert(END, "\n未找到可用串口,请检查接线!")comboxlist.set('')
源码解析 - 执行WL指令:
通过subprocess.getstatusoutput() , 执行wl.exe,并据Tkinter 输入框输入的指令,组包相应的执行参数
def DoWlCommands(cmd = 'ver'):if os.path.exists(wl):wlcmd = wl + serialCmdStr + portCmdStr +' '+ cmd# print(wlcmd)ShowSendtoDUT(wlcmd)try:rst = subprocess.getstatusoutput(wlcmd)except subprocess.CalledProcessError as exc:rst = exc.outputprint(exc.returncode)print(exc.output)# print(rst)return rstelse:inputData.insert(END, "wl.exe Not found in folder")
调用是通过Tkinter Button:bt_bin2json 的回调函数 OnCommandInput :
def OnCommandInput():InputCmd = Et_CommandInput.get()if(len(InputCmd) == 0):print("未输入命令")else:rst = DoWlCommands(InputCmd)ShowRcvfromDUT(rst)
源码解析 - 执行Bat:
通过subprocess.Popen()直接通过cmd 执行bat文件
def executeBatchfile(filepath):try:rst = subprocess.Popen("cmd.exe /c" + filepath, shell=False)except subprocess.CalledProcessError as exc:rst = exc.outputprint(exc.returncode)print(exc.output)return rst
GUI上通过tkinter.filedialog来选中并打开相应bat文件并执行:
OnBatchCmd同样对应Tkinter Button
def OnBatchCmd():File_Batch = tkinter.filedialog.askopenfilename()if File_Batch != '':Filelog = "\nStart Execute Batch file: \n" + File_Batch+'\n\n\r'inputData.insert(END, Filelog)print(Filelog)# exBatchCmd = "r"+Filelog# os.system(exBatchCmd)# rst = subprocess.Popen("cmd.exe /c"+File_Batch, shell=False)rst = executeBatchfile(File_Batch)print(rst)# root.destory()else:Filelog = "\nPlease select Batch file! \n"inputData.insert(END, Filelog)print(Filelog)
全部源码
Github:
https://github.com/HowieXue/PythonWiFiWLTest
# -*- coding: utf-8 -*-
#HowardXue20190816
from tkinter import *
from tkinter import ttk
import serial
import serial.tools.list_ports
import subprocess
import os
import tkinter.filedialogwl = "wl.exe"
serialCmdStr = " --serial "
portCmdStr = "0"print('Wait for GUI start...')
def GetComPortList():port_list = list(serial.tools.list_ports.comports())if len(port_list) == 0:print('找不到串口')#port_list[0] = '找不到串口'else:for i in range(0,len(port_list)):# print(port_list[i])passreturn port_listdef OnCmSelected(*args): global portCmdStrCurSelected = comboxlist.get()portCmdStr = CurSelected[3:4]CportLable_text.set("COM Select:" + portCmdStr)print("ComPortSelect: " + CurSelected) def DoWlCommands(cmd = 'ver'):if os.path.exists(wl):wlcmd = wl + serialCmdStr + portCmdStr +' '+ cmd# print(wlcmd)ShowSendtoDUT(wlcmd)try:rst = subprocess.getstatusoutput(wlcmd)except subprocess.CalledProcessError as exc:rst = exc.outputprint(exc.returncode)print(exc.output)# print(rst)return rstelse:inputData.insert(END, "wl.exe Not found in folder")def ShowSendtoDUT(wlcmd):SendDut = '\n\r >>[Send to DUT] >>:\n\r'inputData.insert(END, SendDut)inputData.insert(END, wlcmd)def ShowRcvfromDUT(rst):RcvDut = ' \n\r >>[Rcv from DUT] >>:\n\r'txt.insert(END, RcvDut)txt.insert(END, rst)def OnComTest_GetVersion():rst = DoWlCommands()ShowRcvfromDUT(rst)#inputData.delete(0.0, END)def OnCommandInput():InputCmd = Et_CommandInput.get()if(len(InputCmd) == 0):print("未输入命令")else:rst = DoWlCommands(InputCmd)ShowRcvfromDUT(rst)def clearSendContent():inputData.delete(1.0, END)def clearRcvContent():txt.delete(1.0, END)def executeBatchfile(filepath):try:rst = subprocess.Popen("cmd.exe /c" + filepath, shell=False)except subprocess.CalledProcessError as exc:rst = exc.outputprint(exc.returncode)print(exc.output)return rstdef OnBatchCmd():File_Batch = tkinter.filedialog.askopenfilename()if File_Batch != '':Filelog = "\nStart Execute Batch file: \n" + File_Batch+'\n\n\r'inputData.insert(END, Filelog)print(Filelog)rst = executeBatchfile(File_Batch)print(rst)# root.destory()else:Filelog = "\nPlease select Batch file! \n"inputData.insert(END, Filelog)print(Filelog)def OnRefreshCom():PortList = GetComPortList()if len(PortList) != 0:comboxlist["values"] = PortListcomboxlist.current(0)CurSelected = comboxlist.get()print("CurSelected:" + CurSelected)ComPortSelected = CurSelecte5d[3:4]print("ComPortSelected:" + ComPortSelected)global portCmdStrportCmdStr = ComPortSelectedCportLable_text.set("COM Select:" + portCmdStr)else:CportLable_text.set("COM Not Found")inputData.insert(END, "\n未找到可用串口,请检查接线!")comboxlist.set('')#Tkinter code below
root = Tk()
root.geometry('1000x600')
root.title('WiFi WL Commands Test Tools from HowieXue')
root.config(bg='#f0ffff')#Lable
intro = Label(root,text='请先选择串口,然后点击相应按钮进行WL测试',\bg='#d3fbfb',\fg='red',\font=('华文新魏',14),\width=20,\height=2,\relief=RIDGE)intro.place(relx=0.1, rely=0.1, relwidth=0.8, relheight=0.1)CportLable_text = StringVar()
CportLable = Label(root, textvariable = CportLable_text,\# bg='#d3fbfb',\fg='red',\font=('华文新魏',14),\width=20,\height=2,\relief=RIDGE)
CportLable.place(relx=0.1, rely=0.03, relwidth=0.15, relheight=0.05)ContactLable = Label(root, text='联系方式:HowieXue@163.com',\# bg='#d3fbfb',\fg='red',\font=('',12),\width=20,\height=2,\relief=RIDGE)
ContactLable.place(relx=0.7, rely=0.03, relwidth=0.25, relheight=0.05)#Input
inputData = Text(root, font = ('',10))
inputData.place(relx=0.1, rely=0.2, relwidth=0.3, relheight=0.625)#Output
txt = Text(root, font = ('',10))
txt.place(relx=0.6, rely=0.2, relwidth=0.3, relheight=0.625)#lable
Lb_CommandInput = Label(root,text='输入WL CMD:',\# bg='#d3fbfb',\fg='red',\font=('华文新魏',14),\width=20,\height=2,\relief=RIDGE)Lb_CommandInput.place(relx=0.425, rely=0.337, relwidth=0.15, relheight=0.05)Lb_CommandBatch = Label(root,text='执行Batch文件:',\# bg='#d3fbfb',\fg='red',\font=('华文新魏',14),\width=20,\height=2,\relief=RIDGE)Lb_CommandBatch.place(relx=0.425, rely=0.59, relwidth=0.15, relheight=0.05)#Entry
Et_CommandInput = Entry(root, bd =5, relief=GROOVE)Et_CommandInput.place(relx=0.425, rely=0.4, relwidth=0.15, relheight=0.05)#Button
bt_json2bin = Button(root, text='连接测试: Get WL Version', command=OnComTest_GetVersion, fg ='blue')
bt_json2bin.place(relx=0.4, rely=0.2, relwidth=0.2, relheight=0.1)bt_bin2json = Button(root, text='执行WL Command', command=OnCommandInput, fg ='blue')
bt_bin2json.place(relx=0.4, rely=0.45, relwidth=0.2, relheight=0.1)bt_batch = Button(root, text='选择要执行的Batch文件', command=OnBatchCmd, fg ='blue')
bt_batch.place(relx=0.4, rely=0.65, relwidth=0.2, relheight=0.1)bt_clear = Button(root, text='Clear Send Data', command=clearSendContent, fg ='blue')
bt_clear.place(relx=0.15, rely=0.825, relwidth=0.2, relheight=0.1)bt_clear_rcv = Button(root, text='Clear Receive Data', command=clearRcvContent, fg ='blue')
bt_clear_rcv.place(relx=0.65, rely=0.825, relwidth=0.2, relheight=0.1)bt_refresh = Button(root, text='刷新', command=OnRefreshCom, fg ='blue')
bt_refresh.place(relx=0.5, rely=0.03, relwidth=0.05, relheight=0.05)#Combobox
comvalue = StringVar()
comboxlist = ttk.Combobox(root, textvariable=comvalue, width =20) # 初始化
comboxlist.place(relx=0.25, rely=0.03, relwidth=0.25, relheight=0.05)#refreshOnRefreshCom()comboxlist.bind("<<ComboboxSelected>>", OnCmSelected)#comboxlist.pack()root.mainloop()
备注:执行本脚本中的WL command需要调用Cypress 提供的wl.exe ,下载地址为:
https://download.csdn.net/download/HowieXue/13189989
Tkinter 官方文档:
https://docs.python.org/zh-cn/3/library/tkinter.html
博主热门文章推荐:
一篇读懂系列:
- 一篇读懂无线充电技术(附方案选型及原理分析)
- 一篇读懂:Android/iOS手机如何通过音频接口(耳机孔)与外设通信
- 一篇读懂:Android手机如何通过USB接口与外设通信(附原理分析及方案选型)
LoRa Mesh系列:
- LoRa学习:LoRa关键参数(扩频因子,编码率,带宽)的设定及解释
- LoRa学习:信道占用检测原理(CAD)
- LoRa/FSK 无线频谱波形分析(频谱分析仪测试LoRa/FSK带宽、功率、频率误差等)
网络安全系列:
- ATECC508A芯片开发笔记(一):初识加密芯片
- SHA/HMAC/AES-CBC/CTR 算法执行效率及RAM消耗 测试结果
- 常见加密/签名/哈希算法性能比较 (多平台 AES/DES, DH, ECDSA, RSA等)
- AES加解密效率测试(纯软件AES128/256)–以嵌入式Cortex-M0与M3 平台为例
嵌入式开发系列:
- 嵌入式学习中较好的练手项目和课题整理(附代码资料、学习视频和嵌入式学习规划)
- IAR调试使用技巧汇总:数据断点、CallStack、设置堆栈、查看栈使用和栈深度、Memory、Set Next Statement等
- Linux内核编译配置(Menuconfig)、制作文件系统 详细步骤
- Android底层调用C代码(JNI实现)
- 树莓派到手第一步:上电启动、安装中文字体、虚拟键盘、开启SSH等
- Android/Linux设备有线&无线 双网共存(同时上内、外网)
AI / 机器学习系列:
- AI: 机器学习必须懂的几个术语:Lable、Feature、Model…
- AI:卷积神经网络CNN 解决过拟合的方法 (Overcome Overfitting)
- AI: 什么是机器学习的数据清洗(Data Cleaning)
- AI: 机器学习的模型是如何训练的?(在试错中学习)
- 数据可视化:TensorboardX安装及使用(安装测试+实例演示)
Python Tkinter - WiFi WL Test 上位机 (自动搜索Uart、执行exe/Bat)相关推荐
- [python] 3 、基于串口通信的嵌入式设备上位机自动测试程序框架(简陋框架)...
星期一, 20. 八月 2018 01:53上午 - beautifulzzzz 1.前言 做类似zigbee.ble mesh...无线网络节点性能测试的时候,手动操作然后看表象往往很难找出真正的原 ...
- qt5_c++工业上位机自动扫码数据追溯
qt5_c++工业上位机自动扫码数据追溯 Qt5之工业应用 一套完整工程,链接PLC,工业无人值守自动扫码使用,无线扫码枪SR1000的使用,使用qt5.14,用qtcreator加载工程后,编译,运 ...
- 【串口助手】Python从零开始制作温湿度串口上位机
文章目录 1. 项目介绍 2. 功能简介 3. 开发过程 3.1 准备工作 3.2 编写串口上位机界面 3.3 功能实现 3.3.1 基本功能 3.3.2 整活 3.4 打包 exe 可执行文件 1. ...
- python做工控机_「上位机软件」工控机上位机软件的开发历程(一) - seo实验室...
上位机软件 本人就职于一家环境监测公司,上位机软件的主要功能是采集各仪器的数据,然后存储起来,并传送到环保局平台. 刚到公司的时候,公司使用的是组态软件(用以显示流程图),然后再开发了报表软件.数据上 ...
- 使用python实现一个简陋的上位机
import tkinter as tk from tkinter import ttk import serial # 导入模块 import threading import serial.too ...
- Python+tkinter实现超时无键盘操作自动退出
功能描述: Python+tkinter应用程序,启用软件之后,如果用户超过10分钟没有在指定组件中进行按键操作,给出提示信息之后退出程序. 参考代码: 运行结果:
- python tkinter、PySide2乱炖,自动连续按键程序,不止自动保存
(源码在结尾 背景: 许多人在编辑一些文件的时候都没有按下保存的习惯,这就导致了许多"事故"的发生,使呕心沥血的成果付之东流,在我身边也发生了许多这样的事情,令我痛心疾首,而我本人 ...
- python 串口_如何使用Python开发串口通讯上位机(一)
用Python开发串口通讯型上位机,其实并非最优解,本系列更新只为个人学习与总结.如果有C语言底子,嵌入式层面的上位机开发,C++ Builder,C#才是更加好用的利器. 1 什么是上位机 从事过嵌 ...
- python编程与下位机通讯_如何使用Python开发串口通讯上位机(一)
用Python开发串口通讯型上位机,其实并非最优解,本系列更新只为个人学习与总结.如果有C语言底子,嵌入式层面的上位机开发,C++ Builder,C#才是更加好用的利器.1 什么是上位机 从事过嵌入 ...
最新文章
- nuxt 过滤 query 参数
- 五分钟叫你看懂美国金融危机的成因和巨大危害[转]
- Linux 命令之 tar 命令-打包和备份的归档工具(附压缩/解压工具)
- MYSQL账户管理及主要操作
- switch用法和原理
- linux ntfs 3g6,CentOS6挂载读写NTFS分区(ntfs-3g)
- centos6.5安装mono
- 出现红字是电脑问题吗_婚姻出现问题,生个孩子就能解决,这是真的吗?
- Keras——用Keras搭建自编码神经网络(AutoEncoder)
- 第4次作业类测试代码 021
- 汇编语言王爽 实验十五
- radius源码下载
- php导入rtf文件获取内容,可以使用PHP在网页中显示RTF文件吗?
- hdu2154跳舞毯(dp)
- java课程设计之球球大作战
- 【c语言】高级篇学习笔记
- JDBC(Java Data Base Connectivity)基本用法
- InstructPix2Pix: 随口修图
- 关于sip和sip的客户端
- python接口测试完善
热门文章
- 新手nvm npm 卸载不用依赖包,项识别为 cmdlet、函数、脚本文件,等命令集合
- php三元运算符要多个赋值,php中三元运算符用法
- 线性代数Python计算:向量的模及向量间的夹角
- mac解决//go:linkname must refer to declared function or variable
- mac 触控板手势以及常用快捷键
- sql查询数据表某列的重复值并计数
- 关于renameTo的用法
- js文件 本地 上传服务器地址,js 本地文件同步服务器地址
- 华为MIB关键字IOD查询地址及方法
- Validform使用说明