在两年多以前,我写了一篇关于如何整定PID的小文章,收到不少的朋友给我发E-mail,讨论关于PID参数整定的问题。今天刚好有一个小小的项目,需要整定PID参数,我们再用原来的方法,来做一遍,看看效果如何。
   需要注意的是,我们都是从头开始,我并不知道之前的方法会不会有效,不过,我们来试一试吧。

图1-1 整个温控系统的结构

1.首先,我们先看看客户的要求。

客户要求我们,控温的精度在0.5度以内,尽量小的波动。

2.好吧,要求比较的少。我们开始吧。

我们测试一下执行机构,看看这个执行机构的加热速度有多快,这个速度将影响我们选取PID的采样时间,这可是整个系统的前提。
    我们编写一个程序,使加热器以100%的功率加热,编写下位机程序,让单片机将温度传感器的采集值,传送到计算机。计算机使用串口助手,将数据收集起来,然后使用我们的秒点绘图的软件,将图像绘制出来【描点绘图软件在我们的网站 www.zyxmcu.com 上有下载。免费】。

  1. unsigned int myData;
  2. PWM(100);                               //最高档加热
  3. for(;;)
  4. {
  5. myData = GetTemp();            //获取当前的温度
  6. SendOnyByte(myData/10);      //发送数据到计算机
  7. os_wait(K_TMO,100,0);           //等待1秒钟
  8. }

复制代码

图1-2 使用串口助手数据采集中

好了,数据开始采集了,让我们耐心等待吧……
    【漫长的等待】
    好了,经过半个小时的连续采集,采集到了8600组有效数据,在下面的文件中,大家可以下载研究:

以上采集到的这些数据是16进制的,我们使用张彦欣单片机有限公司的免费进制转换软件,将其转换为10进制:

图1-3 16进制转换为10禁止批量软件(可到www.zyxmcu.com免费下载)

转换成10进制以后的文件,点击这里可以下载: 昨天 09:15 上传下载次数: 0

现在得到一个转换为10进制的文件,里面的数据可以用来绘制图像了。启动张彦欣单片机的描点绘图软件,将数据导入,可以绘制出图形:

图1-4 将数据绘制成图形后的结果

3.选择合适的采样时间
    根据图1-4,我们可以看出来,整个加热过程基本是呈线性的,也就是说,加热机构的加热速度是比较均匀的,而且加热速度比较的慢。30分钟,温度从35度到了95度,平均每分钟温度升高2度,每30秒变化1度。按照我之前论文中的说法,如果将我们目标控制温度误差0.5度叫做一个“最小单位”,那么变化一个“最小单位”所需要的时间是15秒,我们可以叫这个时间为“最小单位时间”。那么,在PID中,采样时间一定要小于这个“最小单位时间”,否则,可能出现温度超标,却还没有检测到的现象;当然,采样时间也不能远远小于这个时间,否则可能出现系统振荡。综上所述,我们将采样时间定在5秒钟。

虽然方法没有问题,但是加热机构的效率的确有点低,加热速度有些慢,所以,我们更换一个功率更大的加热器,再重新测试一下看看:

图1-5  更换更快的加热器后加热曲线

以上是加热500秒的曲线,温度从24度加热到了106度,平均每6秒钟变化1度。按照之前我们提到的“最小单位时间”,变化0.5度的时间是3秒,所以综合起来,我们选取采样时间为1秒钟。

4.确定比例系数Kp

确定采样周期后,就要确定比例系数Kp、Ki 和Kd。按照顺序,先确定Kp,然后是Ki,最后是Kd。

图1-6 PID控制系统的典型曲线

如图1-6所示,典型PID的控制曲线,在一般的PID控制过程中,比例部分(P部分)至关重要。比例部分可以归结成一句话说:当当前的温度和目标温度相差较远的时候,全火力加热,当温度慢慢接近目标温度的时候,火力慢慢的降低,比例部分(P部分)的作用慢慢的削减,积分(I部分)和微分(D部分)慢慢的起作用。

在这其中 ,比例系数的作用就是告诉系统,什么时候停止全火力加热。比如,在本系统的驱动程序中PWM()函数负责调节输出功率,最低是PWM(0),输出功率是0;最高是PWM(100),输出功率最大(本例子中是200瓦)。

  1. Ek = TargetTemp - CurrentTemp; //计算当前温度和目标温度之间的差值
  2. DTY = Kp * Ek;                         //计算当前应该输出的功率
  3. if(DTY>100)                             //限幅
  4. DTY=100;
  5. PWM(DTY);                              //功率输出

复制代码

例如,当前温度是50度,目标温度是100度,Kp=2:
    Ek=100-50=50;
    DTY=Kp*Ek=2*50=100;
    PWM(100);
    再例如,当前温度是80度,目标温度是100度,Kp=6:
    Ek=100-80=20;
    DTY=Kp*Ek=6*20=120;
    DTY=100;
    PWM(100);
    上面举的例子,可以看出,比例系数(Kp)越大,加热的速度就越快,但是这其中有一个问题:是不是Kp越大越好?肯定不是,那么如果Kp太大,会有什么后果呢?我们不妨来再看一个例子:
    当前温度是98度,目标温度是100度,Kp=50:
    Ek=100-98=2;
    DTY=Kp*Ek=2*50=100;
    PWM(100);
    我们可以看到,在当前温度达到98度的时候,系统还在100%的功率加热,会出现什么情况?会出现系统加热速度太快,过了100度的情况,要知道,一般的加热系统,加热容易,要降温往往就比较麻烦了……
    这个“过了”的了情况,其实就是PID系统里的“超调”。Kp过大,加热速度快,超调也会很大;Kp过小,加热速度很慢,超调也很小。
     当然,Kp的大小,是有一个最优化的,就是并不是平白无故选择的,而是跟系统的特性有关。举个例子说明“超调”:

图1-7  汽车加速到终点线的演示

如图1-7所示,图中的直线是“目标量”,我们希望汽车以最快的速度到达代表“目标量”的直线,但是不要超过,也不要没有到达,最好刚刚好到达直线。现在就来问题了:汽车的司机在离直线很远的时候,全速前进;在离直线距离较近的时候,开始减速前进。不减速,到了直线再刹车,显然会使汽车越过直线较远距离,那么什么时候减速,减速多少,这就是一个优化问题。这也就是上面提到的比例系数Kp的大小问题。
    我们再考虑一下,汽车应该在什么时候减速是最优化的?显然是一开始全速运转,然后在离直线“特定距离”的时候,紧急刹车,车刚刚好停在直线上。这种情况下,到达直线需要的时间显然是最短的。那么,这个“特定距离”是多少,跟什么有关呢?显然,和车的惯性有关,惯性大的车,应该提前刹车;惯性小的车,可以离直线更近的时候刹车。
    同样的道理,不光汽车有“惯性”,我们加热系统同样是有惯性的,加热系统在停止加热以后,温度仍然有可能继续上升,这就是惯性,显然这个惯性越大,Kp就应该相应的减小,提前“刹车”。下面我们就测试一下加热系统的“惯性”:

  1. for(;;)
  2. {
  3. PWM(100);                    //全火力加热
  4. myData = GetTemp();    //获取当前的温度
  5. SendOnyByte(myData);   //将数据发送到计算机
  6. if(myData==100)
  7. {
  8. PWM(0);                   //停止加热
  9. break;                       //跳出循环
  10. }
  11. }
  12. for(;;)
  13. {
  14. myData = GetTemp(); //获取当前的温度
  15. SendOnyByte(myData);//将数据发送到计算机
  16. }

复制代码

以上代码的意思是,使用全部火力加热,当检测到温度达到100度的时候,关闭加热器,继续采集温度,继续观测温度,观看系统的“惯性”。

图1-8 惯性测试曲线
    如图1-8所示,系统在达到100度以后,温度并没有因为“惯性”继续上升,而是转而下降,这说明系统“刹车”很快,我们可以放心驾驶,不会出现到达终点停不下的情况。可以将Kp设置为一个较大的数据。
    我们可以设定,在温度误差是2度的时候,全火力加热,只有小于2度的误差,才慢慢的降低火力,因此Kp=5(因为系统采集的温度都带有1位小数,但是使用整数int表示,所以都乘以了10);
    我们来看看在Kp=5的情况下,系统的加热曲线(目标温度是30度):

  1. for(;;)
  2. {
  3. if(SYS.TargetValue>SYS.Temp) //目标温度值比当前值高
  4. {
  5. Ek = SYS.TargetValue - SYS.Temp; //比例部分
  6. Data = Ek*Kp;
  7. if(Data>100)
  8. Data=100;
  9. PWM.DTY = Data;
  10. }
  11. else if(SYS.TargetValue<=SYS.Temp) //目标温度值比当前值低
  12. {
  13. PWM.DTY=0;
  14. }
  15. os_wait(K_TMO,100,0);    //等待1秒
  16. }

复制代码

图1-9 Kp=5时,系统加热曲线

我们看到,以上的加热曲线中,加热快速而准确,满足了我们的要求。如果此处想验证更加优化的Kp,可以多次调整,绘制图像,比较各个图像,选择一个最佳值。此处我们不做更改了,就选择Kp=5;
    细心的朋友可能会发现了,我们的目标值是30度,而系统最终稳定在了29度(其实是绘图的误差,系统最终稳定在了29.6度左右)。但是无论如何,系统没有到达我们的要求值30度,可奇怪的是,此时的系统是稳定的,一直恒定在这个温度,不像是一个故障状态。
    正是如此,这不是故障,也不是我们设计的问题,这就是P控制的缺陷。随着现实温度和目标温度越来越接近,Ek=TargetTemp-CurrentTemp;越来越小,那么经过Kp*Ek计算出来的DTY就越来越小,那么PWM()输出的数值就比较小了,此时执行机构按照这样的小功率加热,往往不能使温度上升了,这其实和执行机构的精度有关。
    这个误差就是PID系统中的“静差”。静差,就是系统达到平衡、稳定后,存在的“静态误差”。如果要消除这个误差,就必须使用PID控制策略里面的I(积分)。

5.积分项整定
    
    积分项的整定需要谨慎,积分项整定过强,系统会产生严重的振荡;积分项整定过弱,效果不明显。所以,积分项一般从小大到的整定,不能过大。
    那么,是不是积分的整定就无章可循了呢?是不是就要像课本上说的那样,一点一点的试呢?当然不会,我们既然能将比例项总结出经验,积分项也不例外。

温度PID的整定过程相关推荐

  1. PID 参数整定过程

    Kp: 比例系数 ----- 比例带(比例度)P:输入偏差信号变化的相对值与输出信号变化的相对值之比的百分数表示  (比例系数的倒数) T:采样时间 Ti: 积分时间 Td: 微分时间 温度T: P= ...

  2. 一个实例说明PID 参数整定

    引言:PID是比例.积分.微分的简称,PID控制的难点不是编程,而是控制器的参数整定.参数整定的关键是正确地理解各参数的物理意义,PID控制的原理可以用人对炉温的手动控制来理解.     1.比例控制 ...

  3. 【控制理论】——控制系统分类PID算法简介PID参数整定PID上位机通信协议

    目录 ​ 前言 一.PID算法 1.控制系统分类&参数&信号 2.PID算法简介 二.PID参数整定 三.PID上位机通信协议 1.数据帧&协议调试 2.协议代码实现 拓展: ...

  4. 继电反馈法自整定_基于继电反馈PID自整定方法在Buck―Boost电路中应用.doc

    基于继电反馈PID自整定方法在Buck―Boost电路中应用 基于继电反馈PID自整定方法在Buck―Boost电路中应用 摘 要:DC-DC变换器在电力电子和通信等领域中有广泛应用,Buck-Boo ...

  5. matlab求系统根轨迹代码_根轨迹法、PID参数整定和matlab指令计算

    收获 (1)理解根轨迹的概念及其在控制系统设计中的作用: (2)手绘根轨迹草图,以及如何使用极端及绘制根轨迹: (3)熟悉在反馈控制系统中应用广泛的关键部件:PID控制器: (4)理解根轨迹在参数设计 ...

  6. 我的四轴专用PID参数整定方法及原理

    给四轴调了好久的PID,总算是调好了,现分享PID参数整定的心得给大家,还请大家喷的时候手下留情. 首先说明一下,这篇文章的主旨并不是直接教你怎么调,而是告诉你这么调有什么道理,还要告诉大家为什么'只 ...

  7. 用纯C语言分别实现增量式与位置式的PID自整定算法

    对于增量式PID自整定算法,C语言代码如下: #include <stdio.h>#define SAMPLE_TIME 0.1 // 采样时间 #define KP_DEFAULT 0. ...

  8. 针对具有纯滞后环节的一阶惯性系统PID参数整定(衰减曲线法)

    假定被控系统的传递函数为: 一.建立开环结构图,观察系统对阶跃输入信号的跟随性. 由图二可知:开环系统的的上升时间很长,并且输出到达不了给定值,下面对该系统进行PID参数整定,进行PID控制. 图1 ...

  9. 基于遗传算法的PID参数整定研究(三)

    基于遗传算法的PID参数整定研究 在获得对象模型的基础上设计PID参数时常用的原理,经典的有经验试凑法.临界比例度法.极点配置原理.零极点相消原理.幅相裕度法等:现代的则往往借助于计算机,利用最优化方 ...

最新文章

  1. 基于Flink秒级计算时CPU监控图表数据中断问题
  2. bottle模板 template/jinja2_template
  3. MyBatis 源码分析 - 缓存原理
  4. HDU1598【最小生成树拓展】
  5. 【ZJOI2018】历史【结论】【LCT思想】
  6. 悲痛!高校一研究生在校内被撞身亡,肇事者为该校博导,警方已介入
  7. java forkjoinpool_Java并发——Fork/Join框架与ForkJoinPool
  8. 关于使用skimage.measure.shannon_entropy计算图像信息熵的问题
  9. 《Android开发艺术探索》— Android 书籍
  10. 阶段1 语言基础+高级_1-3-Java语言高级_07-网络编程_第1节 网络通信概述_5_端口号...
  11. 计算机附件中的超级终端,windows10系统中附件中没有超级终端怎么解决
  12. 计算机组装与维护思考问题,计算机组装与维护心得体会
  13. Amcharts4使用笔记
  14. 码出高效:Java开发手册PDF
  15. RTP/RTCP工程实践与问题解决方案(合集)
  16. element 前端布局理解经验及好用的属性
  17. Windows 开机自启bat
  18. vue零基础——vue2基础知识
  19. 【go项目-geecache】动手写分布式缓存 - day7 - 使用 Protobuf 通信
  20. 2020年上海交通大学计算机软件学院夏令营面经

热门文章

  1. 【JOURNAL】怎么计算4万亿
  2. Flink ReducingState 实例
  3. 手把手教你系列 - Particle粒子特效(完整代码部分)
  4. 浅议数字化双胞胎与仿真
  5. 二〇二三-三-二十七
  6. 成功解决LINK : fatal error LNK1181: 无法打开输入文件“avdevice.lib” error: command 'D:\\Program Files (x86)\\Micr
  7. bzoj3585 mex
  8. 安利一个超牛的资源网站,国庆看片就用它了
  9. SpringBoot之配置文件YML
  10. django基于python的图书馆管理系统--python-计算机毕业设计