以梦为马,不负韶华

搜索
查看: 4559|回复: 11
收起左侧

[原创] PID调节有关介绍

[复制链接]
发表于 2015-11-5 17:31:02 显示全部楼层 |阅读模式
当今的闭环自动控制技术都是基于反馈的概念以减少不确定性。反馈理论的要素包括三个部分:测量、比较和执行。测量关心的是被控变量的实际值,与期望值相比较,用这个偏差来纠正系统的响应,执行调节控制。在工程实际中,应用最为广泛的调节器控制规律为比例、积分、微分控制,简称PID控制,又称PID调节。
PID控制器(比例-积分-微分控制器)是一个在工业控制应用中常见的反馈回路部件,由比例单元P、积分单元I和微分单元D组成。
PID调节方法
PID是工业生产中最常用的一种控制方式,PID调节仪表也是工业控制中最常用的仪表之一,PID 适用于需要进行高精度测量控制的系统,可根据被控对象自动演算出最佳PID控制参数。
clip_image001.jpg
PID参数自整定控制仪可选择外给定(或阀位)控制功能。可取代伺服放大器直接驱动执行机构(如阀门等)。PID外给定(或阀位)控制仪可自动跟随外部给定值(或阀位反馈值)进行控制输出(模拟量控制输出或继电器正转、反转控制输出)。可实现自动/手动无扰动切换。手动切换至自动时,采用逼近法计算,以实现手动/自动的平稳切换。PID外给定(或阀位)控制仪可同时显示测量信号及阀位反馈信号。
PID光柱显示控制仪集数字仪表与模拟仪表于一体,可对测量值及控制目标值进行数字量显示(双LED数码显示),并同时对测量值及控制目标值进行相对模拟量显示( 双光柱显示),显示方式为双LED数码显示+双光柱模拟量显示,使测量值的显示更为清晰直观。
PID参数自整定控制仪可随意改变仪表的输入信号类型。采用最新无跳线技术,只需设定仪表内部参数,即可将仪表从一种输入信号改为另一种输入信号。
PID参数自整定控制仪可选择带有一路模拟量控制输出(或开关量控制输出、继电器和可控硅正转、反转控制)及一路模拟量变送输出,可适用于各种测量控制场合。
PID参数自整定控制仪支持多机通讯,具有多种标准串行双向通讯功能,可选择多种通讯方式,如RS-232、RS-485、RS-422等,通讯波特率300~9600bps 仪表内部参数自由设定。可与各种带串行输入输出的设备(如电脑、可编程控制器、PLC 等)进行通讯,构成管理系统。
1.PID常用口诀:
参数整定找最佳,从小到大顺序查
先是比例后积分,最后再把微分加
曲线振荡很频繁,比例度盘要放大
曲线漂浮绕大弯,比例度盘往小扳
曲线偏离回复慢,积分时间往下降
曲线波动周期长,积分时间再加长
曲线振荡频率快,先把微分降下来
动差大来波动慢。微分时间应加长
理想曲线两个波,前高后低4比1
一看二调多分析,调节质量不会低
2.PID控制器参数的工程整定,各种调节系统中P.I.D参数经验数据以下可参照:
温度T: P=20~60%,T=180~600s,D=3-180s
压力P: P=30~70%,T=24~180s,
液位L: P=20~80%,T=60~300s,
流量F: P=40~100%,T=6~60s。[1]
发表于 2015-11-5 17:31:02 显示全部楼层
请教一个问题:

做的是一个由51单片机控制的直流电动机调速系统,我使用的是增量式PID算法,输入为偏差速度,请问输出的是速度么??如果是,请问要怎么才能转化为PWM波。我没有AD/DA模块可以去测量电压那些东西,我是使用光电编码盘测速的。请问我要怎么才能够控制到电动机的速度??如果可以的话,请详细解释一下。下面给出我使用的PID算法。
#include <reg52.h>
#include <intrins.h>
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long int uint32;
//??函数声明
void PIDOutput ();
void PIDOperation ();
//================================================================
typedef struct PIDValue
{
uint32 Ek_Uint32[3]; //差值保存,给定和反馈的差值
uint8 EkFlag_Uint8[3]; //符号,1则对应的为负数,0为对应的为正数
uint8 KP_Uint8;
uint8 KI_Uint8;
uint8 KD_Uint8;
uint16 Uk_Uint16;//上一时刻的控制电压
uint16 RK_Uint16;//设定值
uint16 CK_Uint16;//实际值
}PIDValueStr;
PIDValueStr PID;
uint8 out ;// 加热输出
uint8 count;// 输出时间单位计数器
/*================================================================
PID = Uk + KP*[E(k)-E(k-1)]+KI*E(k)+KD*[E(k)-2E(k-1)+E(k-2)];(增量型PID算式)
函数入口: RK(设定值),CK(实际值),KP,KI,KD
函数出口: U(K)
//PID运算函数
================================================================*/
void PIDOperation (void)
{
uint32 Temp[3];//中间临时变量
uint32 PostSum;//正数和
uint32 NegSum;//负数和
Temp[0] = 0;
Temp[1] = 0;
Temp[2] = 0;
PostSum = 0;
NegSum = 0;
if( PID.RK_Uint16 > PID.CK_Uint16 )//设定值大于实际值否?
{
if( PID.RK_Uint16 - PID.CK_Uint16 >10 )//偏差大于10否?
{
PID.Uk_Uint16 = 100;}//偏差大于10为上限幅值输出(全速加热)
else
{
Temp[0] = PID.RK_Uint16 - PID.CK_Uint16;//偏差<=10,计算E(k)
PID.EkFlag_Uint8[1]=0;//E(k)为正数,因为设定值大于实际值
//数值移位
PID.Ek_Uint32[2] = PID.Ek_Uint32[1];
PID.Ek_Uint32[1] = PID.Ek_Uint32[0];
PID.Ek_Uint32[0] = Temp[0];
//================================================================
if( PID.Ek_Uint32[0] >PID.Ek_Uint32[1] )//E(k)>E(k-1)否?
{
Temp[0]=PID.Ek_Uint32[0] - PID.Ek_Uint32[1];//E(k)>E(k-1)
PID.EkFlag_Uint8[0]=0; }//E(k)-E(k-1)为正数
else
{
Temp[0]=PID.Ek_Uint32[0] - PID.Ek_Uint32[1];//E(k)<E(k-1)
PID.EkFlag_Uint8[0]=1; }//E(k)-E(k-1)为负数
//================================================================
Temp[2]=PID.Ek_Uint32[1]*2 ;// 2E(k-1)
if( (PID.Ek_Uint32[0]+ PID.Ek_Uint32[2])>Temp[2] )//E(k-2)+E(k)>2E(k-1)否?
{
Temp[2]=(PID.Ek_Uint32[0]+ PID.Ek_Uint32[2])-Temp[2];//E(k-2)+E(k)>2E(k-1)
PID.EkFlag_Uint8[2]=0; }//E(k-2)+E(k)-2E(k-1)为正数
else
{
Temp[2]=Temp[2]-(PID.Ek_Uint32[0]+ PID.Ek_Uint32[2]); //E(k-2)+E(k)<2E(k-1)
PID.EkFlag_Uint8[2]=1; }//E(k-2)+E(k)-2E(k-1)为负数

//================================================================
Temp[0] = (uint32)PID.KP_Uint8 * Temp[0];// KP*[E(k)-E(k-1)]
Temp[1] = (uint32)PID.KI_Uint8 * PID.Ek_Uint32[0];// KI*E(k)
Temp[2] = (uint32)PID.KD_Uint8 * Temp[2];// KD*[E(k-2)+E(k)-2E(k-1)]
//以下部分代码是讲所有的正数项叠加,负数项叠加?
//KP*[E(k)-E(k-1)]
if(PID.EkFlag_Uint8[0]==0)
PostSum += Temp[0];//正数和
else
NegSum += Temp[0];//负数和
// KI*E(k)
if(PID.EkFlag_Uint8[1]==0)
PostSum += Temp[1];//正数和

//KD*[E(k-2)+E(k)-2E(k-1)]
if(PID.EkFlag_Uint8[2]==0)
PostSum += Temp[2];//正数和
else
NegSum += Temp[2];//负数和
//U(K)
PostSum += (uint32)PID.Uk_Uint16;

if(PostSum > NegSum )// 是否控制量为正数
{ Temp[0] = PostSum - NegSum;
if( Temp[0] < 100 )//小于上限幅值则为计算值输出
PID.Uk_Uint16 = (uint16)Temp[0];
else
PID.Uk_Uint16 = 100;//否则为上限幅值输出
}
else//控制量输出为负数,则输出0(下限幅值输出)
PID.Uk_Uint16 = 0;
}
}
else
{ PID.Uk_Uint16 = 0; }
}
回复 支持 反对

使用道具 举报

发表于 2015-11-5 17:31:02 显示全部楼层
谢谢分享,受益匪浅{:1106_362:}
回复 支持 反对

使用道具 举报

发表于 2015-11-5 17:31:02 显示全部楼层
写的挺严谨的……挺好{:1106_362:}
回复 支持 反对

使用道具 举报

发表于 2015-11-5 17:31:02 显示全部楼层
2.PID控制器参数的工程整定,各种调节系统中P.I.D参数经验数据以下可参照:
温度T: P=20~60%,T=180~600s,D=3-180s
压力P: P=30~70%,T=24~180s,
液位L: P=20~80%,T=60~300s,
流量F: P=40~100%,T=6~60s。

口诀还是挺难得,这个经验型的还好,下次试试看
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-11-5 17:31:02 显示全部楼层
fanzju 发表于 2015-11-7 10:57
2.PID控制器参数的工程整定,各种调节系统中P.I.D参数经验数据以下可参照:
温度T: P=20~60%,T=180~600s,D ...

嗯,确实是这样。

123wys 于 2015-11-07 14:05:48 补充以下内容:
谢谢啊
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-11-5 17:31:02 显示全部楼层
faron 发表于 2015-11-7 10:52
谢谢分享,受益匪浅

嗯  这样还是不错的{:1106_362:}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-11-5 17:31:02 显示全部楼层
沈伦 发表于 2015-11-7 10:43
请教一个问题:

做的是一个由51单片机控制的直流电动机调速系统,我使用的是增量式PID算法,输入为偏差 ...

这个问题我得好好考虑
回复 支持 反对

使用道具 举报

发表于 2015-11-5 17:31:02 显示全部楼层

先看看是什么呢
回复 支持 反对

使用道具 举报

不想打字就选择快捷回复吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|以梦为马,不负韶华

GMT+8, 2025-4-19 14:50

Powered by 以梦为马,不负韶华

© 2024-2099 Meng.Horse

快速回复 返回顶部 返回列表