Introduction 【介绍】
拿到MEGAWIN M0的开发板快一个月了,还没有完成第二篇测评,十一长假在家陪儿子读书,儿子在做练习的同时,我闲来无事翻看了M0芯片的DataSheet和User Manual,发现这个芯片功能还是挺强的,和同级别的STM32F0-M0可以说是不相上下,在UART和TIM的设计上还有自己的一些特色功能,比如说UART的SPI硬件直连功能,TIM的全计数和分离、级联功能,相当不错;遗憾的是并没有太多相关的例程可供参考,只能自己根据User Manual来摸索编写;仔细考虑了一阵子,打算用这个板子做一个PID算法演示的模型。模型的需求如下:
1. 目标让某一个电机的转速控制在指定速度。
2. 需要对该电机提供一些额外的干扰(Noise),考察PID算法的纠偏能力
3. 需要可以控制干扰的强度,修改目标速度,改变PID Gain的值等
4. 需要查看控制电机的速度的波动曲线
映射到软硬件的设计方式,可以用上面的框图来说明。Control Terminal (控制台)通过串口UART0来输入一些命令,满足#3;PID Control的算法可以通过PWM Output/Input来控制风扇的转速和读取风扇的转速;Monitor模块可以把当前的转速的实时情况通过UART1打印出来或者供PC上面的画图工具来进一步展示。
以下是实际建立的工作模块连接。
PID Introduction 【PID 算法的介绍】
PID (Proportional, Integral, Derivative) 比例,积分,微分控制。这种算法经常应用于带有惯性的场合。PID算法通常都非常的简单,一般只要花5行代码就能写完,但是P/I/D分别要取什么样的值以用于特定的场景,达到一个最好的效果往往是一个比较麻烦的事情。采样率的时间间隔长短和目标值往往都会实时的发生变化,从而进一步影响PID的实际效果。
我通常会用学车的过程来和新的同事讲解PID,学会开车如何控制车速,和其他车辆保持合适的距离往往是开车好坏的一个关键因素。你刚开始开车的时候,对油门和刹车的能力并没有很清楚的了解,通过实践,你一点点的学习到,踩多少油门,车速会提高的有多快;踩多少刹车,车速会下降的有多快。通过一天天的驾驶,最后你掌握了一个合适的度,让你在拥挤的车流里面人车合一,自由穿行。一旦到达这个境界,可以说你得到了一个合适的P/I/D的Gain;在你的反应能力(采样率)下,得到了一个较好的驾驶体验。而选取PID的参数也就是这样的一个逐渐磨合的过程。
风扇也是一样的逻辑,当你想要风扇到达一个目标转速的时候,开始的设置往往会超调,当发现超调的时候,你逐步降低控制输出,转速有的时候就会下降的特别快,以致于速度又显著小于目标值,然后你进一步的上调输出,转速就在超调和不及目标的两者之间振荡,随着振荡逐渐收敛,我们最终到达了目标值。而当干扰出现的时候,实际和我们的目标又产生了偏差,于是我们又开始了新一轮的控制历程。 这个过程就是我今天想要演示的模型。
笔者曾经在很多年前做过一个正压呼吸机的项目,病人往往对呼吸机的气压非常敏感,如何能够快速而又平缓的把压力加到目标值是一个难点。PID算法往往可以针对一个病人调整到一个比较理想的参数,而个人各不相同,要想每个病人都满意呼吸机的效果就很不容易做。最后笔者把基于人工智能的PIDNN算法应用到这个呼吸机上,取得了比较理想的效果。但是,最后项目还是由于资金缺口和证书等问题没有落地,这让我们这样的技术工人很是遗憾。
MCU Implementation 【M0开发板上的具体实现】
1. 第一步就是移植RTOS到M0的开发板上,FreeRTOS是我的第一选择,内存占用很小,1KB都不到,footprint大概在3KB左右,这个对于现在动辄几百KB的NOR Flash来说都不是事。移植也非常的方便快捷,核心代码如下:
2. 第二步在RTOS上创建了3个模块Task,控制台Task,PID算法task和Monitor监控 Task
3. 打通PWM 控制和读取的接口,这一块没有特别相关的例程,根据参考文档慢慢调试,花费了几个小时的时间
4. 加上控制台控制,打通UART0
5. 加上监控模块,打通UART1
6. 加上PID算法模块
7. 写好监控用的图形界面,可以很清楚的看到PID的振荡过程
目标转速: 60.00
K: 0.2
P: 0.01
D: 1
采样率: 100ms
OK,花了两天的时间,终于把模块搭建的七七八八。下面是整个模块工作起来的样子:
完整的代码可以从这里下载
https://gitlab.com/imwangwang/megawin_eval
拍了一段简短的视频介绍下整个过程:
链接: https://pan.baidu.com/s/1wlL831igwb3cM8wU6swDug 提取码: u6r2
欢迎拍砖