从恒温控制里学PID

概述

用PID来实现恒温,最简单的PID控制之一,也是最能直观感受PID具体含义的例子之一。

所谓恒温控制,就是温度高了,让它低一点,低了让它高一点,始终保持目标温度恒定的控制。这在各种恒温设备里有广泛的应用,比如电饭煲,热水器,空调...等等。

本文则是通过实现简单的恒温控制,来初步学习PID控制。

PID基本概念及特点

PID控制器,就是在过程控制中,按偏差的比例(P)、积分(I)和微分(D)进行控制,是应用最为广泛的一种自动控制器。在这里,可以简单称为比例器,积分器和微分器,它们最终都要告诉cpu怎么去输出控制量。

最基本的PID控制框图

基本公式:[公式]

控制器输入:目标信号和观测信号的偏差

控制器输出:驱动受控系统的控制量

所以PID是闭环控制算法,要实现PID算法,必须在硬件上具有闭环控制,这就得有反馈。比如控制一个温度,就得有一个测量温度的传感器,并将结果反馈到控制路线上,实现温度的控制。

它具有原理简单,易于实现,适用面广。虽然对于PID控制器,P、I、D的作用是互相补充、互相耦合的,但是好在各个参数对于控制器性能的影响程度有强有弱,所以控制参数相对独立,参数的选定比较简单等优点;而且在理论上可以证明,对于过程控制的典型对象──“一阶滞后+纯滞后”与“二阶滞后+纯滞后”的控制对象,PID控制器是一种最优控制。PID调节规律是连续系统动态品质校正的一种有效方法,它的参数整定方式简便,结构改变灵活(PI、PD、…)。

温度控制

温度控制框图如下:

可以说是最简单的PID控制模型。

一般而言,PID温度控制器的误差响应曲线如下所示:

误差响应曲线

可以从该时域信号曲线看出,此温度控制分为两个阶段,第一阶段在温度远小于目标温度时不采用PID控制,即是PID调节前阶段,第二阶段开始用PID控制。

从中也提取一些表征PID控制性能的关键参数:

  1. 上升时间 Rise Time
    误差第一次缩减到零所需时间,如图t1
  2. 过调量 Overshoot
    误差第一次过零点后,达到的峰值高度t2时
  3. 稳定时间 Settling Time
    当之后的误差绝对值在δ以内,说明系统达到稳态,第一次达到稳态所需的时间,如图t3
  4. 稳态误差 Steady-State Error
    系统稳态时与零偏移
  5. 动态偏差 Stability
    系统稳态时,误差的统计值IAE=sum(|error|)

而P、I、D对于上述关键参数的影响如下:

可以看到:

1、PID三个参数对于系统的影响是相互耦合的,没有哪个性能只受一个参数的影响;

2、PID三个参数的影响各有侧重点

总结如下:

a) Kp用于缩短系统上升时间;

b) Ki用于消除稳态误差;

c) Kd用于降低过冲和动态偏差;

温度控制实现

第一步,让PID离散化:

[公式]

其中 [公式] 就是是输入的误差量,因此,上式可以改写成如下形式:

[公式]

其中

[公式]

[公式]

[公式]

[公式]

[公式]

这样我们很容易理解PID参数的各自含义。

P是比例,P越大,响应越快。

I是积分,每一次采样都会记录误差量,可以理解成快慢。

D是微分,关心的是变化率,要不要打提前量。

实现简码如下:

float temp = 0.0f;                   //传感器温度,全局变量
void PidTempControl(void)
{
    float ee;
    float TempSet = 45.0f;           //目标温度

    float PidE0 = 0.0f;
    float PidKp = 0.0f,PidKi = 0.0f,PidKd = 0.0f;
    float PidOut = 0.0f;
    float PidSum = 0.0f,I_out = 0.0f;
    static float PidE1 = 0.0f;                

    PidKp = 15.0f;
    PidKi = 25.0f;
    PidKd = 0.0f;                         //初始化参数
  
    PidE0 = TempSet - temp;       //本次偏差
    ee = (PidE0 - PidE1);        //计算一阶偏差

    if(ee > 2.0f) ee = 2.0f;
    else if(ee < -2.0f) ee = -2.0f;

    PidSum += PidE0;                               //偏差之和

    if(PidSum > 5.0f) PidSum = 5.0f;
    else if(PidSum < -3.0f) PidSum = -3.0f;

    PidOut = PidKp * PidE0 + PidKd * ee;       //计算PID的比例和微分输出

    if(fabs(PidE0) < 3.0f)                     //如果温度相差小于3度则计入PID积分输出
    {
        if(PidSum > 5.0f) PidSum = 5.0f;
        else if(PidSum < -2.0f) PidSum = -2.0f;

        I_out = PidKi * PidSum;                      //积分输出


        if(fabs(PidE0) < -1.0f)                       //当前温度高于设定温度0.5度时,累计积分限制
        {
            if(PidSum > 5.5f) PidSum = 5.5f;
            if(PidSum > 0)    I_out  -= 1;               //当前温度高于设定温度0.5度时,消弱积分正输出
        } 

        PidOut += I_out;
    }
    else
    {
        PidSum = 0.0f;
    }

    PidOut *= 500;                                                 //与控制量的比例系数
    if(PidOut > 2500) PidOut = 2500;
    if(PidOut < 0)    PidOut = 400;
    if(PidE0 > 5.0f) PidOut = 2500;
    if(PidE0 < -2) PidOut =0;

    HeaterSet(PidOut);                              //输出控制量
    PidE1 = PidE0;   
}

参考文献:

【1】pid control system analysis design and technology

posted @ 2021-01-21 12:45  星辰大海!  阅读(1843)  评论(0编辑  收藏  举报