查看: 3820|回复: 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程序设计基础 blinker物联网解决方案

热门推荐

【教程】pico+hx711电子秤
【教程】pico+hx711电子秤
pico+hx711电子秤 【前言】 我做过多款电子秤,这次移植到pico上
ESP8266+Onenet平台远程数据传输和控制
ESP8266+Onenet平台远程数
这是我的第一个diy,主要功能实现了onenet云平台温湿度数据的传输和远程控制LED灯平台
【Arduino】108种传感器模块系列实验(48)---三轴ADXL345模块
【Arduino】108种传感器模
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是
ps2遥控小车——uno实现
ps2遥控小车——uno实现
前几天在阁楼发现了好久以前3d打印,激光切割的底盘,于是决定做这个东西 正好手上又
震惊!OLED菜单竟只用10行代码就可以完成到完美!!!
震惊!OLED菜单竟只用10行
震惊!OLED菜单竟只用10行代码就可
Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
快速回复 返回顶部 返回列表