直接来源 | 果果小师弟
逛github时看到这个QT的串口示波器,完全开源,支持串口、TCP、波形显示、通信协议。
感觉很不错,跟以前分享的那个vofa+有点像。感兴趣的可以下载下来学习学习(文末附链接)。
Sailor Project功能说明
![60e6b53b2699b08e161d516b6ead0c74.png](https://i-blog.csdnimg.cn/blog_migrate/b241c8ca3bf4aa30d3c4f6989bfff10e.png)
串口调试助手功能
支持传统的串口调试助手的基本收发功能,同时可以刷新大量的数据而不卡顿
支持保存接收的数据
支持最大200条可编辑指令的设置,并用于多条发送
支持定时器发送
支持换行符替换时间戳功能
支持较多的中文编码格式
值得注意的是支持Linux简单的串口调试
支持加载csv表格数据到200条可编辑指令
支持部分窗口配置的保存和重启恢复(前提是你不会删除配置文件)
操作说明
注意由于QT自带文本显示窗口加载大量数据后会造成软件卡顿,现解决方案为设定一个显示缓冲区,在有刷新数据阶段(即串口接收数据阶段),如果需要保持刷新状态(即实时显示接收得数据),则仅显示显示缓冲区的内容,你可以使用鼠标移动向上滚动条,停止数据刷新。
同时当你向上移动滚动条到一定程度,便会开始加载所有数据,如果你想再次触发实时刷新数据状态,只需要将滚动条移动到最低端,并确保有数据接收。
由于保存数据为显示界面的数据,如果出于刷新状态,则无法保存所有数据,正确的做法是关闭串口后,将滚动条移动到最顶端,加载全部数据,然后保存窗口数据。
TCPServer界面
![93d290411d109789500dd6be7123fb70.png](https://i-blog.csdnimg.cn/blog_migrate/4095b89074926ff44d30c9aab31b18df.png)
![517239bf2ddca091071671a7fb564b35.png](https://i-blog.csdnimg.cn/blog_migrate/bad269aad438781cb030522252c1bca5.png)
![ad33b7ae90bb28fe53db5e0af2d9c0ee.png](https://i-blog.csdnimg.cn/blog_migrate/935790206246ef8d5346a70e37e52832.png)
![ffe18418ba3de9384dd05e49bbc0ee1d.png](https://i-blog.csdnimg.cn/blog_migrate/d7ab9fd3edb5c236e2b18d93ab94b34b.png)
![955c0b817fbecefd45f245011b7db999.png](https://i-blog.csdnimg.cn/blog_migrate/c81d3e21fb97dd2557517f60404d97e4.png)
SEASKY串口通信协议
通信方式是串口,配置为波特率115200, 8位数据位, 1位停止位, 无硬件流控, 无校验位。
1、通信协议格式
帧头 | 设备类型 | 设备ID | 数据ID | 帧尾 |
---|---|---|---|---|
protocol_header(4-byte) | equipment_type(2-byte) | equipment_id (2-byte) | data_id(2-byte) | frame_tail(2-byte,CRC16,整包校验) |
2、帧头详细定义
![5a3d1bfc267451407b322d82066d5e3a.png](https://i-blog.csdnimg.cn/blog_migrate/de247b4ca0573c3610cdc0fb038e30a3.png)
3、串口通信协议
int parse_protocol(protocol_struct* pProtocol,uint16_t parseDataLen)
{
//解析数据,使用前需提前缓冲 pProtocol->message_st.pData
int ret = -1;
uint16_t pos_offset;
frame_struct* pFrameStruct = &pProtocol->frame_st;
message_struct* pMessageStruct = &pProtocol->message_st;
if (check_protocol_heade(pMessageStruct->pData) == PROTOCOL_RESULT_OK)
{
//更新帧头数据
pFrameStruct->header.sof = pMessageStruct->pData[0];
//获取data段的数据长度
pFrameStruct->header.data_length = (pMessageStruct->pData[2] << 8) | (pMessageStruct->pData[1]);
pFrameStruct->header.crc_check = pMessageStruct->pData[3];
//获取此次数据包长度
pMessageStruct->data_len = pFrameStruct->header.data_length + PROTOCOL_DATA_OFFSET + 2;
//计算解析后得到的 data_union 数据长度
pFrameStruct->frame_user.cmd_data.data_len = (pFrameStruct->header.data_length) / sizeof(data_union);
if(pMessageStruct->data_len<=parseDataLen)
{
if (pMessageStruct->data_len <= pMessageStruct->max_data_len)
{
if(CRC16_Check_Sum(&pMessageStruct->pData[0], pMessageStruct->data_len) != 0)
{
pFrameStruct->frame_user.equipment_type = (pMessageStruct->pData[5]<<8) | (pMessageStruct->pData[4]);
pFrameStruct->frame_user.equipment_id = (pMessageStruct->pData[7] << 8) | (pMessageStruct->pData[6]);
pFrameStruct->frame_user.data_id = (pMessageStruct->pData[9] << 8) | (pMessageStruct->pData[8]);
//拷贝 data段 指定长度数据
ret = (int)memcpy(&pFrameStruct->frame_user.cmd_data.pData[0], &pMessageStruct->pData[PROTOCOL_DATA_OFFSET], pFrameStruct->header.data_length);
pos_offset = pFrameStruct->header.data_length + PROTOCOL_DATA_OFFSET;
pFrameStruct->frame_tail = (pMessageStruct->pData[pos_offset+1] << 8) | (pMessageStruct->pData[pos_offset]);
return PROTOCOL_RESULT_OK;
}
else
{
//待解析BUFF超过预定解析数据容量,避免内存越界
PROTOCOL_ERROR_PRINTF("parse_protocol->>CRC16_Check_Sum err!\n");
return PROTOCOL_RESULT_CHECK_FRAME_ERR;
}
}
else
{
//待解析BUFF超过预定解析数据容量,避免内存越界
PROTOCOL_ERROR_PRINTF("parse_protocol->>data_len[%d] > max_data_len[%d]!\n",
pMessageStruct->data_len,
pMessageStruct->max_data_len);
return PROTOCOL_RESULT_OUT_OF_LEN;
}
}
else
{
//通过包头计算,还未收到完整的数据包
// PROTOCOL_ERROR_PRINTF("parse_protocol->>data_len[%d] > max_data_len[%d]!\n",
// pMessageStruct->data_len,
// pMessageStruct->max_data_len);
return PROTOCOL_RESULT_OUT_OF_LEN;
}
}
else
{
//待解析BUFF超过预定解析数据容量,避免内存越界
PROTOCOL_ERROR_PRINTF("parse_protocol->>check_protocol_heade err!\n");
return PROTOCOL_RESULT_CHECK_HEAD_ERR;
}
PROTOCOL_DEBUG_PRINTF("parse_protocol->>check_protocol_heade ok!\n");
return PROTOCOL_RESULT_ERR;
}
软件截图
![8939d9c919161b73df3d33d4b36a944e.png](https://i-blog.csdnimg.cn/blog_migrate/ebc9a6c8f10c8cd36e2de78a48e4cef2.png)
![11175b86e5fd34f19dda59f6f239773d.png](https://i-blog.csdnimg.cn/blog_migrate/67895eae6adc42d98d47ea9be5d0074a.png)
![167b1e4382e097276be2eb4be60b240c.png](https://i-blog.csdnimg.cn/blog_migrate/19f28ea8e1c6dd864e1c599434d4e0b8.png)
![7c1dfc0ff48bb7351842906b7930c96b.png](https://i-blog.csdnimg.cn/blog_migrate/02965ae8c5b34673fc9cde1c981a2e5b.png)
项目开源地址:
https://github.com/SEASKY-Master/vSailorProject
声明:本文素材来源网络,版权归原作者所有。如涉及作品版权问题,请与我联系删除。
-END-
往期推荐:点击图片即可跳转阅读