单片机之PID算法
说到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算法的更多相关文章
- PID算法笔记2
总所周知,PID算法是个很经典的东西.而做自平衡小车,飞行器PID是一个必须翻过的坎.因此本节我们来好好讲解一下PID,根据我在学习中的体会,力求通俗易懂.并举出PID的形象例子来帮助理解PID.一. ...
- PID算法通俗理解,平衡车,倒立摆,适合不理解PID算法的人来看!
先插句广告,本人QQ522414928,不熟悉PID算法的可以一起交流学习,随时在线(PID资料再我的另一篇博客里) 倒立摆资料连接↓ https://www.cnblogs.com/LiuXinyu ...
- PID算法原理 一图看懂PID的三个参数
找了好久这一篇算是很容易看懂的了 推荐给大家 写的十分清楚 原文作者DF创客社区virtualwiz LZ以前有个小小的理想,就是让手边的MCU自己"思考"起来,写出真正 ...
- 线性控制原理——PID算法应用
使用控制系统(PID)控制被控对象 PID控制的三要素:控制器,被控对象,反馈器.控制器就是一个数学模型,就PID来说,等同于PID算法.是对反馈量的一个处理与输出.通俗的说就是对于每个被控的量,我的 ...
- PID算法学习记录
最近做项目需要用到PID算法,这个本来是我的专业(控制理论与控制工程),可是我好像是把这个东西全部还给老师了. 没办法,只好抽时间来学习了. 先占个座,后续将持续更新!
- 位置式PID与增量式PID算法
位置式PID与增量式PID算法 PID控制是一个二阶线性控制器 定义:通过调整比例.积分和微分三项参数,使得大多数的工业控制系统获得良好的闭环控制性能. 优点 ...
- PID算法
所谓PID就是比例-积分-微分的英文缩写,但并不是必须同时具备这三种算法,也可以是 PD, PI,甚至只有 P算法控制,下面分别介绍每个参数的含义:首先需要明确一个事实就是,要实现PID算法,必须在硬 ...
- PID算法(c 语言)(转)
PID算法(c 语言)(来自老外) #include <stdio.h> #include<math.h> //定义PID 的结构体 struct _pid { int pv; ...
- PID控制器开发笔记之一:PID算法原理及基本实现
在自动控制中,PID及其衍生出来的算法是应用最广的算法之一.各个做自动控制的厂家基本都有会实现这一经典算法.我们在做项目的过程中,也时常会遇到类似的需求,所以就想实现这一算法以适用于更多的应用场景. ...
随机推荐
- java.util.ConcurrentModificationException详解
引用于http://blog.csdn.net/dabing69221/article/details/40065071 在使用set/map时,一个可爱的小bug:Java.util.Concurr ...
- Python学习:模块初识、数据类型
1.模块初识 在Python中,模块分为两种: (1)标准库 标准库无需安装,只要在使用的时候import就可以使用了 (2)第三方库 第三方库必须下载安装之后才能够引入使用 下面介绍两个基本的模块: ...
- java中异常处理
看到一篇异常处理的好文章: Java异常处理机制主要依赖于try,catch,finally,throw,throws五个关键字. try 关键字后紧跟一个花括号括起来的代码块,简称try块.同理:下 ...
- uname命令详解
1.简介: uname命令用于打印当前系统相关信息(内核版本号.硬件架构.主机名称和操作系统类型等). 2.命令语法: uname (选项) 3.选项: -a或--all:显示全部的信息: -m或-- ...
- Hadoop 学习之Docker
docker环境的配置请参考:http://www.cnblogs.com/frankliu/p/8052673.html hadoop-docker安装地址参考:https://hub.docker ...
- 虚拟网络VDC与VPC
当前互联网行业,内部 IT 基础资源云端化是主要趋势.云平台将资源管理抽象出来,比如云主机.云 DB 等,以服务的方式提供给用户,按需使用,从而带来更大的灵活性与经济性. 随着主机.DB.缓存.存储等 ...
- scrapy爬虫框架处理流程简介
1.SPIDERS的yeild将request发送给ENGIN2.ENGINE对request不做任何处理发送给SCHEDULER3.SCHEDULER( url调度器),生成request交给ENG ...
- ASP 错误捕捉,处理
Asp利用 On Error Resume Next捕捉异常,根据Err.Number判断是否有错误 注:On Error Goto 0取消捕捉异常 模板文件页面 <% Response.Buf ...
- 用swift写的一款小游戏,模仿的僵尸危机
https://github.com/123456qwer/WDZombies.git //git地址
- Python: 下载底层由Python2转Python3环境更新手记
谨记录运行环境改变过程中所碰到的坑. 下载底层运行环境由Python2移至Python3所遇到的问题及处理方法: 1.所引的第三方组件,基本都有替代支持:msvcr90.dll不再需要,有则报错2.引 ...