目录

  • 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)相关推荐

  1. [python] 3 、基于串口通信的嵌入式设备上位机自动测试程序框架(简陋框架)...

    星期一, 20. 八月 2018 01:53上午 - beautifulzzzz 1.前言 做类似zigbee.ble mesh...无线网络节点性能测试的时候,手动操作然后看表象往往很难找出真正的原 ...

  2. qt5_c++工业上位机自动扫码数据追溯

    qt5_c++工业上位机自动扫码数据追溯 Qt5之工业应用 一套完整工程,链接PLC,工业无人值守自动扫码使用,无线扫码枪SR1000的使用,使用qt5.14,用qtcreator加载工程后,编译,运 ...

  3. 【串口助手】Python从零开始制作温湿度串口上位机

    文章目录 1. 项目介绍 2. 功能简介 3. 开发过程 3.1 准备工作 3.2 编写串口上位机界面 3.3 功能实现 3.3.1 基本功能 3.3.2 整活 3.4 打包 exe 可执行文件 1. ...

  4. python做工控机_「上位机软件」工控机上位机软件的开发历程(一) - seo实验室...

    上位机软件 本人就职于一家环境监测公司,上位机软件的主要功能是采集各仪器的数据,然后存储起来,并传送到环保局平台. 刚到公司的时候,公司使用的是组态软件(用以显示流程图),然后再开发了报表软件.数据上 ...

  5. 使用python实现一个简陋的上位机

    import tkinter as tk from tkinter import ttk import serial # 导入模块 import threading import serial.too ...

  6. Python+tkinter实现超时无键盘操作自动退出

    功能描述: Python+tkinter应用程序,启用软件之后,如果用户超过10分钟没有在指定组件中进行按键操作,给出提示信息之后退出程序. 参考代码: 运行结果:

  7. python tkinter、PySide2乱炖,自动连续按键程序,不止自动保存

    (源码在结尾 背景: 许多人在编辑一些文件的时候都没有按下保存的习惯,这就导致了许多"事故"的发生,使呕心沥血的成果付之东流,在我身边也发生了许多这样的事情,令我痛心疾首,而我本人 ...

  8. python 串口_如何使用Python开发串口通讯上位机(一)

    用Python开发串口通讯型上位机,其实并非最优解,本系列更新只为个人学习与总结.如果有C语言底子,嵌入式层面的上位机开发,C++ Builder,C#才是更加好用的利器. 1 什么是上位机 从事过嵌 ...

  9. python编程与下位机通讯_如何使用Python开发串口通讯上位机(一)

    用Python开发串口通讯型上位机,其实并非最优解,本系列更新只为个人学习与总结.如果有C语言底子,嵌入式层面的上位机开发,C++ Builder,C#才是更加好用的利器.1 什么是上位机 从事过嵌入 ...

最新文章

  1. nuxt 过滤 query 参数
  2. 五分钟叫你看懂美国金融危机的成因和巨大危害[转]
  3. Linux 命令之 tar 命令-打包和备份的归档工具(附压缩/解压工具)
  4. MYSQL账户管理及主要操作
  5. switch用法和原理
  6. linux ntfs 3g6,CentOS6挂载读写NTFS分区(ntfs-3g)
  7. centos6.5安装mono
  8. 出现红字是电脑问题吗_婚姻出现问题,生个孩子就能解决,这是真的吗?
  9. Keras——用Keras搭建自编码神经网络(AutoEncoder)
  10. 第4次作业类测试代码 021
  11. 汇编语言王爽 实验十五
  12. radius源码下载
  13. php导入rtf文件获取内容,可以使用PHP在网页中显示RTF文件吗?
  14. hdu2154跳舞毯(dp)
  15. java课程设计之球球大作战
  16. 【c语言】高级篇学习笔记
  17. JDBC(Java Data Base Connectivity)基本用法
  18. InstructPix2Pix: 随口修图
  19. 关于sip和sip的客户端
  20. python接口测试完善

热门文章

  1. 新手nvm npm 卸载不用依赖包,项识别为 cmdlet、函数、脚本文件,等命令集合
  2. php三元运算符要多个赋值,php中三元运算符用法
  3. 线性代数Python计算:向量的模及向量间的夹角
  4. mac解决//go:linkname must refer to declared function or variable
  5. mac 触控板手势以及常用快捷键
  6. sql查询数据表某列的重复值并计数
  7. 关于renameTo的用法
  8. js文件 本地 上传服务器地址,js 本地文件同步服务器地址
  9. 华为MIB关键字IOD查询地址及方法
  10. Validform使用说明