热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

痞子衡嵌入式:串口调试工具JaysPyCOM诞生记(5)软件优化

大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是串口调试工具Jays-PyCOM诞生之软件优化。前面痞子衡已经初步实现了Jays-PyC

  大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是串口调试工具Jays-PyCOM诞生之软件优化

  前面痞子衡已经初步实现了Jays-PyCOM的串口功能,并且通过了最基本的测试,但目前的Jays-PyCOM相比市面上流行的串口调试工具还差得很远,有很大的优化空间。优化可以从两方面进行:一、是功能上的优化,可以添加更多实用的功能;二、是界面效果上的优化,可以增加一些界面动画效果或者重新配色美化界面。下面痞子衡从这两方面分别为Jays-PyCOM做一些简单的优化:

一、功能优化

1.1 增强鲁棒性

  最开始要做的功能优化应该是增强软件鲁棒性,即在任何异常用户输入的情况下,软件都不能挂掉,痞子衡在实测中发现当用户在"Com Port"里输入的是无效串口设备号时,软件会挂掉,因此做了以下改进,在打开设备时使用try except语句,如有异常,直接退出,不会继续后面代码的执行。此类改进还有很多,不一一例举。

class mainWin(win.com_win):def openClosePort( self, event ):if s_serialPort.isOpen():s_serialPort.close()self.m_button_openClose.SetLabel('Open')else:# ...self.setParitybits()# 添加代码开始try:s_serialPort.open()except Exception, e:# Show warning messagereturn# 添加代码结束self.m_button_openClose.SetLabel('Close')# ...

1.2 自动检测可用Port

  最初版本实现Port口选择是用户按标准格式“COMx”手动输入,但这样有一个问题,即用户输入的格式有可能不合法,并且即使是一个合法的格式输入,但也可能不是一个可用的有效Port。参照市面上流行的串口调试助手,有的是下拉菜单选择所有COM口(比如AccessPort,这样可以解决不合法格式输入的问题),有的是下拉菜单选择可用的COM口(比如sscom,这样可以解决Port是否有效的问题),痞子衡参照sscom的做法对Jays-PyCOM进行了如下优化:

class mainWin(win.com_win):def __init__(self, parent):self.refreshComPort(None)self.m_choice_comPort.SetSelection( 0 )def refreshComPort( self, event ):comports = list(serial.tools.list_ports.comports())ports = [None] * len(comports)for i in range(len(comports)):comport = list(comports[i])# example comport = [u'COM3', u'Intel(R) Active Management Technology - SOL (COM3)', u'PCI\\VEN_8086&DEV_9D3D&SUBSYS_06DC1028&REV_21\\3&11583659&0&B3']ports[i] = comport[0] + ' - ' + comport[1]self.m_choice_comPort.Clear()self.m_choice_comPort.SetItems(ports)def setPort ( self ):index = self.m_choice_comPort.GetSelection()comPort = self.m_choice_comPort.GetString(index)comPort = comPort.split(' - ')s_serialPort.port = comPort[0]

1.3 实现格式切换功能

  Char/Hex格式转换属于比较实用的功能,一般的串口调试助手都会有这个功能,Jays-PyCOM之前默认总是按照Char格式来输入和显示,"Format"选项框的功能实际上并没有实现,因此痞子衡在这里加上了格式切换功能。

import formatters_formatter = formatter.formatter()
s_lastRecvFormat = None
s_lastSendFormat = Noneclass mainWin(win.com_win):# 函数功能实现def setSendFormat( self, event ):lines = self.m_textCtrl_send.GetNumberOfLines()if lines != 0:m_sendFormat = self.m_choice_sendFormat.GetString(self.m_choice_sendFormat.GetSelection())global s_lastSendFormatif s_lastSendFormat == m_sendFormat:returnelse:s_lastSendFormat = m_sendFormat# Get existing data from textCtrl_senddata = ''for i in range(0, lines):data += str(self.m_textCtrl_send.GetLineText(i))# Convert data format according to choice_sendFormatif m_sendFormat == 'Char':status, data = s_formatter.hexToChar(data)if not status:self.m_textCtrl_send.Clear()self.m_textCtrl_send.write('Invalid format! Correct example: 12 34 56 ab cd ef')returnelif m_sendFormat == 'Hex':data = s_formatter.charToHex(data)# Re-show converted data in textCtrl_sendself.m_textCtrl_send.Clear()self.m_textCtrl_send.write(data)def sendData( self, event ):if s_serialPort.isOpen():lines = self.m_textCtrl_send.GetNumberOfLines()if lines != 0:data = ''for i in range(0, lines):data += str(self.m_textCtrl_send.GetLineText(i))# 添加代码开始# Make sure data is always in 'Char' formatm_sendFormat = self.m_choice_sendFormat.GetString(self.m_choice_sendFormat.GetSelection())if m_sendFormat == 'Hex':status, data = s_formatter.hexToChar(data)if not status:self.m_textCtrl_send.Clear()self.m_textCtrl_send.write('Invalid format! Correct example: 12 34 56 ab cd ef')return# 添加代码结束s_serialPort.write(data)# 函数功能实现def setRecvFormat( self, event ):lines = self.m_textCtrl_recv.GetNumberOfLines()if lines != 0:m_recvFormat = self.m_choice_recvFormat.GetString(self.m_choice_recvFormat.GetSelection())global s_lastRecvFormatif s_lastRecvFormat == m_recvFormat:returnelse:s_lastRecvFormat = m_recvFormat# Get existing data from textCtrl_recvdata = ''for i in range(0, lines):data += str(self.m_textCtrl_recv.GetLineText(i))# Convert data format according to choice_recvFormatif m_recvFormat == 'Char':status, data = s_formatter.hexToChar(data)elif m_recvFormat == 'Hex':data = s_formatter.charToHex(data)# Re-show converted data in textCtrl_recvself.m_textCtrl_recv.Clear()self.m_textCtrl_recv.write(data)def recvData( self ):if s_serialPort.isOpen():num = s_serialPort.inWaiting()if num != 0:data = s_serialPort.read(num)# 添加代码开始# Note: Assume that data is always in 'Char' format# Convert data format if dispaly format is 'Hex'm_recvFormat = self.m_choice_recvFormat.GetString(self.m_choice_recvFormat.GetSelection())if m_recvFormat == 'Hex':data = s_formatter.charToHex(data)# 添加代码结束self.m_textCtrl_recv.write(data)

  发送输入框格式切换功能实测如下,尤其是在Hex模式下,如果有异常输入,Jays-PyCOM会直接清屏,并在输入框里提示正确的示例。接收显示框格式切换功能雷同,但并不包含异常输入提示,因为这是个结果显示输出框。

JaysPyCOM_optimization_format_send.PNG

JaysPyCOM_optimization_format_send_error.PNG

1.4 启用菜单栏

  菜单栏是一个功能齐全的软件的标配,用于实现各种特性功能,此处痞子衡仅添加了一个“Help”菜单,用于显示Jays-PyCOM的主页以及作者信息。首先需要在wxFormBuilder添加menu控件,然后设置回调函数名,下面是回调函数的实现:

def showHomepageMessage( self, event ):messageText = (('Code: \n https://github.com/JayHeng/Jays-PyCOM.git \n') +('Doc: \n https://www.cnblogs.com/henjay724/p/9416096.html \n'))wx.MessageBox(messageText, "Homepage", wx.OK | wx.ICON_INFORMATION)def showAboutMessage( self, event ):messageText = (('Author: Jay Heng \n') +('Email: hengjie1989@foxmail.com \n'))wx.MessageBox(messageText, "About", wx.OK | wx.ICON_INFORMATION)

JaysPyCOM_optimization_menu.PNG

1.5 启用状态栏

  状态栏也是一般串口调试助手的标配,用于显示发送/接收数据统计信息以及串口开关状态,因此痞子衡为Jays-PyCOM也加上了状态栏功能,状态栏主要分为三栏:接收数据统计、发送数据统计、串口状态。

s_recvStatusFieldIndex = 0
s_sendStatusFieldIndex = 1
s_infoStatusFieldIndex = 2s_recvStatusStr = 'Recv: '
s_recvTotalBytes = 0
s_sendStatusStr = 'Send: '
s_sendTotalBytes = 0class mainWin(win.com_win):def openClosePort( self, event ):if s_serialPort.isOpen():s_serialPort.close()self.m_button_openClose.SetLabel('Open')# 添加代码开始self.statusBar.SetStatusText(s_serialPort.name + ' is closed', s_infoStatusFieldIndex)# 添加代码结束else:# 添加代码开始self.statusBar.SetFieldsCount(3)self.statusBar.SetStatusWidths([150, 150, 400])# 添加代码结束self.setPort()# ...self.m_button_openClose.SetLabel('Close')# 添加代码开始self.statusBar.SetStatusText(s_recvStatusStr + str(s_recvTotalBytes), s_recvStatusFieldIndex)self.statusBar.SetStatusText(s_sendStatusStr + str(s_sendTotalBytes), s_sendStatusFieldIndex)self.statusBar.SetStatusText(s_serialPort.name + ' is open, ' +str(s_serialPort.baudrate) + ', ' +str(s_serialPort.bytesizes) + ', ' +s_serialPort.parity + ', ' +str(s_serialPort.stopbits), s_infoStatusFieldIndex)# 添加代码结束s_serialPort.reset_input_buffer()# ...def sendData( self, event ):if s_serialPort.isOpen():lines = self.m_textCtrl_send.GetNumberOfLines()if lines != 0:# ...s_serialPort.write(data)# 添加代码开始global s_sendTotalBytess_sendTotalBytes += len(data)self.statusBar.SetStatusText(s_sendStatusStr + str(s_sendTotalBytes), s_sendStatusFieldIndex)# 添加代码结束else:self.statusBar.SetStatusText(s_serialPort.name + ' is not open !!!', s_infoStatusFieldIndex)def recvData( self ):if s_serialPort.isOpen():num = s_serialPort.inWaiting()if num != 0:# ...self.m_textCtrl_recv.write(data)# 添加代码开始global s_recvTotalBytess_recvTotalBytes += len(data)self.statusBar.SetStatusText(s_recvStatusStr + str(s_recvTotalBytes), s_recvStatusFieldIndex)# 添加代码结束

  状态栏实测功能如下:

JaysPyCOM_optimization_statusbar_info.PNG

二、界面优化

2.1 添加串口开关亮灯效果

  界面优化的地方有很多,痞子衡简单做了一个与串口开关按钮同步的小灯显示效果,当串口打开时,小灯显示绿色;当串口关闭时,小灯显示黑色;代码里的实现其实就是两张图片之间的切换。

class mainWin(win.com_win):def openClosePort( self, event ):if s_serialPort.isOpen():s_serialPort.close()self.m_button_openClose.SetLabel('Open')# 添加代码开始self.m_bitmap_led.SetBitmap(wx.Bitmap( u"../img/led_black.png", wx.BITMAP_TYPE_ANY ))# 添加代码结束else:# ...self.m_button_openClose.SetLabel('Close')# 添加代码开始self.m_bitmap_led.SetBitmap(wx.Bitmap( u"../img/led_green.png", wx.BITMAP_TYPE_ANY ))# 添加代码结束# ...

JaysPyCOM_optimization_led_switch.PNG

  至此,串口调试工具Jays-PyCOM诞生之软件优化痞子衡便介绍完毕了,掌声在哪里~~~

转:https://www.cnblogs.com/henjay724/p/9447077.html



推荐阅读
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • EPPlus绘制刻度线的方法及示例代码
    本文介绍了使用EPPlus绘制刻度线的方法,并提供了示例代码。通过ExcelPackage类和List对象,可以实现在Excel中绘制刻度线的功能。具体的方法和示例代码在文章中进行了详细的介绍和演示。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文介绍了机器学习手册中关于日期和时区操作的重要性以及其在实际应用中的作用。文章以一个故事为背景,描述了学童们面对老先生的教导时的反应,以及上官如在这个过程中的表现。同时,文章也提到了顾慎为对上官如的恨意以及他们之间的矛盾源于早年的结局。最后,文章强调了日期和时区操作在机器学习中的重要性,并指出了其在实际应用中的作用和意义。 ... [详细]
  • IOS开发之短信发送与拨打电话的方法详解
    本文详细介绍了在IOS开发中实现短信发送和拨打电话的两种方式,一种是使用系统底层发送,虽然无法自定义短信内容和返回原应用,但是简单方便;另一种是使用第三方框架发送,需要导入MessageUI头文件,并遵守MFMessageComposeViewControllerDelegate协议,可以实现自定义短信内容和返回原应用的功能。 ... [详细]
  • C#多线程解决界面卡死问题的完美解决方案
    当界面需要在程序运行中不断更新数据时,使用多线程可以解决界面卡死的问题。一个主线程创建界面,使用一个子线程执行程序并更新主界面,可以避免卡死现象。本文分享了一个例子,供大家参考。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 有没有一种方法可以在不继承UIAlertController的子类或不涉及UIAlertActions的情况下 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有