项目总结
项目简介
通过使用Python编写一个串口调试助手,完成对4G模块的指令配置。
共包含四个.py文件,一个ui文件,一个.ini配置文件,一个.json文件,一个.txt的日志文件。
软件界面
软件界面如下:
主要功能
主要功能:
1.可以导出、导入配置文件,是之可以自动填充内容。
2.选择并打开串口,设置串口号及相关信息,在最终版本中将波特率、数据位、停止位和流控写死,无需再进行操作。
3.在打开串口之前,将“进入配置状态”、“设备重启”、“进入通讯状态”和“设置并保存所有参数”的去能。
操作流程
操作流程:
1.模块通过串口连接PC,并上电。
2.设置参数,并打开串口。
3.单击“进入配置状态”,将4G模块由通讯模式进入指令模式。
4.单击“设置并保存所有参数”,向4G模块发送所有配置指令。
5.单击“进入通讯状态”,将4G模块由指令模式进入通讯模式。
背景知识
开发过程中涉及的知识:
- 首先,需要搭建python的开发环境。先安装Anacoda3,Anaconda中包含了很多Python开发过程中需要用到的包,且可建虚拟环境,适应多种开发要求。安装完成后,通过
conda create ***(环境名称)
(PS:个人理解conda指令类似于Linux中的yum,Anaconda3就类似于Linux中的yum源)。
随后通过conda activate ****(环境名称)
进入建立的虚拟环境。随后在此环境下安装PyQt5、seria和pyserial类,分别用于界面开发和串口操作。
(PS:后发现可将PyQt5结合Eric6共同进行界面开发,打算后续学习。) - 在本次项目中,
- 主要用到了PyQt的相关类-QMessageBox、QAbstrtaButton、QlineEdit和QcheckBox。和PyQt中的@pyqtslot装饰器信号与槽的定义格式:on_发送者对象名称_发射信号名称
- 串口操作的相关类的常用方法:
.read()按字节读取串口缓存区的数据 、
.readlines()按行读取串口缓存区的数据、
.readline()读取一行串口缓存区的数据、
.in_waiting 读取串口缓存区的字节数、
在串口操作部分遇到的问题是-一开始通过行数读取串口发送回来的数据,在解析的过程中代码复杂度很高且经常由于转义字符导致解析出现问题,后续通过延时后,运用ser.read(ser,in_waitng)一次性读取串口返回的数据结合find()进行内容判断。 - 配置文件configpaper的相关类:
在配置文件中主要是将填好的信息存储到配置文件中,初步考虑的是采用json类的json.load()和json.dump()进行数据的存储,但在开发过程中发现.json文件中存储的字符型的数组,因为不一定所有的选项都会使用到,所以在单个读取和单个写入顺序上存在诸多不便,故后续了解到有一个专门用于配置文件的类,分为[section]/[object]/[value],可分为多个块多个目标进行读取,更加便于单个读取config.get(‘section’,‘object’,’‘value’)和有序写入config.set(‘setciton’,‘object’,‘value’)。 - 涉及到时间戳的输入与转化、
Python中的time类通过time.time()读取到的是时间戳(当前时间距离1970年1月1日北京时间上午8:00的秒数)所以需要对其使用time.localtime()将秒数时间戳转化为本地时间格式。产生的是一个包含年月日时分秒周等信息的time.srtuct_time元组,如果想要形成时间格式还需要用到一个time.strftime()将元组转化为我们想要的格式。
file_log.write(str + time.strftime('[%Y-%m-%d %H:%M:%S]' + "\n", time.localtime(time.time())))`
- 字节包与字符串之间的编解码
在串口中通信传输的是字节包,而我们在程序中打印和输入的为字符串,在Python中对字节包和字符串进行了清晰的划分——不能将他们同时输出,故在此项目中涉及到向串口传输数据时需要对写入的字符串进行编码encode();从串口读取到数据后,需要对读到的字节包进行解码decode()。
def send_cmd(self):
self.rt_log(repr(Settings.settings_temp))
for set_down in Settings.settings_temp:
# 循环发送Settings_temp指令
ser.write(set_down.encode())
self.rt_log("[TX->]:\n" + set_down)
# 将数据编码并传输到串口
self.textBrowser.append("[TX->]:\n"+set_down)
# 将发送内容传输到文本浏览框
time.sleep(1)
data = ser.read(ser.in_waiting)
# 读取缓存区的所有字节
if data.find(b'OK') != -1:
self.textBrowser.append("[RX<-]:\n" + data.decode())
self.rt_log("[RX<-]:\n" + data.decode())
# 将字节包解码为字符串,传输到文本浏览框
self.textBrowser.append("发送指令成功")
else:
self.textBrowser.append("发送指令失败")
- Python的pyinstaller指令,将工程打包成exe文件
在对整个项目完成开发后,需要对整个文件进行打包,此时需要用到一个新的工具——pyinstaller。通过pip install pyinstaller即可安装(我理解这里Python的pip就类似于Linux中rpm安装命令),安装完成后进入Anaconda中的虚拟环境,到工程所在的目录下,通过pyinstaller -F -w 文件名对其进行打包,其中比较关键的就是-F:生成一个可执行文件;-w:去除命令行界面。文件名要求是工程中的主文件。