原创 温度PID系统整定过程

2011-8-6 19:28 2839 11 11 分类: 工程师职场
   在两年多以前,我写了一篇关于如何整定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组有效数据,在下面的文件中,大家可以下载研究:
采集到的原始数据1.txt (25.59 KB, 下载次数: 3)
昨天 00:50 上传
下载次数: 3

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

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


     转换成10进制以后的文件,点击这里可以下载: 原始数据1转换成10进制后.txt (25.59 KB, 下载次数: 0)
昨天 09:15 上传
下载次数: 0


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

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


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

    虽然方法没有问题,但是加热机构的效率的确有点低,加热速度有些慢,所以,我们更换一个功率更大的加热器,再重新测试一下看看:
采集到的原始数据2.txt (14.39 KB, 下载次数: 0)
3 小时前 上传
下载次数: 0

原始数据2转换成10进制后.txt.txt (14.75 KB, 下载次数: 0)
3 小时前 上传
下载次数: 0



图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度的时候,关闭加热器,继续采集温度,继续观测温度,观看系统的“惯性”。
惯性测量的原始数据.txt (22.77 KB, 下载次数: 0)
1 小时前 上传
下载次数: 0

惯性测量数据转换为10进制.txt (22.8 KB, 下载次数: 0)
1 小时前 上传
下载次数: 0

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

 

更多内容请登录bbs.zyxmcu.com查看


文章评论0条评论)

登录后参与讨论
我要评论
0
11
关闭 站长推荐上一条 /2 下一条