(完整word版)温度控制的PID算法 及C程序实现

合集下载

温度的PID控制及程序示例

温度的PID控制及程序示例

温度的PID 控制一.温度检测部分首先要OK. 二、PID 调节作用 PID 控制时域的公式))()(1)(()(⎰++=dtt de Td t e Ti t e Kp t y 分解开来:(1) 比例调节器y(t) = Kp * e(t)e(k) 为当前的温差(设定值与检测值的插值) y(k) 为当前输出的控制信号(需要转化为PWM 形式)# 输出与输入偏差成正比。

只要偏差出现,就能及时地产生与之成比例的调节作用,使被控量朝着减小偏差的方向变化,具有调节及时的特点。

但是, Kp 过大会导致动态品质变坏,甚至使系统不稳定。

比例调节器的特性曲线. (2) 积分调节器y(t) = Ki * ∫(e(t))dt Ki = Kp/Ti Ti 为积分时间#TI 是积分时间常数,它表示积分速度的大小,Ti 越大,积分速度越慢,积分作用越弱。

只要偏差不为零就会产生对应的控制量并依此影响被控量。

增大Ti 会减小积分作用,即减慢消除静差的过程,减小超调,提高稳定性。

(3) 微分调节器y(t) = Kd*d(e(t))/dt Kd = Kp*Td Td 为微分时间#微分分量对偏差的任何变化都会产生控制作用,以调整系统输出,阻止偏差变化。

偏差变化越快,则产生的阻止作用越大。

从分析看出,微分作用的特点是:加入微分调节将有助于减小超调量,克服震荡,使系统趋于稳定。

他加快了系统的动作速度,减小调整的时间,从而改善了系统的动态性能。

三.PID 算法:由时域的公式离散化后可得如下公式:y(k) = y(k-1)+(Kp+Ki+Kd)*e(k)-(Kp +2*Kd)*e(k-1) + Kd*e(k-2)y(k) 为当前输出的控制信号(需要转化为PWM形式)y(k-1)为前一次输出的控制信号e(k) 为当前的温差(设定值与检测值的插值)e(k-1) 为一次前的温差e(k-2) 为二次前的温差Kp 为比例系数Ki = Kp*T/Ti T为采样周期Kd = Kp*Td/T四.PID参数整定(确定Kp,Ts,Ti,Td):温度控制适合衰减曲线法,需要根据多次采样的数据画出响应曲线。

温度控制的PID算法及C程序实现

温度控制的PID算法及C程序实现

本文档如对你有帮助,请帮忙下载支持!温度控制与PID 算法温度控制与PID 算法j 较为复杂,下面结合实际浅显易懂的阐述一下 PID 控制理论,将温度控制及PID 算法作一个简单的描述。

1.温度控制的框图asgstiB这是一个典型的闭环控制系统,用于控制加热温区的温度( PV )保持在恒定的温度 设定值(SV )。

系统通过温度采集单元反馈回来的实时温度信号( PV )获取偏差值(EV ),偏差值经过 PID 调节器运算输出,控制发热管的发热功率,以克服偏差,促使偏差趋近 于零。

例如,当某一时刻炉内过PCB 板较多,带走的热量较多时,即导致温区温度下降,这时,通过反馈的调节作用,将使温度迅速回升。

其调节过程如下:温度控制的功率输出采用脉宽调制的方法。

固态继电器电压U ouT 。

当SSR 的触发角触发时,电源电压U AN 通过SSR 的输出端加到发热管的两 端;当SSR 的触发角没有触发信号时,SSR 关断。

因此,发热管两端的平均电压为U d = (t/T )* U AN =K* U AN其中K= t/T ,为一个周期T 中,SSR 触发导通的比率,称为负载电压系数或是占空比, K的变化率在0- 1之间。

一般是周期 T 固定不便,调节t,当t 在0-T 的范围内变化时, 发热管的电压即在 0- U AN 之间变化,这种调节方法称为定频调宽法。

下面将要描述的 PID调节器的算式在这里的实质即是运算求出一个实时变化的,能够保证加热温区在外界干扰的情况下仍能保持温度在一个较小的范围内变化的合理的负载电压系数K 。

甌汕血Ikinl 曲汀 備錢(哉0.1/ 1A『'、、A____ 5^50 工 /it TTVI PID 调节鼬 固憲继电器勻岌恿習 X ?n -Tr-Zn 4f t 沮LEV)*冲端出易度 A 崭1出功率SSR 的输出端为脉宽可调的2.温度控制的两个阶段本文档如对你有帮助,请帮忙下载支持! 本文档如对你有帮助,请帮忙下载支持!温度控制系统是一个惯性较大的系统,也就是说,当给温区开始加热之后, 并不能立即观察得到温区温度的明显上升;同样的,当关闭加热之后, 温区的温度仍然有一定程度的上升。

PID控制算法的C语言实现(完整版)

PID控制算法的C语言实现(完整版)

PID控制算法的C语言实现(完整版) 在现代工业生产中,为了实现对生产过程的精确控制,我们需要采用一种能够根据实际需求自动调整参数的控制算法。

PID(Proportional-Integral-Derivative)控制算法就是这样一种广泛应用于工业控制系统的算法。

本文将详细介绍PID控制算法的C语言实现,包括算法的基本原理、实现方法以及注意事项。

我们来了解一下PID控制算法的基本原理。

PID控制器由三个部分组成:比例(P)、积分(I)和微分(D)。

这三个部分分别对误差信号进行处理,然后将处理后的信号相加得到控制输出。

具体来说,比例部分根据误差信号的大小产生相应的控制作用;积分部分对误差信号进行累积,以消除系统的静差;微分部分对误差信号的变化趋势进行预测,以便及时调整控制策略。

通过这三个部分的综合作用,PID控制器能够实现对生产过程的精确控制。

接下来,我们来看一下如何用C语言实现PID控制算法。

我们需要定义一些变量来存储所需的参数和状态信息。

例如,我们需要定义比例系数Kp、积分系数Ki、微分系数Kd以及误差信号e等。

我们还需要定义一些变量来存储上一次的误差信号和积分项等。

这些变量的定义如下:```cdouble Kp, Ki, Kd; // 比例、积分、微分系数double e; // 当前误差信号double de; // 当前误差信号的导数double last_e; // 上一次的误差信号double integral; // 积分项有了这些变量之后,我们就可以开始实现PID控制器的计算过程了。

PID控制器的计算过程主要包括以下几个步骤:1. 计算误差信号:当前误差信号等于期望值与实际值之差。

2. 计算比例项:比例项等于当前误差信号乘以比例系数Kp;3. 计算积分项:积分项等于当前误差信号乘以积分系数Ki加上累积误差信号乘以积分系数Ki;4. 计算微分项:微分项等于当前误差信号的导数乘以微分系数Kd;5. 计算控制输出:控制输出等于比例项、积分项和微分项之和。

温度控制的PID算法 及C程序实现

温度控制的PID算法 及C程序实现

温度控制与PID算法温度控制与PID算法j较为复杂,下面结合实际浅显易懂的阐述一下PID控制理论,将温度控制及PID算法作一个简单的描述。

1.温度控制的框图这是一个典型的闭环控制系统,用于控制加热温区的温度(PV)保持在恒定的温度设定值(SV)。

系统通过温度采集单元反馈回来的实时温度信号(PV)获取偏差值(EV),偏差值经过PID调节器运算输出,控制发热管的发热功率,以克服偏差,促使偏差趋近于零。

例如,当某一时刻炉内过PCB板较多,带走的热量较多时,即导致温区温度下降,这时,通过反馈的调节作用,将使温度迅速回升。

其调节过程如下:温度控制的功率输出采用脉宽调制的方法。

固态继电器SSR的输出端为脉宽可调的电压U OUT 。

当SSR的触发角触发时,电源电压U AN通过SSR的输出端加到发热管的两端;当SSR的触发角没有触发信号时,SSR关断。

因此,发热管两端的平均电压为U d=(t/T)* U AN=K* U AN其中K=t/T,为一个周期T中,SSR触发导通的比率,称为负载电压系数或是占空比,K 的变化率在0-1之间。

一般是周期T固定不便,调节t, 当t在0-T的范围内变化时,发热管的电压即在0-U AN之间变化,这种调节方法称为定频调宽法。

下面将要描述的PID 调节器的算式在这里的实质即是运算求出一个实时变化的,能够保证加热温区在外界干扰的情况下仍能保持温度在一个较小的范围内变化的合理的负载电压系数K。

2.温度控制的两个阶段温度控制系统是一个惯性较大的系统,也就是说,当给温区开始加热之后,并不能立即观察得到温区温度的明显上升;同样的,当关闭加热之后,温区的温度仍然有一定程度的上升。

另外,热电偶对温度的检测,与实际的温区温度相比较,也存在一定的滞后效应。

这给温度的控制带来了困难。

因此,如果在温度检测值(PV)到达设定值时才关断输出,可能因温度的滞后效应而长时间超出设定值,需要较长时间才能回到设定值;如果在温度检测值(PV)未到设定值时即关断输出,则可能因关断较早而导致温度难以达到设定值。

温度控制的PID算法的C语言程序

温度控制的PID算法的C语言程序

我的题目是:基于PID算法的温度控制系统89C51单片机,通过键盘输入预设值,与DS18B20测得的实际值做比较,然后驱动制冷或加热电路。

用keil C语言来实现PID的控制。

最佳答案//PID算法温控C语言2008-08-17 18:58#include<reg51.h>#include<intrins.h>#include<math.h>#include<string.h>struct PID {unsigned int SetPoint; // 设定目标 Desired Valueunsigned int Proportion; // 比例常数 Proportional Constunsigned int Integral; // 积分常数 Integral Constunsigned int Derivative; // 微分常数 Derivative Constunsigned int LastError; // Error[-1]unsigned int PrevError; // Error[-2]unsigned int SumError; // Sums of Errors};struct PID spid; // PID Control Structureunsigned int rout; // PID Response (Output)unsigned int rin; // PID Feedback (Input)sbit data1=P1^0;sbit clk=P1^1;sbit plus=P2^0;sbit subs=P2^1;sbit stop=P2^2;sbit output=P3^4;sbit DQ=P3^3;unsigned char flag,flag_1=0;unsigned char high_time,low_time,count=0;//占空比调节参数unsigned char set_temper=35;unsigned char temper;unsigned char i;unsigned char j=0;unsigned int s;/*********************************************************** 延时子程序,延时时间以12M晶振为准,延时时间为30us×time***********************************************************/ void delay(unsigned char time){unsigned char m,n;for(n=0;n<time;n++)for(m=0;m<2;m++){}}/*********************************************************** 写一位数据子程序***********************************************************/ void write_bit(unsigned char bitval){EA=0;DQ=0; /*拉低DQ以开始一个写时序*/if(bitval==1){_nop_();DQ=1; /*如要写1,则将总线置高*/}delay(5); /*延时90us供DA18B20采样*/DQ=1; /*释放DQ总线*/_nop_();_nop_();EA=1;}/*********************************************************** 写一字节数据子程序***********************************************************/ void write_byte(unsigned char val){unsigned char i;unsigned char temp;EA=0; /*关中断*/TR0=0;for(i=0;i<8;i++) /*写一字节数据,一次写一位*/{temp=val>>i; /*移位操作,将本次要写的位移到最低位*/temp=temp&1;write_bit(temp); /*向总线写该位*/}delay(7); /*延时120us后*/// TR0=1;EA=1; /*开中断*/}/*********************************************************** 读一位数据子程序***********************************************************/ unsigned char read_bit(){unsigned char i,value_bit;EA=0;DQ=0; /*拉低DQ,开始读时序*/_nop_();_nop_();DQ=1; /*释放总线*/for(i=0;i<2;i++){}value_bit=DQ;EA=1;return(value_bit);}/*********************************************************** 读一字节数据子程序***********************************************************/ unsigned char read_byte(){unsigned char i,value=0;EA=0;for(i=0;i<8;i++){if(read_bit()) /*读一字节数据,一个时序中读一次,并作移位处理*/ value|=0x01<<i;delay(4); /*延时80us以完成此次都时序,之后再读下一数据*/}EA=1;return(value);}/***********************************************************复位子程序***********************************************************/ unsigned char reset(){unsigned char presence;EA=0;DQ=0; /*拉低DQ总线开始复位*/delay(30); /*保持低电平480us*/DQ=1; /*释放总线*/delay(3);presence=DQ; /*获取应答信号*/delay(28); /*延时以完成整个时序*/EA=1;return(presence); /*返回应答信号,有芯片应答返回0,无芯片则返回1*/ }/***********************************************************获取温度子程序***********************************************************/void get_temper(){unsigned char i,j;do{i=reset(); /*复位*/}while(i!=0); /*1为无反馈信号*/ i=0xcc; /*发送设备定位命令*/ write_byte(i);i=0x44; /*发送开始转换命令*/ write_byte(i);delay(180); /*延时*/do{i=reset(); /*复位*/}while(i!=0);i=0xcc; /*设备定位*/write_byte(i);i=0xbe; /*读出缓冲区内容*/write_byte(i);j=read_byte();i=read_byte();i=(i<<4)&0x7f;s=(unsigned int)(j&0x0f);s=(s*100)/16;j=j>>4;temper=i|j; /*获取的温度放在temper中*/}/*================================================================= ===================================Initialize PID Structure=================================================================== ==================================*/void PIDInit (struct PID *pp){memset ( pp,0,sizeof(struct PID));}/*================================================================= ===================================PID计算部分=================================================================== ==================================*/unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint ){unsigned int 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); // 微分项}/***********************************************************温度比较处理子程序***********************************************************/ compare_temper(){unsigned char i;if(set_temper>temper){if(set_temper-temper>1){high_time=100;low_time=0;}else{for(i=0;i<10;i++){ get_temper();rin = s; // Read Inputrout = PIDCalc ( &spid,rin ); // Perform PID Interation}if (high_time<=100)high_time=(unsigned char)(rout/800); elsehigh_time=100;low_time= (100-high_time);}}else if(set_temper<=temper){if(temper-set_temper>0){high_time=0;low_time=100;}else{for(i=0;i<10;i++){ get_temper();rin = s; // Read Inputrout = PIDCalc ( &spid,rin ); // Perform PID Interation }if (high_time<100)high_time=(unsigned char)(rout/10000);elsehigh_time=0;low_time= (100-high_time);}}// else// {}}/***************************************************** T0中断服务子程序,用于控制电平的翻转 ,40us*100=4ms周期******************************************************/ void serve_T0() interrupt 1 using 1{if(++count<=(high_time))output=1;else if(count<=100){output=0;}elsecount=0;TH0=0x2f;TL0=0xe0;}/***************************************************** 串行口中断服务程序,用于上位机通讯******************************************************/void serve_sio() interrupt 4 using 2 {/* EA=0;RI=0;i=SBUF;if(i==2){while(RI==0){}RI=0;set_temper=SBUF;SBUF=0x02;while(TI==0){}TI=0;}else if(i==3){TI=0;SBUF=temper;while(TI==0){}TI=0;}EA=1; */}void disp_1(unsigned char disp_num1[6]) {unsigned char n,a,m;for(n=0;n<6;n++){// k=disp_num1[n];for(a=0;a<8;a++){clk=0;m=(disp_num1[n]&1);disp_num1[n]=disp_num1[n]>>1;if(m==1)data1=1;elsedata1=0;_nop_();clk=1;_nop_();}}}/***************************************************** 显示子程序功能:将占空比温度转化为单个字符,显示占空比和测得到的温度******************************************************/ void display(){unsigned char codenumber[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6};unsigned char disp_num[6];unsigned int k,k1;k=high_time;k=k%1000;k1=k/100;if(k1==0)disp_num[0]=0;elsedisp_num[0]=0x60;k=k%100;disp_num[1]=number[k/10];disp_num[2]=number[k%10];k=temper;k=k%100;disp_num[3]=number[k/10];disp_num[4]=number[k%10]+1;disp_num[5]=number[s/10];disp_1(disp_num);}/*********************************************************** 主程序***********************************************************/ main(){unsigned char z;unsigned char a,b,flag_2=1,count1=0;unsigned char phil[]={2,0xce,0x6e,0x60,0x1c,2};TMOD=0x21;TH0=0x2f;TL0=0x40;SCON=0x50;PCON=0x00;TH1=0xfd;TL1=0xfd;PS=1;EA=1;EX1=0;ET0=1;ES=1;TR0=1;TR1=1;high_time=50;low_time=50;PIDInit ( &spid ); // Initialize Structure spid.Proportion = 10; // Set PID Coefficients spid.Integral = 8;spid.Derivative =6;spid.SetPoint = 100; // Set PID Setpoint while(1){if(plus==0){EA=0;for(a=0;a<5;a++)for(b=0;b<102;b++){} if(plus==0){set_temper++;flag=0;}}else if(subs==0) {for(a=0;a<5;a++)for(b=0;a<102;b++){} if(subs==0){set_temper--;flag=0;}}else if(stop==0) {for(a=0;a<5;a++)for(b=0;b<102;b++){} if(stop==0){flag=0;break;}EA=1;}get_temper();b=temper;if(flag_2==1)a=b;if((abs(a-b))>5) temper=a;elsetemper=b;a=temper;flag_2=0;if(++count1>30) {display();count1=0;}compare_temper(); }TR0=0;z=1;while(1){EA=0;if(stop==0){for(a=0;a<5;a++)for(b=0;b<102;b++){} if(stop==0)disp_1(phil);// break;}EA=1;}}//DS18b20 子程序#include <REG52.H>sbit DQ=P2^1; //定义端口typedef unsigned char byte;typedef unsigned int word;//延时void delay(word useconds){for(;useconds>0;useconds--);}//复位byte ow_reset(void){byte presence;DQ=0; //DQ低电平delay(29); //480us DQ=1; //DQ高电平delay(3); //等待presence=DQ; //presence信号delay(25);return(presence);} //0允许,1禁止//从1-wire 总线上读取一个字节byte read_byte(viod){byte i;byte value=0;for (i=8;i>0;i--){value>>=1;DQ=0;DQ=1;delay(1);if(DQ)value|=0x80;delay(6);}return(value);}//向1-wire总线上写一个字节void write_byte(char val){byte i;for (i=8;i>0;i--) //一次写一个字节{DQ=0;DQ=val&0x01;delay(5);DQ=1;val=val/2;}delay(5);}//读取温度char Read_Temperature(void) {union{byte c[2];int x;}temp;ow_reset();write_byte(0xcc);write_byte(0xBE);temp.c[1]=read_byte(); temp.c[0]=read_byte();ow_reset();write_byte(0xCC);write_byte(0x44);return temp.x/2;}参考资料:你把这两个程序组合就可以了图1 模拟PID 控制系统原理图PID 控制器的控制规律可以描述为:(1)比例(P)控制能迅速反应误差,从而减小稳态误差。

pid算法温度控制c语言程序

pid算法温度控制c语言程序

pid算法温度控制c语言程序PID算法是一种常用的温度控制算法,广泛应用于各种温度控制系统中。

在C语言中,我们可以通过编写程序来实现PID算法的温度控制功能。

我们需要了解PID算法的基本原理。

PID算法是通过对系统的反馈信号进行不断调整,使得系统的输出达到期望值。

PID算法由三个部分组成:比例控制、积分控制和微分控制。

比例控制根据反馈信号与期望值的差异来调整输出;积分控制根据反馈信号与期望值的累积差异来调整输出;微分控制根据反馈信号的变化率来调整输出。

在C语言中,我们可以使用变量来表示系统的输入、输出和期望值。

以下是一个简单的示例代码:```c#include <stdio.h>// 定义PID参数float Kp = 1.0; // 比例系数float Ki = 0.5; // 积分系数float Kd = 0.2; // 微分系数// 定义系统变量float setpoint = 25.0; // 期望值float input = 0.0; // 输入值float output = 0.0; // 输出值// 定义误差变量float error = 0.0; // 当前误差float last_error = 0.0; // 上一次误差float integral = 0.0; // 累积误差// PID算法函数float pid_algorithm(float setpoint, float input) {// 计算误差error = setpoint - input;// 计算比例控制float proportional = Kp * error;// 计算积分控制integral += error;float integral_control = Ki * integral;// 计算微分控制float derivative = Kd * (error - last_error); // 计算输出output = proportional + integral_control + derivative;// 更新误差last_error = error;return output;}int main(){// 模拟温度传感器的输入input = 23.5;// 调用PID算法函数output = pid_algorithm(setpoint, input);// 打印输出结果printf("Output: %.2f\n", output);return 0;}```在上述代码中,我们首先定义了PID算法的参数和系统变量。

C语言编写PID温度控制程序

(* init program *)PIDpara.enable = 1 ;使能端PIDpara.enter = 1 ;当enter为1时,检查参数并转换为内部显示。

;当enter为0时,忽略输入参数的改变并存储计算时间。

PIDpara.Y_max = 32767 ;PID输出最大值(0~~32767)PIDpara.Y_min = 0 ;PID输出最小值(0~~32767)PIDpara.dY_max = 10.0 ;输出最大容许变化量,操作变量斜坡最大值。

为0时ramp不起作用,不需计算时间PIDpara.Kp = 1.0 ;比例PIDpara.Tn = 10.0 ;积分(越小作用越大),为0时第I part和jolt-free切换不起作用且不需要任何计算时间。

= 1 ;微分PIDpara.Tf = 1 ;微分滤波时间。

若Tv不为0必须输入(初值为Tv/10),不应少于(1.4*任务的扫描时间).PIDpara.Kw = 1 ;比例项衰减系数。

Kw为1时设定值不变进行比例项计算,为小于1时,设定值乘Kw后进行比例项计算(此项不能为零)PIDpara.Kfbk = 1 ;抗积分饱和,终结阻尼值。

Kfbk为0时终结保护无效,不需要计算时间PIDpara.fbk_mode = LCPID_FBK_MODE_INTERN ;操作变量的反馈模式:内部模式(一般为内部模式)PIDpara.d_mode = LCPID_D_MODE_E ;微分模式:对偏差值进行微分计算(标准PID控制);X模式:对实际值进行微分计算(一般选次方式)PIDpara.calc_mode= LCPID_CALC_MODE_EXACT ;计算模式:精确(所有计算为双精度浮点型, 如无舍入错误和CPU计算次数过长)(一般选次方式)PIDpara FUB LCPIDpara() ;调用PID参数功能块循环程序中程序如下,此程序只对P、I、D三个参数由变量进行输值,变量可在pid程序运行中实时修改,如果大家还需要某些参数实时修改,方法相同:(* cyclic program *)PIDpara.enable = PIDpara.enablePIDpara FUB LCPIDpara() = D_Ctrl ;积分(越小作用越大),为0时第I part和jolt-free 切换不起作用且不需要任何计算时间。

温度控制的PID算法与C程序实现

温度控制的PID算法与C程序实现PID (Proportional-Integral-Derivative) 是一种经典的反馈控制算法,被广泛应用于温度控制中。

在温度控制中,PID算法可以根据实际温度与设定温度之间的差异来调整控制器的输出,以达到稳定的温度控制。

下面将介绍PID算法的原理及其在C程序中的实现。

PID算法是通过对三个控制参数的不同组合调整,来实现对控制系统的精确控制。

这三个参数分别是比例项(P),积分项(I)和微分项(D)。

比例项(P)是根据实际温度与设定温度的差异计算出来的,并且与这个差异成比例。

比例项主要用于对系统的快速响应进行调整。

如果比例项过大,可能会导致系统产生震荡,如果比例项过小,则可能导致控制系统响应迟缓。

积分项(I)用于校正持续的误差,通过对误差的积分来进行控制系统的调整。

积分项主要用于对系统的稳定性进行调整。

如果积分项过大,可能会导致系统产生超调和振荡,如果积分项过小,则可能导致系统无法快速地消除误差。

微分项(D)用于预测系统未来变化的趋势,并根据这个趋势来进行控制系统的调整。

微分项主要用于对系统的响应速度进行调整。

如果微分项过大,可能会导致系统产生过度的抖动,如果微分项过小,则可能导致系统响应迟缓。

PID算法的输出是三个控制参数的加权和,即 control = P * error + I * integral + D * derivative。

其中,error为实际温度与设定温度的差异,integral为误差的累积和,derivative为误差的变化率。

下面是一个使用PID算法实现温度控制的C程序的示例:```c#include <stdio.h>//PID参数float Kp = 0.5;float Ki = 0.2;float Kd = 0.1;//温度设定值float setpoint = 50.0;//初始化float errorSum = 0;float lastError = 0;//计算PID控制量float calculateOutput(float currentTemperature) float error = setpoint - currentTemperature; errorSum += error;//计算PID控制量float proportional = Kp * error;float integral = Ki * errorSum;float derivative = Kd * (error - lastError);float output = proportional + integral + derivative; lastError = error;return output;int mai//模拟当前温度float currentTemperature = 40.0;//模拟控制循环while (1)//获取温度传感器读数// float currentTemperature = readTemperature(;//计算PID控制量float controlOutput = calculateOutput(currentTemperature); //执行控制动作,例如根据控制量控制加热器或冷却器// executeControlAction(controlOutput);//模拟温度变化currentTemperature += 0.5;//输出当前温度和控制量printf("Current temperature: %.2f, Control output: %.2f\n", currentTemperature, controlOutput);}return 0;```上述C程序中,首先定义了PID参数Kp、Ki和Kd,以及温度设定值setpoint。

PID控制算法的C语言实现(完整版)

PID控制算法的C语言实现一 PID算法原理最近两天在考虑一般控制算法的C语言实现问题,发现网络上尚没有一套完整的比较体系的讲解。

于是总结了几天,整理一套思路分享给大家。

在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法,如果能够熟练掌握PID算法的设计与实现过程,对于一般的研发人员来讲,应该是足够应对一般研发问题了,而难能可贵的是,在我所接触的控制算法当中,PID控制算法又是最简单,最能体现反馈思想的控制算法,可谓经典中的经典。

经典的未必是复杂的,经典的东西常常是简单的,而且是最简单的,想想牛顿的力学三大定律吧,想想爱因斯坦的质能方程吧,何等的简单!简单的不是原始的,简单的也不是落后的,简单到了美的程度。

先看看PID算法的一般形式:PID的流程简单到了不能再简单的程度,通过误差信号控制被控量,而控制器本身就是比例、积分、微分三个环节的加和。

这里我们规定(在t时刻):1.输入量为rin(t);2.输出量为rout(t);3.偏差量为err(t)=rin(t)-rout(t);pid的控制规律为理解一下这个公式,主要从下面几个问题着手,为了便于理解,把控制环境具体一下:1.规定这个流程是用来为直流电机调速的;2.输入量rin(t)为电机转速预定值;3.输出量rout(t)为电机转速实际值;4.执行器为直流电机;5.传感器为光电码盘,假设码盘为10线;6.直流电机采用PWM调速转速用单位转/min表示;不难看出以下结论:1.输入量rin(t)为电机转速预定值(转/min);2. 输出量rout(t)为电机转速实际值(转/min);3.偏差量为预定值和实际值之差(转/min);那么以下几个问题需要弄清楚:1.通过PID环节之后的U(t)是什么值呢?2.控制执行器(直流电机)转动转速应该为电压值(也就是PWM占空比)。

3.那么U(t)与PWM之间存在怎样的联系呢?/user1/3407/archives/2006/33541.html(见附录1)这篇文章上给出了一种方法,即,每个电压对应一个转速,电压和转速之间呈现线性关系。

PID控制算法的C语言实现(完整版)

PID控制算法的C语言实现(完整版) 嘿,伙计们!今天我们要聊聊一个非常实用的技能——PID控制算法。

PID是英文Proportional-Integral-Derivative的缩写,翻译过来就是“比例积分微分”。

这个算法在我们的日常生活中随处可见,比如空调、洗衣机等家电的温度调节,还有汽车的速度控制等等。

那么,这个看似高深莫测的算法到底是怎么实现的呢?别急,让我们一起揭开它的神秘面纱吧!我们来了解一下PID控制算法的基本概念。

PID控制算法主要包括三个部分:比例(P)、积分(I)和微分(D)。

这三个部分分别对误差进行处理,然后将处理后的结果相加,得到控制输出。

具体来说,比例部分主要负责消除误差的瞬时成分;积分部分主要负责消除误差的稳态成分;微分部分则负责预测误差的未来变化趋势。

通过这三个部分的综合作用,我们可以实现对系统的精确控制。

接下来,我们来看一下PID控制算法的具体实现。

我们需要定义一些变量和参数,比如比例系数Kp、积分系数Ki、微分系数Kd以及采样时间Ts等。

这些参数的选择对于算法的效果至关重要,需要根据实际应用场景进行调整。

然后,我们需要不断地对系统进行采样,计算出当前的状态值和期望值之间的误差e(t)。

误差e(t)可以通过以下公式计算得到:e(t) = 期望值实际值有了误差e(t),我们就可以开始计算PID控制器的输出了。

根据之前的介绍,PID控制器的输出由比例、积分和微分三个部分组成。

具体计算过程如下:1. 比例部分:计算比例系数Kp乘以误差e(t),得到比例输出u(t);2. 积分部分:计算积分系数Ki乘以误差e(t)的时间积分,得到积分输出u(t);3. 微分部分:计算微分系数Kd乘以误差e(t)的时间微分,得到微分输出u(t)。

将比例、积分和微分三个部分的输出相加,得到最终的控制输出u(t)。

这样,我们就完成了一次PID控制算法的计算过程。

这只是理论上的实现方法,实际上还需要考虑一些其他因素,比如控制器的稳定性、响应速度等。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

温度控制与PID算法温度控制与PID算法j较为复杂,下面结合实际浅显易懂的阐述一下PID控制理论,将温度控制及PID算法作一个简单的描述。

1.温度控制的框图这是一个典型的闭环控制系统,用于控制加热温区的温度(PV)保持在恒定的温度设定值(SV)。

系统通过温度采集单元反馈回来的实时温度信号(PV)获取偏差值(EV),偏差值经过PID调节器运算输出,控制发热管的发热功率,以克服偏差,促使偏差趋近于零。

例如,当某一时刻炉内过PCB板较多,带走的热量较多时,即导致温区温度下降,这时,通过反馈的调节作用,将使温度迅速回升。

其调节过程如下:温度控制的功率输出采用脉宽调制的方法。

固态继电器SSR的输出端为脉宽可调的电压U OUT 。

当SSR的触发角触发时,电源电压U AN通过SSR的输出端加到发热管的两端;当SSR的触发角没有触发信号时,SSR关断。

因此,发热管两端的平均电压为U d=(t/T)* U AN=K* U AN其中K=t/T,为一个周期T中,SSR触发导通的比率,称为负载电压系数或是占空比,K 的变化率在0-1之间。

一般是周期T固定不便,调节t, 当t在0-T的范围内变化时,发热管的电压即在0-U AN之间变化,这种调节方法称为定频调宽法。

下面将要描述的PID 调节器的算式在这里的实质即是运算求出一个实时变化的,能够保证加热温区在外界干扰的情况下仍能保持温度在一个较小的范围内变化的合理的负载电压系数K。

2.温度控制的两个阶段温度控制系统是一个惯性较大的系统,也就是说,当给温区开始加热之后,并不能立即观察得到温区温度的明显上升;同样的,当关闭加热之后,温区的温度仍然有一定程度的上升。

另外,热电偶对温度的检测,与实际的温区温度相比较,也存在一定的滞后效应。

这给温度的控制带来了困难。

因此,如果在温度检测值(PV)到达设定值时才关断输出,可能因温度的滞后效应而长时间超出设定值,需要较长时间才能回到设定值;如果在温度检测值(PV)未到设定值时即关断输出,则可能因关断较早而导致温度难以达到设定值。

为了合理地处理系统响应速度(即加热速度)与系统稳定性之间地矛盾,我们把温度控制分为两个阶段。

(1)PID调节前阶段在这个阶段,因为温区的温度距离设定值还很远,为了加快加热速度,SSR与发热管处于满负荷输出状态,只有当温度上升速度超过控制参数“加速速率”,SSR 才关闭输出。

“加速速率”描述的是温度在单位时间的跨度,反映的是温度升降的快慢,如上图所示。

用“加速速率”限制温升过快,是为了降低温度进入PID调节区的惯性,避免首次到达温度设定值(SV)时超调过大。

在这个阶段,要么占空比K=0, SSR关闭;要么占空比K=100%, SSR全速输出。

PID调节器不起作用,仅由“加速速率”控制温升快慢。

(2)PID调节阶段在这个阶段,PID调节器调节输出,根据偏差值计算占空比(0-100%),保证偏差(EV)趋近于零,即使系统受到外部干扰时,也能使系统回到平衡状态。

3.PID算法PID控制的原理是基于下面的算式:输出M(t)是比例项,积分项和微分项的函数。

其中:M(t) PID回路的输出,是时间的函数Kc PID回路的比例增益e PID回路的偏差(设定值(SV)与过程变量(PV)之差)Minitial PID回路的静态输出值为了能让数字计算机处理这个算式,连续算式必须离散化为周期采样偏差算式,才能用来计算输出值。

数字计算机处理的算式如下:从这个公式可以看出,积分项是从第一个采样周期到当前采样周期所有误差项的函数,微分项是当前采样和前一次采样的函数,比例项仅是当前采样的函数。

在数字计算机中,不保存所有的误差项,其实也不必要。

由于计算机从第一次采样开始,每有一个过程采样值必须计算一次输出值,只需要保存前一次过程值(PVn-1)和积分项前值。

利用计算机处理的重复性,可以将以上算式变换为:其中:Mn 在第n 采样时刻,PID回路的输出计算值SV PID 回路设定值PVn 在第n 采样时刻的过程变量值PVn-1 在第n-1 采样时刻的过程变量值MX 积分前项值Mintial PID回路的静态输出值Kc PID回路的比例增益KI 积分项的比例常数KI=Kc * Ts / TiTs是离散化时的采样时间间隔Ti是积分时间参数;KD 微分项的比例常数KD=Kc * Td / TsTs是离散化时的采样时间间隔Td是微分时间参数;从上面PID的算式,可以分析三个基本参数Kc, KI, KD在实际控制中的作用:(1)比例调节作用:比例项按比例反应系统的偏差,系统一旦出现了偏差,比例调节立即产生调节作用用以减少偏差。

比例作用大,可以加快调节,减少偏差。

但是过大的比例调节,使系统的稳定性下降,甚至造成系统的不稳定。

(2)积分调节作用:积分项消除系统的稳态误差,提高无差度。

只要有偏差,积分就进行,直到无偏差时,积分运算才停止,积分调节项输出一常数值。

积分作用的强弱取决于积分时间常数Ti,Ti越小,积分作用越强。

积分控制可提高系统的无差度,但积分项输出响应缓慢,使得系统调节时间增长。

(3)微分调节作用:微分项反映系统过程变量的变化率((PVn-1-PVn)/ Ts),具有预见性,能预见变化的趋势,因此,能产生超前的调节作用,在偏差还没有形成之前,已被微分调节作用消除。

因此,可以改善系统的动态性能。

在微分时间参数Td选择合适的情况下,可以减少超调,减少调节时间。

微分调节对干扰有放大效果,过强的微分调节,对系统抗干扰不利。

此外,微分项反映的是过程变量的变化率,而当过程变量没有变化时,微分调节输出为零。

微分调节不能单独使用,需要与另外两种调节规律相结合,组成PD或PID调节器。

以上面的推导,C程序如下/*pid算法C源程序,还有实现pid自动调整。

51用于控制温度26-100摄氏度。

TIME:2011-07-29 20:15:07*/#include <stdlib.h>#include "global_varible.h"/***************************************************************************** 模块名: PID* 描述: PID调节子程序* 采用PID-PD算法。

在偏差绝对值大于△e时,用PD算法,以改善动态品质。

* 当偏差绝对值小于△e时,用PID算法,提高稳定精度。

* PIDout=kp*e(t)+ki*[e(t)+e(t-1)+...+e(1)]+kd*[e(t)-e(t-1)]*===================================================================== =======* 入口: 无* 出口: 无* 改变: PID_T_Run=加热时间控制*****************************************************************************/ void PID_Math(void){signed long ee1; //偏差一阶//signed long ee2; //偏差二阶signed long d_out; //积分输出if(!Flag_PID_T_OK)return;Flag_PID_T_OK = 0;Temp_Set = 3700; //温度控制设定值37.00度PID_e0 = Temp_Set - Temp_Now; //本次偏差ee1 = PID_e0 - PID_e1; //计算一阶偏差//ee2 = PID_e0-2*PID_e1+PID_e2; //计算二阶偏差//一阶偏差的限制范围if(ee1 > 500) ee1 = 500;if(ee1 < -500) ee1 = -500;PID_e_SUM += PID_e0; //偏差之和//积分最多累计的温差if(PID_e_SUM > 200) PID_e_SUM = 200;if(PID_e_SUM < -200) PID_e_SUM = -200;PID_Out = PID_kp * PID_e0 + PID_kd * ee1; //计算PID比例和微分输出if(abs(PID_e0) < 200) //如果温度相差小于1.5度则计入PID积分输出{if(abs(PID_e0) > 100){ //如果温度相差大于1度时积分累计限制if(PID_e_SUM > 100) PID_e_SUM = 100;if(PID_e_SUM < -100) PID_e_SUM = -100;}d_out = PID_ki * PID_e_SUM; //积分输出if(PID_e0 < -5){ //当前温度高于设定温度0.5度时积分累计限制if(PID_e_SUM > 150) PID_e_SUM = 150;if(PID_e_SUM > 0) d_out >>= 1; //当前温度高于设定温度0.5度时削弱积分正输出}PID_Out += d_out; //PID比例,积分和微分输出}elsePID_e_SUM=0;PID_Out /= 100; //恢复被PID_Out系数放大的倍数if(PID_Out > 200) PID_Out=200;if(PID_Out<0) PID_Out=0;if(PID_e0 > 300) PID_Out=200; //当前温度比设定温度低3度则全速加热if(PID_e0 < -20) PID_Out=0; //当前温度高于设定温度0.2度则关闭加热Hot_T_Run = PID_Out; //加热时间控制输出// PID_e2 = PID_e1; //保存上次偏差PID_e1 = PID_e0; //保存当前偏差}。

相关文档
最新文档