0 引言

之前介绍的电机PID控制的系列文章:
电机控制与PID实践
得到不少电子爱好者的关注,不过也收到一些关于串口通信的疑问反馈。之前的一系列文章,确实没有着重介绍串口软件的使用细节以及通信协议的具体格式。本篇就来补充一下野火PID调试助手的串口协议。

下野火PID调试助手的使用界面如下,与串口通信协议相关的,主要分为三个部分:

  • 参数区:包括数据通道选择、PID参数设置与展示、目标值、周期值的设置与展示
  • 启/停区:控制电机的启动、停止以及程序的复位
  • 数据曲线区:接收板子发上来的数据,进行速度曲线或位置曲线等的绘制

在介绍串口协议之前,推荐安装一个虚拟串口驱动软件来在自己的电脑上虚拟出两个串口,方便分析串口数据。

比如我们在电脑上产生两个虚拟串口,这两个串口可以看作是通过线连接了起来,比如我们使用野火PID助手和另一个串口助手软件分别连接这两个虚拟串口,当野火PID助手发送数据时(比如按下启动按钮),另一端的串口助手软件就可以收到并显示野火PID助手发来的数据,这样我们就能分析野火PID助手下发数据的数据格式了。

1 PID调试助手串口协议介绍

先来看一下野火PID调试助手的串口协议数据格式。

串口协议的定义参考野火论坛的介绍:https://www.firebbs.cn/forum.php?mod=viewthread&tid=29923&extra=page%3D1

1.1 指令包格式

串口数据是通过一包一包的数据发送的,每一包的数据格式如下:

字节数 名称 内容
4bytes 包头 0x59485A53
1bytes 数据通道 0xXX
4bytes 包长度 0xXXXXXXXX
1bytes 指令 0xXX
1bytes 参数1 0xXX
1bytes 参数n 0xXX
1bytes 校验和 0xXX

说明:

  1. 所有多字节的低字节在前(关于高低字节或数据大小端的介绍,可参考:这篇)
  2. 包头固定为四字节的0x59485A53
  3. 通道地址1到5对应软件上的CH1到CH5,CH1为0x01,CH2为0x02
  4. 包长度为从包头到校验的所有数据长度
  5. 指令为相应的功能码
  6. 参数为指令需要参数时加入
  7. 校验为校验和方式——8位

1.2 指令分类

上述数据格式中,需要重点关注的是“指令”这一字段,它表明了这一包数据的具体含义。

另外,串口数据包括下发数据上传数据,下发数据就是野火PID助手按照协议包格式向板子发送串口数据,上传数据就是板子按照协议包格式向野火PID助手送串口数据。

1.2.1 下发数据

野火PID助手下发设定的数据或指令到板子中

功能 指令 参数
PID 0x10 3个float
目标值 0x11 1个int
启动 0x12
停止 0x13
复位 0x14
周期 0x15 1个uint

1.2.2 上传数据

板子上传数据或指令到野火PID助手

功能 指令 参数
目标值 0x01 1个int
实际值 0x02 1个int
PID 0x03 3个float
启动 0x04
停止 0x05
周期 0x06 1个uint

2 数据实测与分析

2.1 实测下发的数据

测试数据的下发,可以只使用一个电脑进行测试,通过虚拟串口,分别连接野火PID助手和另一个串口助手软件,通过野火PID助手向另一个串口助手发送数据,以Hex方式显示接收的数据,并观察数据的格式。

2.1.1 下发启动(0x12) 停止(0x13) 复位(0x14)

这3个是指令,没有数据参数,数据长度为0x0B,也就是11个byte

包头 通道 包长度 指令 校验
启动 53 5A 48 59 01 0B 00 00 00 12 6C
停止 53 5A 48 59 01 0B 00 00 00 13 6D
复位 53 5A 48 59 01 0B 00 00 00 14 6E

2.1.2 下发目标值(0x11) 周期(0x15)

这2个指令,带有1byte数据,数据长度为0x0F,也就是15个byte

包头 通道 包长度 指令 参数(数据) 校验
目标值 53 5A 48 59 01 0F 00 00 00 11 C8 00 00 00 37
周期 53 5A 48 59 01 0F 00 00 00 15 64 00 00 00 D7

2.1.3 下发送PID(0x10)

这个指令,带有12byte数据(3个float),数据长度为0x17,也就是23个byte

包头 通道 包长度 指令 参数(数据) 校验
53 5A 48 59 01 17 00 00 00 10 9A 99 99 3F 00 00 20 40 9A 99 99 3E EB

注意:这里PID的数据是float型的,在发送时是需要拆分成4个字节的Hex格式发送的,关于float类型数据转为Hex格式的介绍,可参考:这里

2.2 实测上传数据

测试数据的上传,需要将程序下载到板子中,板子通过软件连接电脑上的任意串口调试软件,以Hex方式显示接收的数据,分析数据的格式。

2.2.1 上传启动(0x04)/停止(0x05)状态

包头 通道 包长度 指令 校验
启动 53 5A 48 59 01 0B 00 00 00 04 5E
停止 53 5A 48 59 01 0B 00 00 00 05 5F

2.2.2 上传目标值(0x01)/周期值(0x06)

包头 通道 包长度 指令 参数(数据) 校验
目标值 53 5A 48 59 01 0F 00 00 00 01 70 3A 00 00 09
周期 53 5A 48 59 01 0F 00 00 00 06 xx xx xx xx xx

2.2.3 上传PID参数(0x03)

包头 通道 包长度 指令 参数(数据) 校验
53 5A 48 59 01 17 00 00 00 03 CD CC 4C 3D 00 00 00 00 00 00 00 00 8B

2.2.4 上传实际值(0x02)

这里就是将电机的转速和位置值上传到野火PID助手中,用于显示位置曲线或速度曲线。

包头 通道 包长度 指令 参数(数据) 校验
53 5A 48 59 01 0F 00 00 00 02 2D 00 00 00 8D

3 串口收发程序

再来看一下与串口数据发送与接收相关的主要代码:

3.1 发送

按格式组包数据:

/*** @brief 设置上位机的值* @param cmd:命令* @param ch: 曲线通道* @param data:参数指针* @param num:参数个数* @retval 无*/
void set_computer_value(uint8_t cmd, uint8_t ch, void *data, uint8_t num)
{static packet_head_t set_packet;uint8_t sum = 0;    // 校验和num *= 4;           // 一个参数 4 个字节set_packet.head = FRAME_HEADER;     // 包头 0x59485A53set_packet.ch   = ch;              // 设置通道set_packet.len  = 0x0B + num;      // 包长set_packet.cmd  = cmd;             // 设置命令sum = check_sum(0, (uint8_t *)&set_packet, sizeof(set_packet));       // 计算包头校验和sum = check_sum(sum, (uint8_t *)data, num);                           // 计算参数校验和usart1_send((uint8_t *)&set_packet, sizeof(set_packet));    // 发送数据头usart1_send((uint8_t *)data, num);                          // 发送参数usart1_send((uint8_t *)&sum, sizeof(sum));                  // 发送校验和
}

将一包数据一个个发送给上位机

void usart1_send(u8*data, u8 len)
{u8 i;for(i=0;i<len;i++){while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); USART_SendData(USART1,data[i]);   }
}

3.2 接收

使用中断的方式进行串口数据的接收:

//=======================================
//串口1中断服务程序
//=======================================
uint8_t Recv1[128]={0};//串口接收缓存
u8 rx_cnt=0;//接收数据个数计数变量
int sizecopy=128;void USART1_IRQHandler(void)
{uint8_t data;//接收数据暂存变量uint8_t bufcopy[128];//最多只取前64个数据if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断{data = USART_ReceiveData(USART1);              Recv1[rx_cnt++]=data;//接收的数据存入接收数组 USART_ClearITPendingBit(USART1,USART_IT_RXNE);} if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)//空闲中断{data = USART1->SR;//串口空闲中断的中断标志只能通过先读SR寄存器,再读DR寄存器清除!data = USART1->DR;//清空本地接收数组memset(bufcopy,0,sizecopy);memcpy(bufcopy,Recv1,rx_cnt);//有几个复制几个protocol_data_recv(bufcopy, rx_cnt);memset(Recv1,0,sizecopy);rx_cnt=0;}
}

接收之后的数据保存在串口接收缓存Recv1数组中,然后再根据协议格式解析数据即可。

4 总结

本篇介绍的野火PID助手的串口协议格式,包括下发的数据格式和上传的数据格式,并通过实际获取串口数据的Hex格式数据,与协议的定义进行对比分析,使得能够更加的理解串口数据的格式。

如果遇到野火PID助手下发指令板子没反应,或板子上传数据PID数据无法显示曲线,这时就要先排查一下串口数据的格式是否正确,若不正确,就要看下自己程序中的串口收发函数编写的是否正确,只有串口数据符合了规定的协议格式,才能正确的进行数据通信。

如果串口数据格式正常,电机还不转,就要排查硬件接线是否正常以及是否要根据自己的电机编码器参数来修改程序中的参数

电机PID控制补充篇-野火上位机串口协议介绍相关推荐

  1. QT 篇 QT上位机串口编程

    QT 篇 QT上位机串口编程 最近因为项目需要,需要用到上位机,通过串口与上位机进行通讯,来上传和下发一些数据以及控制指令,所以用QT写了一个上位机,并记录下来,免得到时候要用又到处翻资料. QT版本 ...

  2. 用python做一个上位机串口通信_【教程】简易Python上位机之LED控制

    电子爱好者应该不会对"上位机"这个词感到陌生,毕竟或多或少有过接触.但若是说到上位机的开发的话,大家就不一定熟悉了.很多电子爱好者完全没有接触过上位机的开发工作,他们真的没有相应的 ...

  3. 电机PID控制和闭环控制

    电机PID控制和闭环控制 1 PID控制 1.1 位置式PID 理论公式: PID中,P用于提高响应速度,I用于减小静差.D用于抑制震荡.一般在进行PID参数整定时,首先设I和D的值为0,然后把P值从 ...

  4. ANO匿名上位机V7协议STM32

    ANO匿名上位机V7协议&STM32 说明:以下程序为自己编写,若有误欢迎各位指出. 基于ANO匿名V7上位机的通信协议编写的代码 文章目录 ANO匿名上位机V7协议&STM32 前言 ...

  5. react android 串口,Maix Bit(K210) 与上位机串口通信

    串口通信 1.K210 UART 1.1 .串口通信函数 1.2 .常用函数 3.代码 4.效果展示 准备工具 K210开发板 USB转TTL串口 (俗称ISP烧录器) 串口助手 其实Maix Bit ...

  6. 基于VS2015,MFC平台的上位机串口程序搭建详细教程(兼容debug x64、win32 、x86等解决方案平台)

    通常在32位编译环境下,我们可以通过插入MFC串口控件(MSCOMM32.OCX)的方式来实现串口通信,但是MSCOMM32.OCX不支持64位编译环境,也就是说,在x64解决方案平台下会报错.为此, ...

  7. C#上位机——串口发送

    C#上位机--串口发送 第一步:搭建框架 第二步:设置属性 第三步:编写代码,实现各个模块之间的联系和功能. using System; using System.Collections.Generi ...

  8. Labview上位机串口通信-读写

    使用VISA进行串口通信: (1)相关配置:串口资源(波特率等设置).VISA的打开.配置(接收和发送缓冲区).调用属性结点(一有字节出现就马上接收,或者发送) (2)读取部分:首先依据协议进行包头的 ...

  9. tek示波器软件_泰克示波器自带上位机软件功能介绍

    原标题:泰克示波器自带上位机软件功能介绍 有人问,仪器背后那么多程控接口,为什么平时大家都只手动设置调试,从来没见过它们派上用场呢?今天安泰测试马工就给大家介绍一下电子工程师常用的仪器--泰克示波器的 ...

  10. 学习制作平衡小车:(四)PID学习、位置PID参数整定以及匿名上位机显示

    一.PID学习 PID的知识网上有很多教学讲解的非常清楚,可以再参考学习[平衡小车之家]的视频教程. 二.位置PID学习 位置PID控制公式为:Pwm=Kp*e(K)+Ki*∑e(K)+Kd[e(K) ...

最新文章

  1. 将服务器置于最终用户附近可解决性能问题?—Vecloud微云
  2. boost::isomorphism用法的测试程序
  3. 接口隔离原则_设计模式之七大设计原则(上)
  4. 试着理解cookie和session
  5. 前端学习(2432):关于组件和目录名
  6. 漫话:为什么计算机起始时间是1970年1月1日?
  7. srgan要训练多久_儿童内裤多久换一次,穿多久要扔掉?
  8. 旅游后台管理系列——使用maven tomcat插件启动web工程
  9. 驾校一点通电脑版2015 v1.5 最新版
  10. Java实现打印进度条
  11. mac免费CAD模型设计软件FreeCAD怎样设置中文模式
  12. java date获取24点_获取0点和24点时间戳的方式
  13. caffe安装+Ubuntu16.04+三显卡gpu加速
  14. qq接收不了文件显示服务器拒绝,QQ提示服务器拒绝了您发送离线文件怎么办
  15. TRY HACK ME |RELEVANT「渗透测试挑战」
  16. Excel转PDF 一百行代码超简单
  17. 《星际争霸》战术总结==神族对战基本发展流程
  18. 用python绘制小猪佩奇
  19. 想学文字生成图片?3招告诉你描述文字生成图片怎么做
  20. 【PS】图片背景透明化

热门文章

  1. Google Chrome与Apple Safari内核-webkit
  2. 戴尔微型计算机电源怎么拆,教你怎么拆解电源适配器
  3. 商用密码产品认证-电子签章系统
  4. 新广告法违规词、敏感词在线检测工具
  5. 盘点python socket 中recv函数的坑
  6. 20135202闫佳歆——信息安全系统设计基础第七周学习总结
  7. JAVA招聘管理系统计算机毕业设计Mybatis+系统+数据库+调试部署
  8. 磁性能测试标准和项目有哪些
  9. 01 - 树莓派简介以及烧录系统
  10. 软件设计与体系结构实验——图书馆管理系统