关于单片机的PID控制程序-Arduino中文社区 - Powered by Discuz!
查看: 4037|回复: 1

关于单片机的PID控制程序

[复制链接]

该用户从未签到

发表于 2016-3-8 17:52 | 显示全部楼层 |阅读模式
在网上找了大概3个版本的PID控制程序,但逻辑不同,不知道那个版本是正确的?
版本1:应该是基于△Uk=A*e(k)+B*e(k-1)+C*e(k-2)
typedef struct PID
{
    int SetPoint; //设定目标Desired Value
    double Proportion; //比例常数Proportional Const
    double Integral; //积分常数Integral Const
    double Derivative; //微分常数Derivative Const
    int LastError; //Error[-1]
    int PrevError; //Error[-2]
} PID;

static PID sPID;
static PID *sptr = &sPID;

int IncPIDCalc(int NextPoint)
{
    int iError, iIncpid; //当前误差
    iError = sptr->SetPoint - NextPoint; //增量计算
    iIncpid = sptr->Proportion * iError //E[k]项
             - sptr->Integral * sptr->LastError //E[k-1]项
             + sptr->Derivative * sptr->PrevError; //E[k-2]项
    sptr->PrevError = sptr->LastError;   //存储误差,用于下次计算
    sptr->LastError = iError;
    return(iIncpid);                         //返回增量值
}

版本2:应该是基于△Uk=Kp[e(k)-e(k-1)] + Ki*e(k) + Kd[e(k)-2e(k-1)+e(k-2)]
typedef struct PID {              //结构体定义

        int  SetPoint            //设定值
        int  Proportion;         // Proportion 比例系数
        int  Integral;            // Integral   积分系数
        int  Derivative;          // Derivative  微分系数
        int  LastError;          // Error[-1]  前一拍误差
        int  PreError;           // Error[-2]  前两拍误差

} PID;

//Title:增量式PID算法程序
//Description:给出一个误差增量
//Input: PID的P、I控制常数和之前的误差量(PID *pp)& 当前误差量(ThisError)
//Return: 误差增量templ
int PIDCal( PID *pp, int ThisError ){

//增量式PID算法(需要控制的不是控制量的绝对值,而是控制量的增量)

    int pError,dError,iError;
    long templ;
    pError = ThisError-pp->LastError;
    iError = ThisError;
    dError = ThisError-2*(pp->LastError)+pp->PreError;

    //增量计算
    templ=pp->Proportion*pError + pp->Integral*iError+pp->Derivative*dError;  //增量

    //存储误差用于下次运算
    pp->PreError  = pp->LastError;
    pp->LastError = ThisError;

    return ((int)(templ>>8));
}

版本3:不知道基于什么公式
typedef struct PID {

        double  SetPoint;           //  设定目标 Desired Value

        double  Proportion;         //  比例常数 Proportional Const
        double  Integral;           //  积分常数 Integral Const
        double  Derivative;         //  微分常数 Derivative Const

        double  LastError;          //  Error[-1]
        double  PrevError;          //  Error[-2]
        double  SumError;           //  Sums of Errors

} PID;

/*====================================================================================================
   PID计算部分
=====================================================================================================*/

double PIDCalc( PID *pp, double NextPoint )
{
    double  dError,
            Error;

        Error = pp->SetPoint -  NextPoint;          // 偏差
        pp->SumError += Error;                      // 积分
        dError = pp->LastError - pp->PrevError;     // 当前微分
        pp->PrevError = pp->LastError;
        pp->LastError = Error;
        return (pp->Proportion * Error              // 比例项
            +   pp->Integral * pp->SumError         // 积分项
            +   pp->Derivative * dError             // 微分项
        );
}

该用户从未签到

发表于 2016-3-11 11:58 | 显示全部楼层
PID只是一个算法,看你怎么用,这几个看都是正确的。增量型PID和位置式PID,就是对每次检测的误差处理方式不一样,都叫PID
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

热门推荐

arduino 2560串口无法通信问题
arduino 2560串口无法通信
这样将2560主板和蓝牙模块连接到一起进行通信,结果arduino2560可以通过电脑给蓝牙模
求助各位大佬,proteus8软件为什么搜不到uno板子
求助各位大佬,proteus8软
求各位大佬帮忙看看,小白第一次用就出了这个,泪了
【Arduino】168种传感器系列实验(171)---HLK-V20离线语音模块
【Arduino】168种传感器系
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是
esp8266网页配置wifi 及Blinker秘钥,实现远程开灯
esp8266网页配置wifi 及Bl
经过一段时间的学习借鉴,写了一段可以web配网,配Blinker秘钥的程序,借鉴很多大佬,
【Arduino】168种传感器模块系列实验(144)---0.91寸OLED液晶屏
【Arduino】168种传感器模
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是
Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
快速回复 返回顶部 返回列表