说到PID算法,想必大部人并不陌生,PID算法在很多方面都有重要应用,比如电机的速度控制,恒温槽的温度控制,四轴飞行器的平衡控制等等,作为闭环控制系统中的一种重要算法,其优点和可实现性都成为人们的首选。下面简单来讲解一下PID算法:

首先PID算法是有比例,积分,微分三部分组成,先说下比例部分,所谓比例部分,就是呈线性关系,举个例子,一个电热丝加热水,开始的时候温度很低,离50℃很大,这时应该加大功率,离目标温度越大,其功率应该越大,反之越小,这就是比例部分。

乍一看,既然比例部分已经可以控制温度了为啥还需要积分和微分部分呢,难道是多此一举么?其实不然,在实际中会出现这种情况,当加热到50℃时,系统很难停止下来,而是会持续一段时间,这样就会超过预设值,所以仅有比例控制并不完美,这是就需要积分部分和微分部分。积分部分就是把之前的误差全部累加起来,这样起始时由于误差很大加热功率就大,随着接近预设值后功率开始减少,微分部分就是起始时温度增加很快,表示此时需要很大的功率,随着温度接近预设值,其斜率开始减小最后为零,意味着功率也减少,当然很难为零,一般在一定的范围内波动。

现在开始用C语言来实现PID算法:

位置式:

比例部分

    Kp:比例系数  SetValue:预设值  FactValue:当前实际值  Error_1:当前误差

则比例部分为:

    Sp  =   Kp*(SetValue - FactValue)

或者

    Sp  =  Kp*Error_1

注解:Sp大小反应需要控制的量大小,比如Sp越大,功率越大。当Sp为负值时,表示要超过预设值,如果是电机,则需要反转

积分部分

    Ki:积分系数  Error_1:当前误差  Error_2:上一次误差  Error_3:上上一次误差  ........Error_n:开始时的误差

则积分部分为:

    Si  =  Ki*(Error_1+Error_2+Error_3+......+Error_n)

注解:因为整个是一个过程,所以上一次误差其实就是上一次的当前误差

微分部分

    Kd:微分系数  Error_1:当前误差  Error_2:上一次误差 

则微分部分为:

    Sd  =  Kd*(Error_1-Error_2)

综上部分的PID得:

    PID=Sp + Si + Sd = Kp*Error_1 + Ki*(Error_1+Error_2+Error_3+......+Error_n) + Kd*(Error_1-Error_2)

增量式

将上述推导的PID记作时间为k时刻的PID控制量,则

    PID(k) =Sp + Si + Sd = Kp*Error_1(k) + Ki*(Error_1(k)+Error_2(k-1)+Error_3(k-2)+......+Error_n(0)) + Kd*(Error_1(k)-Error_2(k-1))        1

将上式k=k-1代入得:

    PID(k-1) =Sp + Si + Sd = Kp*Error_1(k-1) + Ki*(Error_1(k-1)+Error_2(k-2)+Error_3(k-3)+......+Error_n(0)) + Kd*(Error_1(k-1)-Error_2(k-2))               2

1-2得:

    PID(k) - PID(k-1) =  Kp*(Error_1(k)-Error_1(k-1)) + Ki*(Error_1(k)) + Kd*(Error_1(k)-2*Error_2(k-1)+Error_2(k-2))

PID(k) - PID(k-1)记作detPID

    detPID = Kp*(Error_1(k)-Error_1(k-1)) + Ki*(Error_1(k)) + Kd*(Error_1(k)-2*Error_2(k-1)+Error_2(k-2))

这样就得到了增量式的PID算法,其计算的结果为增加的控制量

增量式的PID有个好处就是只与当前三个误差量有关系,与其他无关,这样就简化的处理过程,而且提高了精度,下面是PID源码:

/*文件名:PID.h*/

#ifndef  _PID_H_
#define _PID_H_ extern float Kp,Ki,Kd; //系数(全局变量)
extern float AclValue; //实际值
extern float SetValue; int PID(void); #endif
/*########################################################################
文件名:PID.c
时间: 2018.9.7
备注:无
#########################################################################*/ #include "PID.h" float Kp=,Ki=0.8,Kd=0.5; //系数 float SetValue=; //设定值 float AclValue=; //实际 float Error1=,Error2=,Error3=; //误差 /* 下面为增量式PID算法 */ /**********************************************************************************
函数名:PID
返回值:输出增量
参数:无
备注:当输出大于0表示小于预设值,当输出小于0表示大于预设值
***********************************************************************************/
int PID(void)
{
float OutValue =;
Error3 = SetValue - AclValue; OutValue = Kp*(Error3-Error2)+Ki*(Error3)+Kd*(Error3-*Error2+Error1); Error1=Error2; //这部分是迭代,因为上次的误差就是上次的当前误差
Error2=Error3; if(OutValue>) //这部分是规定最大输出增量
OutValue=;
if(OutValue<-)
OutValue=-; return OutValue;
}

下面给出计算机模拟代码;

#include "stdio.h"

float Kp=,Ki=,Kd=0.5;  //系数

float SetValue=;  //设定值

float AclValue=; //实际

float Error1=,Error2=,Error3=;     //误差

/*  下面为增量式PID算法  */

/**********************************************************************************
函数名:PID
返回值:输出增量
参数:无
备注:当输出大于0表示小于预设值,当输出小于0表示大于预设值
***********************************************************************************/
int PID(void)
{
float OutValue =;
Error3 = SetValue - AclValue; OutValue = Kp*(Error3-Error2)+Ki*(Error3)+Kd*(Error3-*Error2+Error1); Error1=Error2;
Error2=Error3; return OutValue;
} int main(void)
{
unsigned int i=;
while(i)
{ PID(); //特别注意这里:必须要运行,因为需要执行这一步:Error1=Error2; Error2=Error3; printf("当前实际值为:%f \n",AclValue); AclValue += PID(); i--);
    } 

    return ;
}

运行结果:

    

单片机之PID算法的更多相关文章

  1. PID算法笔记2

    总所周知,PID算法是个很经典的东西.而做自平衡小车,飞行器PID是一个必须翻过的坎.因此本节我们来好好讲解一下PID,根据我在学习中的体会,力求通俗易懂.并举出PID的形象例子来帮助理解PID.一. ...

  2. PID算法通俗理解,平衡车,倒立摆,适合不理解PID算法的人来看!

    先插句广告,本人QQ522414928,不熟悉PID算法的可以一起交流学习,随时在线(PID资料再我的另一篇博客里) 倒立摆资料连接↓ https://www.cnblogs.com/LiuXinyu ...

  3. PID算法原理 一图看懂PID的三个参数

    找了好久这一篇算是很容易看懂的了  推荐给大家   写的十分清楚   原文作者DF创客社区virtualwiz LZ以前有个小小的理想,就是让手边的MCU自己"思考"起来,写出真正 ...

  4. 线性控制原理——PID算法应用

    使用控制系统(PID)控制被控对象 PID控制的三要素:控制器,被控对象,反馈器.控制器就是一个数学模型,就PID来说,等同于PID算法.是对反馈量的一个处理与输出.通俗的说就是对于每个被控的量,我的 ...

  5. PID算法学习记录

    最近做项目需要用到PID算法,这个本来是我的专业(控制理论与控制工程),可是我好像是把这个东西全部还给老师了. 没办法,只好抽时间来学习了. 先占个座,后续将持续更新!

  6. 位置式PID与增量式PID算法

    位置式PID与增量式PID算法  PID控制是一个二阶线性控制器     定义:通过调整比例.积分和微分三项参数,使得大多数的工业控制系统获得良好的闭环控制性能.     优点             ...

  7. PID算法

    所谓PID就是比例-积分-微分的英文缩写,但并不是必须同时具备这三种算法,也可以是 PD, PI,甚至只有 P算法控制,下面分别介绍每个参数的含义:首先需要明确一个事实就是,要实现PID算法,必须在硬 ...

  8. PID算法(c 语言)(转)

    PID算法(c 语言)(来自老外) #include <stdio.h> #include<math.h> //定义PID 的结构体 struct _pid { int pv; ...

  9. PID控制器开发笔记之一:PID算法原理及基本实现

    在自动控制中,PID及其衍生出来的算法是应用最广的算法之一.各个做自动控制的厂家基本都有会实现这一经典算法.我们在做项目的过程中,也时常会遇到类似的需求,所以就想实现这一算法以适用于更多的应用场景. ...

随机推荐

  1. 【亲测】502 Bad Gateway 怎么解决?

    502 Bad Gateway 怎么解决? 1.什么是502 badgateway 报错 简单来说 502 是报错类型代码,bad gateway 错误的网关. 2.产生错误的原因 连接超时 具体原因 ...

  2. 面向连接的tcp 编程

    from socket import * serverSocket=socket(AF_INET,SOCK_STREAM) serverSocket.bind(("",8899)) ...

  3. Oracle创建pfile spfile 文件及其恢复

    1.Oralce在启动实例的时读取$ORACLE_HOME/dbs下面的初始化文件.初始化文件分为:A.静态参数文件PFILE,一般名为initSID.oraB.永久参数文件SPFILE,一般名为sp ...

  4. scrollview嵌套recyclerview卡顿现象

    方式一xml: android:nestedScrollingEnabled="false" <android.support.v7.widget.RecyclerView ...

  5. pyqt5 -——介绍及和pycharm的环境搭建

    pyqt5简介: yQt5的类存在与如下模块当中: ● QtCore ● QtGui ● QtWidgets ● QtMultimedia ● QtBluetooth ● QtNetwork ● Qt ...

  6. jquery 返回浏览器顶部

    经常在网页中看到有这样的现象,点击一个按钮,然后页面会跳到页面的中指定的位置,那这种效果是怎么实现的呢? 很多网页都有这种效果:返回顶部或者跳到不同的楼层(以下是天猫的效果) 实现原理: 1.我们来看 ...

  7. jenkins Manage and Assign Roles使用

    1.安装插件  Role-based Authorization Strategy 2.使用插件 3.进入 Manage and Assign Roles  配置Pattern 匹配项目, 如果要匹配 ...

  8. postgresql数据库varchar、char、text的比较

    名字 描述character varying(n), varchar(n) 变长,有长度限制character(n), char(n) 定长,不足补空白text 变长,无长度限制简单来说,varcha ...

  9. faster rcnn源码阅读笔记1

    自己保存的源码阅读笔记哈 faster rcnn 的主要识别过程(粗略) (开始填坑了): 一张3通道,1600*1600图像输入中,经过特征提取网络,得到100*100*512的feature ma ...

  10. zend studio mac

    zend studio mac是一款PHP语言集成开发环境(IDE),专为开发人员研发,它包含了所有组件的开发为完整的PHP应用程序生命周期提供条件.zend studio是很多开发人员.程序员等专业 ...