Bittly 串口调试助手是一款集串口设备调试、通讯指令管理、上位机控制面板绘制以及自动化测试和串口设备模拟等功能于一体的综合型调试工具,可以帮助开发者进行串口通讯协议设计、调试以及开发工作, 帮助测试人员检查串口数据收发情况,从而提高产品开发速度,简化串口通讯测试复杂度,并提高产品通讯稳定性。
Bittly 串口调试助手支持多种操作系统,可在 Bittly 官网 通过选择合适的操作系统即可。
通过浏览器下载时,可能会提示安全警告,请选择保留下载文件,否则可能无法正常下载 Bittly 串口调试助手安装程序。
在下载完成后,找到下载的安装包文件, 双击打开即可安装 Bittly 应用程序,在此之前,可能会出现 windows 的 SmartScreen 警告,如果您是正常从官网下载, 则正常运行即可。
安装完成后,可在桌面点击 “Bittly” 图标来启动 Bittly 串口调试助手并开始使用,需要注意的是, 在首次打开 Bittly 时, Bittly 会花费一些时间进行一系列的初始化操作,例如建立应用程序本地数据库,初始化应用配置,并创建默认项目等。
首次打开 Bittly 串口调试助手时, Bittly 会显示默认项目主界面, 界面结构如下图所示:
Bittly 串口调试助手由通讯连接、指令管理、上位机面板、自动化测试、自动化动作流程、设备模拟等功能模块组成;其中:
通讯连接
用于与串口设备建立串口连接, 在后续功能模块使用前, 都需要先进行通讯连接配置。指令管理
用于收藏与整理串口通讯发送数据内容以及响应内容解析规则。上位机面板
用于通过将通讯连接或指令绑定到UI组件来快速创建上位机操作界面。自动化测试
用于通过配置指令发送内容以及期待响应内容对比来验证流程中通讯数据是否正确。自动化流程
用于将固定的步骤或业务流程通过流程图的方式自动执行,并支持通过输入组件进行人工干预。通过选择左侧功能模块栏中的功能模块,便可在功能模块操作区对该模块进行操作,例如新建通讯连接, 新建指令或者新建上位机面板等。 同时对应的功能数据也会在该功能模块区域进行展示。
内容区域用于显示 Bittly 串口调试助手的主要工作内容, 例如在打开一个通讯连接时,这里将会显示通讯连接界面, 在打开一个指令或者面板时,内容区域则用于显示对应的指令内容或上位机面板内容。 当打开多个内容时, 可通过上方内容页标签进行切换,关闭或者关闭所有。
底部状态栏用于显示当前Bittly 串口调试助手的运行状态, 例如当前打开的串口连接列表或者正在运行的设备模拟器列表等,以及左侧用于显示应用其他帮助信息,例如如果该项目被推送到服务器,则当其他成员更新指令或面板时,这里会收到项目变更通知等。
顶部菜单栏则用于进行 Bittly 串口调试助手的应用管理, 例如应用配置,项目切换,环境变量切换等。
首先切换到通讯连接功能模块来新建一个通讯连接:
在各种通讯类型中选择串口通讯便可以新建一个串口通讯连接:
在串口通讯连接配置界面,我们可以通过右侧配置栏来配置串口通讯的各种信息,例如基础连接信息,包括串口号, 波特率,数据位,停止位,校验位等。 以及下方更多高级设置, 例如通讯连接脚本可以在数据发送和接收时进行自定义数据处理、分帧方式可以配置在接收到串口数据时如何进行数据分帧以方便数据查看以及后续处理、串口数据转发可支持将通过该通讯连接收到的数据内容转发到其他通讯连接上,并且转发支持转发到网络、蓝牙、Websocket 等其他支持的通讯连接方式上。
这里我们仅配置基础的通讯连接参数, 其他的采用默认即可。 在配置完成后可通过右上方保存按钮保存当前通讯连接配置,以下次或者被其他地方引用,例如指令,面板或者自动化测试等。 然后点击启动按钮即可打开串口,接下来我们便可以像其他串口调试助手一样通过手动输入内容的方式来发送串口数据内容 :
默认情况下 Bittly 串口调试助手并没有处理数据分帧, 当数据接收数据间隔时间极短时, 可能造成两次收到的数据被当作一次进行显示, 又或者因为数据过长导致原本一帧数据被分成两次来接收, 例如:
对于这种问题,可通过 Bittly 串口调试助手的分帧方式配置来解决,以第一种情况为例, 假设我们的每帧数据固定为10个字节, 则我们可以选择分帧方式为固定长度,并将长度选项这是为10, 配置完成后保存重新打开串口连接即可:
对于过长的数据被分割成两帧数据,我们假设两帧数据之间至少间隔100ms, 那么我们可以通过设置分帧方式为超时,并将超时时间参数设置为100即可。 这样只要间隔在100ms内发送的数据都将被合并为一帧数据; 当然,又或者我们有固定的帧头帧尾标记, 那么我们便可以设置分帧方式为匹配头尾, 然后填入相应的帧头字节或帧尾字节即可, 这里我们以帧头 AA
,帧尾 FF
为例 :
Bittly 串口调试助手支持的数据分帧方式不只上述方式,还有换行、正则表达式、JSON、XML 等, 对于更加复杂的分帧方式, 更是可以通过脚本的 onData
回调来进行处理,从而实现更加自由准确的数据分帧。
当需要定时向设备发送心跳数据时, 我们可以通过 Bittly 串口调试助手的心跳配置来配置需要发送的内容,这样便可以实现自动发送心跳数据,又不影响正常数据通讯, 例如:
但需要注意的是,如果发送心跳数据后, 设备有对应的响应内容,在默认情况下 Bittly 不会进行处理,目前只能通过脚本回调函数来进行忽略。
Bittly 串口调试助手支持将串口数据转发到其他通讯连接上,而不论目标通讯连接是TCP, UDP,又或者是经典蓝牙, 只需要目标通讯连接支持接收和发送二进制数据即可, 即只要支持通讯连接所对应的数据格式即可在通讯连接间相互转发。
这里我们以串口数据转发到 TCP 为例, 我们先新建 TCP 连接用于进行转发操作, 例如:
配置完成后便保存该连接,接着返回到我们最开始的串口通讯连接,并配置转发目标, 将转发目标选择为刚才配置的 TCP 连接, 例如:
这样配置完成, 当前串口通讯连接所有收到的内容将会被转发到目标TCP连接上。
但需要注意的是,如果 TCP 连接收到了来自服务器的数据内容, 这个时候并不会主动发送给我们的串口连接。 那么,如果我们需要在 TCP 连接收到来自服务器的数据时同时发送到串口设备,我们只需要在 TCP 通讯连接的转发配置中将转发目标选择为当前串口连接即可, 例如:
如果接收的串口数据量比较大或者时间比较长, Bittly 串口调试助手为了保持正常运行而回仅保存大小的固定的数据量,以保持数据处理的稳定性以及持续性。 那么, 如果需要保存所有收到的数据内容, 可通过 Bittly 串口调试助手的重定向功能将所有接收到的内容写入到文件中以保证数据不丢失。
配置重定向功能仅需要选择目标文件存放路径即可,例如:
当发送的内容需要经常被重复使用时, 可通过指令管理来将发送的内容作为指令保存起来,后续再次发送时则不再需要编辑内容,而是通过已保存的指令直接发送即可, 并且指令管理支持文件夹创建, 您可通过指令文件夹来分类管理您的串口指令。除此之外,Bittly 串口调试助手的指令能够更加方便的发送内容复杂的通讯数据和解析接收到的响应数据。您可以通过多种参数编辑器来构建复杂的参数内容,从而不再需要手动进行进制转换或者数据校验; 并且通过不同的数据响应解析方式来更加方便的查看接收到的响应内容。
在 Bittly 串口调试助手中, 指令是用来发送数据和接收响应内容并解析的一种方法。 如果通讯协议是基于请求-响应这种交互模式,例如 Modbus-RTU 这种一问一答的模式,则可以使用指令来进行管理通讯协议中的每个接口或者API或者交互命令。但是,对于仅仅用来接收数据也同样可以适用,毕竟只需要将发送的参数设置为空即可。 不对对于类似于消息通知或者需要监听类型的交互方式则不适合使用 Bittly 的指令功能来进行管理。
Bittly 串口调试的指令操作界面可以分为四个部分,从上到下一次为指令配置区,通讯目标配置区,请求参数编辑区以及响应内容查看区域。
我们以串口为例,在默认情况下, 新建指令后 Bittly 串口调试助手会将指令参数编辑器设置为文本编辑器,这里可使用编辑器切换下拉框来进行编辑器切换。
这里我们切换到 HEX 编辑器来演示如何动态发送请求内容:
在编辑器中,我们可以通过 {{ }}
实现函数调用,变量引用以及循环或者判断控制,例如,如果我们需要将下方伪代码结构体作为参数内容发送给设备:
struct {
uint8 head = 0xFF; // 帧头标记
uint16 deviceId = 100; // 设备ID, 十进制100
uint8 command = 0x01; // 操作码
struct { // 请求参数内容
int16 temp = 43; // 目标温度
}
}
那么,如果我们手动计算的话,则需要将100转为十六进制,以及将43转为十六进制。 但是使用 HEX 编辑器的话, 我们可以通过内置函数来实现自动转换,则我们在函数编辑器中内容如下:
FF {{ uint16BE(100) }} 01 {{ int16BE(43) }}
其中 {{ uint16BE(100) }}
是调用 uint16BE
函数将100 转为uint16 十六进制表示并且以大端模式进行处理。 {{ int16BE(43) }}
则是使用 int16BE
函数将 43 转为int16 的十六进制表示。
但是,这么看起来时间久了仍然不记得这是什么意思,那么,我们可以通过 {{* xxx *}}
来给请求参数进行注释说明,例如:
FF {# 帧头 #}
{{ uint16BE(100) }} {# 设备ID #}
01 {# 操作码 #}
{{ int16BE(43) }} {# 目标温度 #}
Bittly 串口调试助手在执行指令时,对于请求参数的构建完全交由请求参数编辑器来进行处理, 这里的HEX编辑器会首先将输入的内容进行编译, 编译完成后得到完整的十六进制字符串,然后将十六进制字符串打包成二进制数据传递给通讯连接,最后由通讯连接发送到目标设备。
当请求参数内容更加复杂时,使用十六编辑器就有点不太合适了,即使注释写的足够详细, 但是如果遇到需要计算校验值或者其他操作, 那么使用结构体编辑器则更加适合。
假设我们的串口通讯指令格式伪代码定义如下:
struct {
uint16 head = 0xFFFF; // 帧头
uint16 moduleId = 1; // 模块ID
uint16 commandId = 0; // 操作码
uint16 dataLength = 0; // 数据长度
struct data {
uint8 servoId = 0; // 电机ID
uint16 position = 100; // 目标位置
} ;
uint8 checksum; // 校验码
}
则使用结构体编辑如下:
这样,我们便可以将结构体中的属性名称直接填入结构体编辑器中的名称栏,并选择对应的数据格式,然后输入需要发送的值内容。 如果需要针对属性进行详细说明,则直接编辑属性描述信息即可。
由于结构体属性支持子属性, 所以对于 data
这种子结构体也能够提供很好的支持, 只需要在数据类型中再次选择结构体即可编辑对应属性的子属性。
同样的, 对于属性值编辑, 结构体编辑器同样支持使用 {{ }}
来调用函数或者引用变量。
另外,在结构体编辑器中, 还提供了 $
函数来根据索引或者名称引用对应的属性, 从而实现调用函数时进行引用结构体中的属性值。例如 $(1)
则是引用第一个属性 head
, 其作用和 $('head')
效果类似。
在指令执行时,结构体编辑器会根据已经定义的属性列表进行数据打包,并将最终的二进制数据传递给串口通讯连接实例来发送到设备。
最后,我们以 checksum 属性来说明一下如何编辑结构体属性。
首先属性名称填入 checksum
, 需要说明的是,属性名称并非必填项, 当属性名为空时可通过索引使用对应的属性。
接着,checksum 的数据类型为 uint8, 我们可以通过数据类型的下拉框来选择对应的数据类型 :
由于checksum 的值是根据其他属性计算得来, 这里我们直接使用内置的函数来计算校验值:
需要注意的是, 该函数返回的值是一个十进制数值, 所以变量值前面的数据格式我们改成了 DEC
表示该属性值以十进制来进行打包处理,如果依然使用 HEX
格式进行打包,假设计算出的校验值为 100
则该值会被作为十六进制字符串进行处理, 即 0x0100
, 这样就超出了数据类型 uint8
的表示范围,从而导致数据打包失败。
最后,我们将描述填入,说明一下校验值的取值方式, 描述部分也不是必填项,仅在需要时对属性进行更详细的说明。
到这里便完成了结构体一个属性的定义, 虽然看起来有点繁杂, 但对于后续需改参数或者生成文档来说, 这里还是值得的 ~~~ 毕竟修改参数时我们无需重新计算,只需要需改特定的值内容即可。
我们将完整的结构体发送至串口设备,并查看设备实际收到的内容:
如果请求参数为文本格式,但是内容格式比较复杂, 并且每次修改的时候我们仅需要修改其中的某个部分。 例如:
servo rotate 200 100
假设上述指令为设置电机以100的速度旋转200步, 那么我们仅仅需要修改的部分为最后的参数, 即 100
和 200
。 如果每次修改的时候都要修改修改字符串,或者时间长了我们已经不记得100是最高速还是平均速度了的时候,这个时候如果使用文本参数编辑器就有点不好办了, 所以这里 Bittly 串口调试助手推荐使用文本模板来创建该类型的请求参数, 以上述指令为例, 使用 Bittly 串口调试助手的文本模板参数编辑器则为 :
这样, 需要变更的部分我们以 {{steps}}
和 {{speed}}
进行替换,后续我们需要修改步数或者速度,则仅需要修改下方变量值即可。
同样的,在文本模板中,使用 {{ }}
也可以调用函数或者引用外部变量。 而类似 {{ steps }}
这种则是应用下方配置的变量列表中的变量,在指令执行时, Bittly 串口调试助手会将文本模板进行编译, 在编译完成后再将编译后的文本内容传递给串口通讯连接发送到串口设备。
当 Bittly 串口调试助手收到串口指令响应数据后, 会将响应数据传递给当前的响应查看器来进行数据展示, 不同的通讯方式其对应的响应内容查看器也会用所不同, 所以这里以串口为例进行说明。 在默认情况下, Bittly 串口调试助手会将数据流查看器作为默认查看器来展示发送和收到的数据内容 :
当然,我们还可以切换到其他的响应查看器, 例如这里我们切换到十六进制响应查看器:
同样的,如果请求参数使用结构体来构建, 那么对应的响应内容应该也足够复杂, 这里我们以一个响应示例内容举例说明如何解析复杂的响应内容, 我们仍然以让电机移动指定步数为例,并且该指令的响应内容和请求内容一致 :
struct {
uint16 head = 0xFFFF; // 帧头
uint16 moduleId = 1; // 模块ID
uint16 commandId = 0; // 操作码
uint16 dataLength = 0; // 数据长度
struct data {
uint8 servoId = 0; // 电机ID
uint16 position = 100; // 目标位置
} ;
uint8 checksum; // 校验码
}
那么,我们首先切换到结构体查看器:
当该指令未创建结构体解析规则时,我们会看到结构体的编辑界面,这里同结构体参数编辑器一样需要我们手动针对每个属性进行配置。 不过与请求参数编辑器不同的时, 参数编辑是用来构建内容, 而这里的编辑器是已经有了二进制内容来编辑如何解析这一段二进制数据。
我们点击创建新的属性按钮来开始添加属性,完成后的配置如下:
配置完成后,我们便可以切换到查看模式来准备查看解析出来的数据内容, 如果解析内容为空,可再次执行一次指令即可:
需要注意的是,当收到的数据不足以填充结构体时, 则仅仅会显示部分解析出来的结果。 而如果收到的数据内容超过结构体所能够解析的长度,则默认会仅显示第一次解析出来的数据内容,除非启用的 “解析到末尾” 的选项。
对于 “解析到末尾”, 假设我们的解析规则为 三个 byte 属性, 而我们收到了四个字节分别为 0A 0B 0C 0D
, 那么, 0A 0B 0C
会被完整解析,剩余字节 0D
则会放到第二次进行解析, 由于我们启用了 "解析到末尾" 的选项, 所以在最终显示的时候就仅仅显示了第二次仅解析 0D
的结果。如果没有启用 "解析到末尾" 则会显示 0A 0B 0C
的完整解析结果。
如果指令响应内容需要多次解析, 例如指令发送后设备持续发送内容,而 Bittly 串口调试助手收到的内容包含多个结构体数据帧, 虽然我们可以使用查看模式来实时查看最新的解析结果。但是如果希望查看所有解析结果, 那么便可以切换到结构体查看器的列表模式进行查看, 例如:
在列表模式中,会将所有解析到的结构体展示出来, 从而更加方便的进行数据查看与比较。
如果我们需要将 Bittly 串口调试助手收到的响应内容解析后绘制成折线图来更加方便的查看数据变换,则可以使用绘图响应查看器。
假设我们收到的数据是这样子的:
01 02 03
04 05 06
07 08 09
...
然后我们希望第一组 01 02 03
分别对应三条直线频道1
, 频道2
以及频道3
, 同样第二组 04 05 06
也分别对应三条直线频道1
, 频道2
以及频道3
, 第三组,第四组, ... 以此类推, 则我们可以使用字节流来解析收到的数据内容。
首先我们选择解析方式为字节流,如下:
接着在弹出的对话框中设置数据类型为 uint8, 频道数量为3。 这样所有收到的数据内容将会依次按照 uint8 来读取, 然后分别填入三条直线中, 例如:
使用字节流对单一数据类型的数据很方便, 但是如果收到的数据内容中包含多种数据类型, Bittly 串口调试助手仍然能够正常解析。 当没有定义解析结构体时,我们可以使用 HEX 匹配这种解析模式来解析一些简单的二进制数据, 但对于比较复杂的数据结构类型,这里还是推荐使用结构体来解析,这样会更加。
假设我们定义的解析结构体如下:
这样我们收到内容后可以自动解析出水位和温度等数据, 在这里我们需要同时将水位和温度放到折线图中。 首先选择绘图解析器为结构体,然后点击右侧配置按钮弹出结构体对话框:
在对话框中,我们需要指定将那些属性放到绘图中,并且需要指定频道名称, 当然默认情况下频道名称会自动生成, 但仍然可以手动进行修改,这里我们将水位和温度放到折线图中:
保存配置后我们重新执行指令来查看绘图情况:
如果指令每次仅仅响应一次,需要多次请求才能获取到多个结果实现折现图展示效果, 那么我们可以取消 “执行新请求时清除绘图” 这个开关, 这样我们便可以多次执行指令而不清除绘图的结果,并且每次执行指令响应后都会自动更新绘图; 另外如果指令是一直发送数据来进行解析,则需要切换到指令的数据流模式才可以持续接收数据并进行绘图操作。
如果响应内容为纯文本,并且数据是通过某个特定的字符来分割, 则可以使用文本来解析。 但是如果文本内容比较复杂一些,并存在一些辅助内容, 那么我们可以通过正则表达式来进行匹配,通过匹配出的内容进行数据绘制。
首先选择解析器为正则表达式,然后点击右侧配置按钮弹出配置对话框:
在匹配模式中填入正则表达式内容,并通过 ?<>
来指定频道名称, 例如:(?<age>\d+)
则可以将 age
作为一个折线频道添加到绘图中。
匹配模式完成后,我们可以在下方的测试文本框中输入我们收到的数据内容进行匹配测试,如果匹配成功则会在下方显示匹配出的数据,如果匹配失败则会显示相应的错误信息。
最后我们保存配置,重新执行指令:
在通讯连接和通讯指令配置完成之后,如果在调试过程中需要经常来回切换多个指令,或者手动发送一些内容, 这样子的话还是有些不方便, 又或者对于一个刚刚接触项目的人来说, 面对众多的通讯指令,貌似无法知道应该先调用哪个后调用哪个。 所以, Bittly 串口调试助手通过上位机面板功能模块来解决这个问题。
Bittly 串口调试助手的上位机面板功能是通过将通讯连接或通讯指令与 UI 组件进行绑定连接。 例如我们有一个 “设备初始化”指令,我们拖拽一个按钮,并将按钮点击的动作配置成执行 “设备初始化” 指令, 那么,后面只要我们点击这个按钮就可以直接发送“设备初始化” 指令,而不需要从指令管理中再去查找这条指令,然后再去执行这种麻烦操作。
Bittly 串口调试助手的上位机控制面板由编辑模式和运行模式组成。编辑模式用于编辑面板内容,例如放置按钮,下拉框等组件位置或者如何布局。 面板运行模式则是用于执行已经配置好的上位机面板实例。
我们从最开始的按钮示例来说明如何实现将指令绑定到按钮上并点击执行指令。
首先我们新建一个面板,我们切换到面板模块,在面板模块的功能操作区点击加号即可新建一个空白的上位机面板。 由于新建的上位机面板为空, 所以 Bittly 串口调试助手会自动将面板切换到编辑模式 :
然后我们在面板的右侧的组件列表中点击 基础
分组, 然后将按钮拖拽到面板的合适位置进行放置 :
放置完成后我们便可以在右侧操作栏看到当前按钮的配置信息, 我们在配置信息中找到事件分组,然后将 点击
事件的处理器选择为指令 :
接着我们点击指令后方的 “未选择” 按钮来选择我们需要执行的指令,以最开始的示例为例, 在弹出的指令配置对话框中我们选择 “设备初始化”指令, 选择完成后如下:
这将会显示指令的请求参数编辑器以及指令响应内容解析器配置, 如果我们不需要修改指令参数, 则直接点击确定即可。
配置下方的响应解析用于将指令执行后收到的响应内容解析到变量,现在我们不关心指令响应内容,所以这里选择 无
, 这样我们便可以忽略掉指令响应内容。
到这里便全部配置完成了, 我们点击保存按钮来保存面板。 提示保存成功后,我们切换到运行模式即可查看该面板 :
在运行模式下,我们点击按钮即可执行我们所配置的 “设备初始化” 指令。
在 Bittly 串口调试助手中, 每个能够触发事件的组件都可以配置相应的事件处理器, 这些处理器包括执行指令、执行脚本、为变量赋值或者执行函数等, 这样我们便可以通过拖拽不同的组件来实现不同的操作功能, 从而更加方便快捷的构建上位机面板。
在前面的例子中我们说明了如何绑定指令到按钮,如果我们需要执行一个需要实时传递变化的参数的指令,比如调整小车方向或者水位警告高度等,那么又应该如何配置呢? 这里我们就来说明如何获取组件的值并传递给指令。
这里我们以改变电机速度为例,我们的指令配置如下:
在指令中, 电机速度
参数用于填写需要设置的速度, 并且最大值为1024,最小值为0。 我们需要实现的是当我们滑动滑动条的时候能够自动调用指令并改变速度, 并且滑动条的值自动填入指令的 电机速度
参数。
首先,我们先新建一个空白面板,并将滑动条组件从组件列表的数据输入分组拖放到面板合适位置:
接着我们在右侧的属性配置栏的事件中找到 滑动
事件进行配置, 该事件会在滑动条发生变化时执行相应的动作。 需要注意的是,由于活动条变化频率过高, 所以这里组件增加了一个防抖的操作。
将滑动条的滑动事件操作选择为指令,并点击指令选择按钮进行指令配置:
在请求参数配置中,我们需要将 电机速度
的值改为当前滑动条的值, 这里我们可以用到 $value
这个变量 :
$value
变量是由滑动条组件提供, 用于表示当前滑动条组件的值。 不同的组件都会有不同的内置变量用于表示不同的状态值, 不过大部分都是使用 $value
来表示当前值。
配置完成后我们保存面板,并切换到运行模式试一试效果:
如果一条指令在执行时需要传递多个参数,例如驱动电机前进指定步数的同时还可以设置速度。 所以从界面上来看,应该是一个数值输入框用于输入步数, 一个滑动条用于输入速度, 最后再加一个按钮用来提交执行, 现在我们来实现这个控制面板。
首先,我们再次新建一个空白面板,然后将数值输入框和滑动条从组件列表的数据输入分组拖放到面板合适位置。并将按钮组件从基础分组里拖放到面板合适位置, 这样便完成了 UI 的布局:
由于我们需要传递多个参数,那么实现的方式有两种, 一种是直接引用组件的值,另外一种是通过变量的方式来间接引用。
首先我们先演示下直接引用组件值,引用组件值是通过找到组件实例,然后调用其方法来实现的,在指令配置中,我们可以使用 $widget(id)
来获取组件实例,然后通过 .value()
的方法获取组件值。 例如,如果我们设置步数输入框的id为 numSteps, 则获取步数值的方式为 : $widget("numSteps").value()
。 需要注意的时, .value()
方法是大部分组件获取其值的方法,但有些特殊的组件有其特有的获取值的方式, 这个查询对应组件的使用手册来获取。
组件 ID 设置方式如下, 我们先点击步数数值输入框使其处于激活状态, 然后在右侧属性配置区域的最顶部可以修改其id值:
同样的方式修改速度滑动条组件的值为 sliderSpeed
, 完成后我们便可以配置按钮点击时的指令参数, 如下:
这样我们便完成了通过组件ID直接引用组件值的方式, 我们保存面板然后切换到运行模式来试一试效果:
另外一种传递多个参数的方式便是使用变量来临时存储一些数据,然后在通过指令参数配置时进行引用。 我们仍然以上述指令为例。
首先我们将刚刚创建的面板切换会编辑模式,然后在右侧配置区域的变量区创建两个变量,分别用来存储速度和步数。
其中变量的数据类型和默认值我们都选择数值和0,以方便变量初始化和后续操作赋值。
接着,我们点击步数的数值输入框, 然后在右侧输入框配置的事件区域的变更事件选择处理方式为 变量
, 并下拉后面的变量选择框先择变量 转动步数
:
如此配置完成后, 当输入框中的值发生变化则会执行变量赋值的操作, 将输入框当前的值赋值给变量 步数
。
使用同样的操作,我们将滑动条的滑动事件处理器设置为为变量 速度
赋值。
最后我们修改按钮的点击事件, 重新配置指令, 将参数从应用组件改为引用变量:
其中的 $var
则是用来引用变量的函数,只需要填写对应的变量名称即可。
最后我们保存面板,切换到运行模式查看效果:
之前我们在使用 Bittly 串口调试助手的面板时都是在写入写入数据, 例如跟新配置,或者发送一些响应无关的指令。 但是还有一种情况就是我们需要从设备读取一些内容, 或者说我们需要将串口指令响应内容解析出来留着我们后续使用。 还是以我们之前的电机项目为例,假如我们需要显示电机当前速度,那么我们就需要发送一个读取的指令,然后将响应的速度放到变量中, 最后显示出来,这就是这一节我们需要说的内容。
首先,我们还是新建一个空白面板,然后新建一个变量 速度
用于保存解析后的结果。 并且我们再加一个按钮用来执行获取当前速度的指令 :
再按钮指令配置时我们需要配置指令解析方式, 在此之前, 该指令的结构体解析配置如下:
那么,再按钮指令解析时,我们选择使用结构体来进行解析,然后我们需要映射结构体中的属性到我们的面板变量中:
到这里便完成了指令解析并赋值到变量的操作, 我们保存配置并保存面板。 然后切换到面板运行模式查看一下配置效果:
在面板运行过程中,我们可能需要实时监测某个变量的值的变化或者输出一些日志消息, 这个时候我们可以使用日志查看组件来实现该功能, 日志输出组件用于监视变量,并根据监视类型来输出日志消息或者变量变化:
现在我们不再新建面板,而是继续使用上一个示例的面板,切换到编辑模式,并从组件列表的数据输出分组将日志查看组件拖放到面板合适的位置 :
接着,我们在日志输出组件的配置项目中配置日志数据源。 对于 Bittly 串口调试助手的输出组件来说, 输出组件的数据源即为变量, 当变量发生变化时将会由监听它的组件来实现对应的操作,例如输出变量内容或者更新组件值等。
日志输出组件支持配置多个数据源, 即支持同时监听多个变量,当这些变量发生变化时则将变量内容进行输出或者进行变量值对比后输出。
首先点击添加按钮,在弹出的数据源配置弹框输出数据源名称,用于标记日志消息前缀。然后配置日志记录类型,当类型为“消息记录”时则变量内容作为日志消息输出,当类型为“变量监视”时则当变量发生变化时输出变量变更提示。
当数据源项目添加完成后,再选择数据源需要监听的变量, 这样便完成了数据源的配置。 如果需要添加多个数据源,则重复上述步骤即可。
这样,当变量发生变化时则会通过日志输出组件进行展示,我们保存面板,然后切换到运行模式查看效果:
有时候我们可能需要每隔一定的时间来自动执行某条指令,比如前面的示例所说的获取电机当前速度,可能我们需要每秒钟读取一次速度并将其显示出来。 但是,如果通过按钮组件人工每隔1秒点击一次来执行指令的话,那效率实在是太低了,而且过于麻烦了。 所以在 Bittly 串口调试助手的面板中, 可以使用定时器组件来实现定时循环执行某个指令。
我们依旧使用之前的面板来继续修改, 首先切换到面板的编辑模式,然后从组件列表中的其他分组中将定时器组件拖拽到面板合适位置:
接着,我们在右侧配置区域配置一下间隔时间为1000, 需要说明的是,这里的时间单位是毫秒。 执行限制下拉选择无限制,这样只要定时器启动后将会一直执行下去, 如果我们只需要固定执行指定次数,则使用固定次数,并设置执行次数即可, 这里我们选择无限制执行。
然后我们需要配置定时器需要循环执行的操作,我们在事件配置区中配置定时动作为指令类型,然后选择并配置我们的指令, 最终配置项如下:
其中指令配置可参考之前的例子进行配置,这里不再说明。 到这里后,我们便可以保存面板切换到运行模式查看效果:
由于我们在配置时没有打开定时器的自动启动选项,所以这里需要手动点击来打开定时器。
当配置了定时器后,我们每隔1秒来获取一次当前电机速度。 那么直接通过日志组件输出速度值虽然能看。但效果不是很好,因为我不知道当前速度处于一个什么状态,是太高了还是太低了,又或者是其他什么情况。 而对于速度这种数据来说,使用仪表盘来显示是最恰当不过了, 所以这里我们就再加一个仪表盘来一直显示当前速度。
同样使用之前的面板,我们切换到编辑模式。 从组件列表的数据输出分组中将仪表盘拖放到面板合适位置:
接着我们对仪表盘进行数据源配置,仪表盘组件通过监听数据源变量来实时显示对应指针的位置。 虽然仪表盘组件支持多个数据源,但是这里我们仅配置一个,用于显示当前速度值。
另外,由于我们的速度限制为0~1024, 所以我们同样需要在最大值和最小值那里配置一下速度范围, 则最终的配置如下:
这样,我们便完成了仪表盘的配置。 当速度变量发生变化时,仪表盘的指针也会同时跟着发生变化 :
最后,我们可能还需要将当前速度通过折现的方式来观察其变化过程。 这里通过Bittly 串口调试助手的折线图组件来实现即可。 同仪表盘一样, 折线图组件也属于输出组件, 我们仍然使用之前的面板, 切换到编辑模式, 然后将折线图组件从组件列表中的数据输出分组拖放到面板合适位置 :
接着配置折线图的数据源, 折线图同样支持多个数据源, 每增加一个数据源便会对应增加一条折线。 这里我们只需要显示当前速度, 所以使用默认数据源。
数据源配置完成后,我们保存面板,并切换到运行模式查看效果:
当设备流程比较复杂时,人工手动测试往往会遗漏某个步骤或者某个特定的测试条件,所以这里便可使用 Bittly 串口调试助手的自动化测试功能来完成对设备的自动化的测试。 Bittly 串口调试助手的自动化测试分为针对指令的单元测试和针对流程的功能测试两部分。
在 Bittly 串口调试助手中,针对指令的单元测试是通过对所选指令发送不同请求参数内容并进行验证其响应内容是否与期待值匹配。
要在 Bittly 串口调试助手中创建单元测试,首先切换到测试功能模块,然后在模块操作区选择单元测试, 接着在指令列表中选择需要进行测试的指令,并打开单元测试内容页:
点击 “创建测试用例” 按钮为该指令新建一个测试用例,在打开的弹框中编辑测试信息 :
根据我们的需要可任意修改测试用例的名称与描述信息,这样方便其他测试者了解该测试用例内容。
接着切换到 “请求参数” 编辑页 :
在这里,我们需要修改指令执行时的请求参数,比如一些边界值等。 请求参数编辑完成后,我们再切换到 “期望结果” 配置页来配置指令响应的匹配规则 :
这里由于我选择的指令响应解析配置了结构体,所以这里的验证方式便使用 “结构体” 进行验证。
配置结构体验证时, 需要选择哪个属性进行什么样子的匹配规则,例如 :
这样配置完成后,便可以保存测试用例来执行。
在指令执行时, 会将测试用例编辑的请求参数打包发送给串口设备,并在指令响应后, 根据匹配规则进行响应内容的验证。 当匹配成功时则显示测试通过,例如:
或者匹配失败时则会显示出具体的匹配失败原因, 例如:
当需要将多个测试步骤组合起来时则可以使用 Bittly 串口调试助手的功能测试。 功能测试是通过将一系列步骤进行搭配组合来实现一个完整的业务流程或测试流程。在组合这些测试步骤时可执行多个指令、自定义循环次数、以及验证规则。
现在我们来创建一个功能测试实例, 首先我们切换到测试模块, 选择功能测试标签,在下方工具栏点击加号按钮来创建新的测试用例:
假设我们需要执行获取当前电机速度的指令, 那么我么在右侧指令列表中将获取当前速度指令拖放到步骤列表即可:
指令添加到步骤之后,我们需要对指令进行配置,由于获取当前速度并不需要特殊参数,所以对于参数部分我们并不需要修改, 但是在获取了当前速度之后我们需要验证一下电机速度是否在一个合理的范围内。 那么,我们首先切换到指令的响应验证标签来配置验证规则:
由于我们电机速度取值范围是0~1024, 我们这里只要确保获取的速度在这个区间即可。
指令配置完成后,我们保存该测试用例,然后切换到运行模式来执行一次看下效果:
在我们的测试过程中,往往需要记住一些中间值来方便后续使用。 在 Bittly 串口调试助手中, 可使用变量来完成这个操作, 指令执行完毕后, 可通过解析规则将解析出的属性赋值到对应的变量中, 从而方便测试用例后续使用。
我们继续修改我们的测试用例, 之前我们已经在测试用例中添加了一个获取当前速度的步骤, 接着,我们需要将当前速度存储到变量 当前速度
中。
首先,我们切换测试用例到编辑模式, 然后修改刚刚配置的指令执行步骤中的响应解析配置:
接着,我们将解析方式选择为结构体,并点击结构体映射表格右上角的加号按钮增加结构体属性到变量的映射规则:
如此,我们便完成了指令响应内容解析到变量的操作,现在我们可以保存指令并回到运行模式再次看下执行效果:
除了通过指令响应解析外,Bittly 串口调试助手还支持手动为变量赋值。 我们再次将测试用例切换到编辑模式,然后将变量赋值步骤拖放到测试用例步骤列表中, 最后点击赋值表格右上角加号添加赋值操作:
在变量赋值时,赋值模式有表达式和模板两种方式。 其中 表达式
是将表达式执行结果赋值到变量,其数据类型有表达式计算结果决定。 而模板模式则是将赋值的内容作为字符串模板,并通过编译模板后将最终的字符串赋值给变量,例如:
赋值操作完成后,我们保存测试用例,然后切换到运行模式查看一下运行结果 :
对于变量赋值,除了通过指令响应解析, 手动赋值之外,还支持脚本赋值。 那么我们便需要在必要的时候验证一下变量的值是否满足我们接下来的步骤执行。 那么我们便需要对变量进行匹配验证。
我们继续编辑之前的测试用,然后对我们手动赋值的变量进行验证。
将测试用例切换到编辑模式,然后将变量验证步骤拖放到测试步骤的合适位置:
接着,我们在变量栏中通过下拉选择需要验证的变量, 接着选择操作用用来指定我们在进行变量匹配的时候应该如何操作, 最后输入期待值, 即在匹配时的时候我们希望变量匹配的内容是什么。 例如:
配置完成后,我们再次切换到运行模式查看一下运行效果:
在 Bittly 串口调试助手的功能测试执行时,只要前一个步骤执行完毕并且没有错误则会立即执行接下来的步骤。 那么如果我们希望间隔一定时间在执行,则可以使用延时等待这个测试步骤来实现。
比如,我们希望间隔5秒后重新获取当前电机速度,则可以在第一次获取完毕后加入延时等待步骤,接着再次添加当前速度获取指令。
我们重新新建一个测试用例,并拖放两次获取电机速度的指令并配置步骤执行属性, 接着从步骤列表中拖拽延时等待步骤到执行步骤列表的合适位置:
延时等待的时间配置为一个表达式,可以任意填写一个合法的表达式,或者简单的来说, 直接填写一个数值就行。 需要注意的是,这里的时间单位是毫秒, 这里我们填写5000来延时5秒钟。
延时配置完成后,我们保存测试用例,并切换到运行模式查看一下效果:
如果我们的测试需求是连续取5次当前速度, 并检查是否在有效范围内。 那么如果我们手动配置执行步骤5次的话,不论是后续维护还是实际操作起来都是个大麻烦。 所以 Bittly 串口调试助手在功能测试时提供了循环指定步骤的支持。
首先,我们再次新建一个测试步骤,然后将计数循环拖放到测试步骤执行列表中。 接着指定循环次数为5次。
接着我们为计数循环步骤添加子步骤,在循环时,所有在计数循环步骤下的子步骤都将会被循环执行。
在子步骤中,我们添加当前速度读取的指令以及1秒中的延时等待:
在配置完成子步骤后,我们保存测试用例,然后切换到运行模式查看执行效果:
和固定次数循环不同的是, 条件循环会在每次执行循环体之前检查循环条件是否成立。 如果循环条件不成立,则停止循环而继续执行后续的步骤。
我们再次新建一个空白测试用例,然后新建一个变量赋值为0, 并且当变量小于5的时候执行循环操作。
条件循环的条件表达式可调用测试用例运行时函数, 例如,我们可以使用 $var(name)
函数来获取变量值。 那么我们的循环条件即为 : $var("循环次数") < 5
在循环体中,我们更新变量值,使其每次循环增加1,并且延时1秒中:
到这里我们的测试用例便配置完成了,我们保存测试用例并切换到运行模式查看一下效果:
在测试用例运行过程中,我们可能会关注一些变量或者一些值的输出,但变量列表面板无法查看历史数据,所以我们可以使用 Bittly 串口调试助手的 内容查看
步骤来实现该需求。
我们新建一个测试用例,并创建一个变量,并赋值为100 :
然后我们拖拽内容查看步骤到测试用例执行步骤列表中, 并点击内容查看表格右上角加号增加两个查看项目 ,分别使用变量和表达式两种方式:
其中,变量类型的查看方式用于直接输出变量值,而表达式类型的查看方式则是通过表达式计算后输出计算结果值;
我们保存测试用例,然后切换到运行模式查看效果:
当设备尚未开发完成或者临时无法使用时,我们可以使用 Bittly 串口调试助手来模拟设备通讯。 通过配置自动相应规则来模拟设备对串口请求的自动响应。
首先我们先切换到 MOCK 功能模块来创建一个新的模拟服务:
在新建的内容页中选择串口模拟即可新建串口模拟服务 :
需要说明的是, Bittly 串口调试助手虽然能够模拟串口设备,但无法模拟一个串口,所以你还需要自行安装一个串口模拟软件,例如 vspd 又或者是其他串口模拟功能, Bittly 目前能做的是从模拟的串口接收消息并进行自动响应。
现在我们来配置串口连接, 假设我们新建了一对虚拟串口 COM1 和 COM2。 其中 COM1 用于我们自己的应用程序进行连接, 而 COM2 用于 Bittly 串口助手进行连接。 这样应用程序通过 COM1 发送的数据将会传递给 COM2, 并最终由 Bittly 串口调试助手接收并处理。 这里我们配置 Bittly 串口调试助手连接到 COM2 :
到这里便完成了串口设备模拟服务的创建,我们点击保存来保存该服务配置。
在默认情况下,新建串口模拟服务后 Bittly 串口调试助手会对模拟服务自动生成一个ECHO响应规则并启用 :
这样,当模拟服务收到任何内容后,都将会自动将收到的内容直接响应回去:
我们从最简单的匹配操作开始, 比如当模拟服务收到 hello
的时候,自动响应 world
, 则我们的配置规则如下:
其中,规则名称仅仅用于标记规则, 匹配类型用于告诉 Bittly 串口调试助手如何对收到的内容进行匹配,需要更改匹配规则时可通过下来选项来进行切换。 比如如果我们需要进行匹配二进制数据,那么可以下拉选择HEX 或者 HEX 匹配。 匹配内容用来告诉 Bittly 串口调试助手内容匹配的模板是什么, 比如前面我们选择匹配方式为文本, 然后匹配内容为 hello, 则只用收到 hello 时方可匹配成功该规则。响应用来告诉 Bittly 串口调试助手如何打包后面的响应内容。 例如如果我们选择 hex, 那么响应内容将会被以十六进制字符串进行打包并发送。
配置完成规则后,我们保存,然后向模拟服务发送 hello 来尝试一下 :
但是,正常情况下,即使是基于文本的指令,也同样需要对可变的内容进行模糊匹配, 例如我们的文本指令可以是 motor speed-set 100
这样。 那么,文本完整匹配则无法实现内容匹配并响应。 在 Bittly 串口调试助手中,我们可以使用 通配符或者正则表达式来进行这类内容的匹配操作。
对于通配符,Bittly 串口调试助手可使用 .
代替一个字符, *
代替多个字符, 以 motor speed-set
并返回 ok
为例, 则配置方式如下 :
接着,我们保存配置,然后向模拟服务发送 motor speed-set 299
来试一下 :
在上面的例子中,我们只是简单的响应了一个 ok
, 那么,如果我们需要将请求参数同样发送回来应该如何配置呢? 比如发送 motor speed-set 100
后我们需要响应 ok speed 100
。 使用通配符的方式无法获取请求内容的参数部分,但是我们可以使用 Bittly 串口调试助手的正则表达式来进行匹配,并且通过 ?<name>
的方式提取参数内容,则我们的配置如下:
在响应内容中,我们使用了 {{ $request.speed }}
来引用匹配出来的速度值,这样我们便可以正确的将速度值响应回去,我们保存一下模拟服务,再次发送一次速度设置试一下 :
对于二进制数据, Bittly 串口调试助手同样增加了匹配支持, 这里先介绍一下完成匹配:
如图所示,假设当模拟服务收到 AA BB CC
时,则自动响应 00 11 22
。
我们保存一下来看下效果:
如果发送的二进制数据包含一系列参数, 而我们也需要将这些参数解析出来,那么我们便可以使用 HEX 匹配 来匹配接收到的二进制数据:
关于 HEX 匹配表达式的规则可参考 HEX 匹配规则
现在我们保存一下来看下效果:
另外,常用的数据格式例如 JSON这种,如果使用文本模式进行匹配的话, 那么不仅规则难以书写,并且可读性也不存在。 所以 Bittly 串口调试助手针对 JSON 也提供了额外的支持。 例如:
在匹配规则中,Bittly串口调试助手使用 $request
变量保存了所有 JSON 数据。 这样模拟服务在收到数据时,如果匹配模式为 JSON 则首先会尝试解析请求内容到一个 JSON 对象, 如果解析成功则会继续执行表达式, 那么如果表达式结果为 true, 则该次匹配成功。
我们保存一下配置来看下效果:
到这里我们便大致了解了 Bittly 串口调试助手的主要功能框架。 从串口他通讯的建立, 到串口指令管理, 到上位机控制面板的绘制以及自动化测试的实现, 还有最后的设备模拟功能。通过这些功能的组合使用,无论是 调试设备、开发项目,还是进行自动化测试,Bittly 都能大幅提升效率,让调试更便捷、高效。