为了便于做智能小车的朋友快速方便的构建自己的小车,我很早前设计过一个轮式驱动单元,将电机、驱动电路、轮子集成在一起,只需使用TTL电平的IO口即可驱动,即常见的核心板或开发板可以直接驱动,无需外加电路。(这部分的详细介绍可以看订阅号“嵌入之梦”中智能小车主题下的相关文章)。
轮式驱动单元的实现弱化了电机驱动部分的硬件电路,用任何MCU核心板都可以方便地控制,只需编写单片机程序即可构建自己的小车。
但是还有一些朋友,他们关注的是更上一层的控制和算法,通常基于操作系统编程,不便于直接操控硬件输入、输出,硬件是由操作系统来管理的,应用程序基本与硬件隔离。
在这种状况下,如果要操控硬件,通常是通过编写驱动程序实现,这在任何一个操作系统中都是一件耗时、费力且技术含量较高的活儿。对于做策略、算法研究的朋友而言,小车只是一个验证和测试的工具,而非研究对象,所以不想在上面耗费时间。
为了让这些朋友能够方便地控制用轮式驱动单元构建的小车(如:可用笔记本电脑控制的四轮全向小车),便尝试在轮式驱动单元的驱动板上,嵌入一个单片机,从而使轮式驱动单元可以通过串口命令操控,使之成为“智能轮式驱动单元”。
通过一段时间的努力,基本实现了这个想法,虽说不太完美,但主要功能都实现了;只是由于一些其它原因,没有深入完善。
搁置数年,如今发现还有一些存货,便尝试让其复活。正好最近在轮式驱动单元的测速和PID整定上有所改进,看看是否可以应用于它,让其“重现活力”。
首先介绍一下硬件:
智能轮式驱动单元是在轮式驱动单元基础上,加入一片MCU实现,其余没有改变,故硬件介绍只涉及控制板。
由于空间限制,以及学习的需求(当初主流单片还是51系列),选择了宏晶的STC12系列的STC12C5206AD,当时主要是考虑其体积小,SO16封装。可体积小,资源也少,只有256字节RAM,6K ROM(这是10年前的选择,如今要选肯定会选Cortex-M系列,如最近才在28BYJ48步进电机控制板上所用的STM32G030F6)。
没办法,只能“螺丝壳里做道场”。不过STC的单片机还有点优势:可以直接通过串口下载程序,这样对外的接口就可少一个,对于轮式驱动单元而言还是很重要的(外接线有限)。此外,相较于经典51,STC12增加了一个PCA(可编程计数器阵列),也就是目前主流单片机(如STM32)的定时器架构,等于是增加了2个通道的定时功能,经典51只有2个定时器,很难应对电机PWM驱动、测速以及舵机驱动等几个功能同时存在。
STC12C5206AD的PCA虽然只有两个通道,加上标准51定时器T0、T1,正好满足控制中所需的定时需求,而且它的串口有单独的波特率发生器,无需占用定时器。(现在宏晶的单片机又有了不少改进,12系列似乎已经隐退,15系列成为主流)
电路的其余部分和轮式驱动单元一样,没有做任何改动。电原理图如下:
对外的接口改为:
一个2芯插头作为电机驱动的电源输入,接 4 节镍氢充电电池(或其它5~6V的电源);
一个3芯插头作为舵机控制信号输出,可驱动舵机,电源用的是电机驱动电源;
一个4芯插头作为UART控制信号输入,分别为 GND TXD RXD VCC,VCC为5V,TTL电平。
之所以增加了舵机驱动信号输出,是因为轮式驱动单元主推的使用方式是和舵机配合,构成“可操作驱动轮”,而舵机信号也需要用单片机产生,故整合之,这样通过串口即可操作舵机,为需要使用舵机的朋友提供方便。
智能轮式驱动单元实物如下:
当时完成时也实现了测速和PID调速,由于程序空间和RAM都小,只能通过配置字选择 PID参数调试模式 还是 正常工作模式,在调试模式下,支持通过串口输出当前速度,借助PC观察调速效果,完成PID整定。
那时还没有看到关于PID自整定的相关资料,是基于PID的手工调参方式实现的。不过效果还行,就是有点费劲。
将当时的程序也附在下载资源中,有兴趣可以和目前的比对一下,看看区别。
这次“复活”,计划实现以下几项改进:
1、原来是基于VC6.0 编写的PC端辅助测试程序,在如今的Win10环境下已无法运行,必须重新编写,为和我现在做的其它辅助测试程序统一,还是基于Processing编写,实质是找一个控制功能接近的程序修改。
2、近期发现原来的倍频测速逻辑略有不足,基于目前的方式,尝试简化为:测前N个脉冲的平均周期。
3、尝试应用PID参数自整定程序实现PID参数调节。
实施过程虽说不算太难,但也遇到了一些麻烦,在此将所做的过程分享之,期望能给有兴趣的朋友提供启发。
一、PC端辅助测试程序移植
因为用智能轮式驱动单元同样会构建四轮驱动全向小车,故选择最近才用Processing实现的四轮驱动全向小车辅助测试程序为基础,修改为智能轮式驱动单元所用程序。
因为STC12C5206AD的程序空间太小,担心改变协议导致装不下,故通讯协议不变,改写Processing测试程序的通讯部分,界面基本维持不变,增加一个轮子数量选择,因为原来的协议中支持1个轮子和四个轮子的命令帧,将四个轮子的串口并联(轮子的TXD和TXD、RXD和RXD并联,利用51单片机IO口的特性,实现“线或”逻辑),通过一条命令完成对四个轮子的控制,提高同步性。
按钮中只支持PWM定距离和定速定距离操作,因为单片机中没有设计定时运行命令。
其余一些按钮保留,在需要时可以启用。我现在只是测试单轮,如果用四个轮子构建一个全向小车,便可以启用下面的几个操作按钮。
二、测速逻辑完善
因为测速是用轮毂上的齿作为编码器,分辨率较低,所以前面是基于相邻脉冲周期变化不大为基础,用上一脉冲周期推测当前不完整脉冲的时间,实现倍频从而提高编码器分辨率的目的。由于要处理各种情况,避免出现计算出不合理结果,导致程序逻辑过于繁琐。
最近在完善相关程序时,发现这个倍频对于测速而言,毫无价值,如果是要提高控制行走距离精度还有点意义,测速完全是多余,直接使用前面脉冲的周期计算即可。
为了降低周期测量波动带来的误差,采用前5个脉冲的周期平均值计算速度。
在STM32中,这个算法实现很简单,因为内存足够。在此处实现略有困难,主要是RAM太小,不敢用32位数据作为缓存,只好通过降低周期测量的分辨率,并且将STM32中的脉冲起始时间缓存改为脉冲周期缓存,从4字节降低为2字节。勉强完成了周期测量及缓存的算法。
由于计时范围需要用到PCA溢出软计数,采集脉冲出现时间要在中断处理中同时读取软计数值和硬件计时值,会遇到不同步的现象(硬件计时溢出,软计数由于在脉冲中断中,未能响应PCA溢出中断,未计),导致周期计算出错。花了点时间才消除:
修改后的速度计算就比较简单了:
有兴趣可以对比一下所提供的老程序。
三、实现PID自整定
PID参数整定一直困扰我,前段时间得空,总算是静下心来把网上的PID参数自整定程序搞明白了,而且比较圆满地用于我的小车调速。
此处自然也想尝试一下。
不过STC12C5206AD的ROM空间也有限,不可能将PID自整定完整算法加入到MCU中。
分析自整定过程,实际上由两部分组成:一是通过改变激励产生速度振荡,二是根据速度变化计算对象的响应幅值特征和时间特征,基于幅值及时间特征得到PID参数。
改变激励、产生振荡操作只能在MCU内完成,而计算可以放在PC辅助测试程序中,只要MCU可以实时将速度变化传送给PC,这个功能在原来的程序中就有。这样只要增加少量的处理程序即可,程序空间应该可以应付。
具体细节如下:
1)设置产生自整定振荡所需的激励变化参数:
速度判断中值、速度判断回差、PWM中值、PWM摆幅。为减小RAM占用以及额外的程序消耗,利用STC12C5206AD的FLASH参数空间,将上述参数定义在 FLASH ROM中,借用已有的写内存操作命令,实现参数设置,无需新增程序代码,只是增加了几个定义:
2)增加一个通讯命令:自整定命令
收到命令后,MCU启动电机,进入自整定状态,并启动速度输出:
在自整定状态中,每次计算完速度,根据速度值改变PWM,从而产生速度振荡:
3)修改速度输出内容,以满足PC自整定计算需要。原来程序输出的是运行计时值和速度,修改为:
时间(1 字节,取1ms计数器的最低字节) 当前速度(2字节,L H ,单位mm/s)当前 PWM(1字节)。
4)在PC程序原来的PID整定界面上,修改程序,配合MCU采集的速度数据,完成PID自整定计算:
在上述界面中输入相应的参数(注:先在驱动测试界面中,用读记录启动按钮启动MCU速度输出,用PWM测试功能测试不同的PWM下速度,用显示波形观察结果,从而得到自整定工作参数),按自整定按钮,将参数设置到MCU中;再按读记录启动按钮启动自整定过程。PC程序中完成自整定计算后,发停止命令给MCU,完成自整定过程。按读整定结果按钮,可以得到计算出的PID参数。
PC中的程序是将原来的PID自整定库程序移植过来的,计算部分未做修改,只是语法上的适配。
至此,顺利实现了PID参数自整定,并得到了相应的PID参数,可如何使用呢?
对比原来调试好的参数,差别很大,直接使用根本无法完成调速。仔细阅读前面实现的程序,发现在PID参数初始化中,Ki、Kd系数是需要根据采样时间折算的,PID自整定所得到的参数的采样时间是1秒,如果PID过程中的采样时间只有100ms,则Ki、Kd需要折算:
多数情况下,测速采样周期是固定的,可在智能轮式驱动单元中,由于速度是用前5个脉冲周期计算得到的,故采样周期是随速度而变化的,我用固定的采样周期折算,效果不好,尝试改为:以设定速度为基础,计算出响应的脉冲周期,从而得到采样周期,以此折算Ki、Kd,实际效果还不错。这样在每次改变设定速度时,修改相应的Ki、Kd,计算量不大。目前程序只需在收到调速命令时,计算一次。
(自整定过程速度和PWM波形)
(自整定结果)
(120mm/s调速效果)
(220mm/s调速效果)
智能轮式驱动单元PID自整定
智能轮式驱动单元PID自整定A
总体来说,调速效果不错,只是调速范围略小,低速时不行,感觉还是测速上存在问题,可能电机驱动特性也不行,或者需要改变PWM频率。我曾经仔细分析过PWM频率和占空比之间的关系,当占空比太低时,需要提高PWM频率,从而提升电机驱动的平顺性。不过这些在STC12C5206AD上无法实现了,程序空间已经基本耗尽(只剩不到100字节)。
作为一般的小车使用,目前的特性已能满足需求,方便和性能难以两全,如果想要有更大的改进空间,还是使用外置的控制板吧,前面所做的STM31F103RB控制板有足够的发挥空间。
如果有兴趣用这个智能轮式驱动单元构建小车,可以到我的淘宝店(单片机学习之家),免费赠送(不包邮),数量有限。
——————————
文章中程序下载:
1、原来的MCU程序:
链接:https://pan.baidu.com/s/1Qg5i9eMPF36JlxmnXsp0ew
提取码:kh9l
2、本次完善后的MCU程序:
链接:https://pan.baidu.com/s/1rk4QQayIrC_8U0IDcCPSUQ
提取码:r1kt
3、本次完善后的PC辅助测试程序:
链接:https://pan.baidu.com/s/1vybrJxLZXlGLR78NLNmtiw
提取码:f9bq