PID控制算法

本文介绍了PID控制算法,包括二位式控制算法的特点和流程,然后详细阐述了PID控制算法的流程、数据序列分析、数学模型,并具体讨论了基于单片机的位置式和增量式PID控制算法的实现,其中重点解析了积分项Sk和微分项Dk的处理方法。
摘要由CSDN通过智能技术生成

一、二位式控制算法

流程

Sv
OUT
Pv
用户设定值
位式控制算法
执行部件
控制对像
传感器

Sv:目标值
Pv:控制对象当前值

特点

1.输出信号只有H/L两种
2.只考察当前状态值
3.算法输出信号OUT依据:
O U T = { P v < S v ⇒ H P v ≥ S v ⇒ L OUT=\begin{cases} Pv<Sv \rArr H\\ Pv\ge Sv \rArr L \end{cases} OUT={Pv<SvHPvSvL

二、PID控制算法

流程

Sv
Out
Pv
用户设定值
偏差E=Sv-Pv
历史偏差
当前偏差
最近偏差
+
负载
传感器

分析数据序列

从开始以来采样到的数据序列: X 1 , X 2 , X 3 ⋯ X k − 2 , X k − 1 , X k X_1,X_2,X_3 \cdots X_{k-2},X_{k-1},X_k X1X2X3Xk2Xk1Xk
通过分析数据序列可得到以下3方面信息:
1.比例控制
E k = S v − X k { E k > 0 : 当 前 控 制 未 达 标 E k = 0 : 当 前 控 制 正 好 达 标 E k < 0 : 当 前 控 制 超 标 E_k=Sv-X_k\begin{cases} E_k>0:当前控制未达标\\ E_k=0:当前控制正好达标\\ E_k<0:当前控制超标 \end{cases} Ek=SvXkEk>0:Ek=0:Ek<0:
P o u t = K p × E k + O U T 0 P_{out}=K_p \times E_k+OUT_0 Pout=Kp×Ek+OUT0
2.积分算法
历史偏差序列: E 1 , E 2 , E 3 ⋯ E k − 2 , E k − 1 , E k E_1,E_2,E_3 \cdots E_{k-2},E_{k-1},E_k E1E2E3Ek2Ek1Ek
S k = E 1 + E 2 + E 3 + ⋯ + E k − 2 + E k − 1 + E k S_k=E_1+E_2+E_3 +\cdots +E_{k-2}+E_{k-1}+E_k Sk=E1+E2+E3++Ek2+Ek1+Ek
S k { S k > 0 : 从 开 始 以 来 大 部 分 时 间 未 达 标 S k = 0 S k < 0 : 从 开 始 以 来 大 部 分 时 间 达 标 S_k\begin{cases} S_k>0:从开始以来大部分时间未达标\\ S_k=0\\ S_k<0:从开始以来大部分时间达标 \end{cases} SkSk>0:Sk=0Sk<0:
I o u t = K p × S k + O U T 0 I_{out}=K_p\times S_k+OUT_0 Iout=Kp×Sk+OUT0
3.微分算法
最近两次偏差相减:
D k = E k − E k − 1 { D k > 0 : 偏 差 有 增 大 趋 势 D k = 0 : 偏 差 没 有 变 化 D k < 0 : 偏 差 有 减 小 趋 势 D_k=E_k-E_{k-1}\begin{cases} D_k>0:偏差有增大趋势\\ D_k=0:偏差没有变化\\ D_k<0:偏差有减小趋势 \end{cases} Dk=EkEk1Dk>0:Dk=0:Dk<0:
D o u t = K p × D k + O U T 0 D_{out}=K_p\times D_k+OUT_0 Dout=Kp×Dk+OUT0

PID控制算法的数学模型

P I D o u t = P o u t + I o u t + D o u t = ( K p × E k + O U T 0 ) + ( K p × S k + O U T 0 ) + ( K p × D k + O U T 0 ) = K p × ( E k + S k + D k ) + O U T 0 \begin{aligned} PID_{out}&=P_{out}+I_{out}+D_{out} \\&=(K_p \times E_k+OUT_0)+(K_p\times S_k+OUT_0)+(K_p\times D_k+OUT_0) \\&=K_p \times (E_k+S_k+D_k)+OUT_0 \end{aligned} PIDout=Pout+Iout+Dout=(Kp×Ek+OUT0)+(Kp×Sk+OUT0)+(Kp×Dk+OUT0)=Kp×(Ek+Sk+Dk)+OUT0

基于单片机的PID控制算法

S k S_k Sk 的处理:
S k = 1 T i × ∑ k = 0 n E k × T S_k=\dfrac{1}{T_i} \times \sum_{k=0}^n{E_k} \times T Sk=Ti1×k=0nEk×T
D k D_k Dk 的处理:
D k = T d × ( E k − E k − 1 T ) D_k=T_d \times (\dfrac{E_k-E_{k-1}}{T} ) Dk=Td×(TEkEk1)
其中: T T T为采样周期(计算周期)、 T i T_i Ti为积分常数、 T d T_d Td为微分常数

位置式PID控制算法

O U T = ( K p × E k ) + ( K p × T T i × ∑ k = 0 n E k ) + ( K p × T d T × ( E k − E k − 1 ) ) + O U T 0 (1) OUT=(K_p \times E_k)+(K_p \times \dfrac{T}{T_i} \times \sum_{k=0}^n{E_k})+(K_p \times \dfrac{T_d}{T} \times (E_k-E_{k-1}))+OUT_0 \tag{1} OUT=(Kp×Ek)+(Kp×TiT×k=0nEk)+(Kp×TTd×(EkEk1))+OUT0(1)

增量式PID控制算法

Δ O U T = O U T k − O U T k − 1 O U T k − 1 = ( K p × E k − 1 ) + ( K p × T T i × ∑ k = 0 n − 1 E k ) + ( K p × T d T × ( E k − 1 − E k − 2 ) ) + O U T 0 ∴ Δ O U T = ( 1 ) − ( 2 ) Δ O U T = K p × ( E k − E k − 1 ) + K p × T T i × E k + K p × T d T × ( E k − 2 E k − 1 + E k − 2 ) (2) \begin{aligned} \Delta OUT&=OUT_k-OUT_{k-1} \\ OUT_{k-1}&=(K_p \times E_{k-1})+(K_p \times \dfrac{T}{T_i} \times \sum_{k=0}^{n-1}{E_k})+(K_p \times \dfrac{T_d}{T} \times (E_{k-1}-E_{k-2}))+OUT_0 \tag{2} \\ \therefore \Delta OUT&=(1)-(2) \\ \Delta OUT&=K_p \times(E_k-E_{k-1})+K_p \times \dfrac{T}{T_i} \times E_k+K_p \times \dfrac{T_d}{T} \times (E_k-2E_{k-1}+E_{k-2}) \end{aligned} ΔOUTOUTk1ΔOUTΔOUT=OUTkOUTk1=(Kp×Ek1)+(Kp×TiT×k=0n1Ek)+(Kp×TTd×(Ek1Ek2))+OUT0=(1)(2)=Kp×(EkEk1)+Kp×TiT×Ek+Kp×TTd×(Ek2Ek1+Ek2)(2)

单片机中增量式PID控制算法实现
void PID_Init()			//PID初始化
{
	pid.sv=0;			//设定值
	pid.pv=0;			//当前值
	pid.Ek=0;			//当前偏差值
	pid.Ek_1=0;			//上次偏差值
	pid.Ek_2=0;			//前次偏差值
	pid.out=0;			//输出值
	pid.increase=0;		//增量值

/*以下3个为经验值*/
	pid.Kp=;
	pid.Ki=;
	pid.Kd=;
}


float PID_Calc(float sv,float pv)			//PID计算
{
 float dacx;
 pid.sv=(float)sv;							//设定值
 pid.pv=(float)Get_Adc_Average(pv,20);		//设置AD采样通道
 pid.Ek=pid.sv-pid.pv;						//当前偏差值
	
 pid.out=pid.Kp*(pid.Ek-pid.Ek_1)+pid.Ki*pid.Ek+pid.Kp*(pid.Ek-2*pid.Ek_1+pid.Ek_2);
  
 if(pid.increase>20)
  {
	pid.increase=20;
  }else if(pid.increase<-20){
	pid.increase=-20;
  }

 pid.out+=pid.increase;
 
 HAL_DAC_SetValue(&DAC1_Handler,DAC_CHANNEL_1,DAC_ALIGN_12B_R,pid.out);//设置DAC值
 
 dacx=HAL_DAC_GetValue(&DAC1_Handler,DAC_CHANNEL_1) * (3.3/4096);
 printf("t0.txt=\"%f\"",dacx);				//在串口屏上打印DAC值
 printf("%c%c%c",0xff,0xff,0xff);
   
 pid.Ek_2=pid.Ek_1;							//更新偏差值
 pid.Ek_1=pid.Ek; 
 
 return 0;
}

/*
此代码通过单片机AD/DA功能实现,仅供参考
有很多不当之处请见谅,若能指出则更好 ○| ̄|_
*/

本文部分内容来源于网络,内容均为非盈利,如有侵权请告知,马上删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值