#include #include struct _pid { int pv; /*integer that contains the process value*/ int sp; /*integer that contains the set point*/ float integral; float pgain; float igain; float dgain; int deadband; int last_error; }; struct _pid warm,*pid; int process_point, set_point,dead_band; float p_gain, i_gain, d_gain, integral_val,new_integ;; /*------------------------------------------------------------------------ pid_init DESCRIPTION This function initializes the pointers in the _pid structure to the process variable and the setpoint. *pv and *sp are integer pointers. ------------------------------------------------------------------------*/ void pid_init(struct _pid *warm, int process_point, int set_point) { struct _pid *pid; pid = warm; pid->pv = process_point; pid->sp = set_point; } /*------------------------------------------------------------------------ pid_tune DESCRIPTION Sets the proportional gain (p_gain), integral gain (i_gain), derivitive gain (d_gain), and the dead band (dead_band) of a pid control structure _pid. ------------------------------------------------------------------------*/ void pid_tune(struct _pid *pid, float p_gain, float i_gain, float d_gain, int dead_band) { pid->pgain = p_gain; pid->igain = i_gain; pid->dgain = d_gain; pid->deadband = dead_band; pid->integral= integral_val; pid->last_error=0; } /*------------------------------------------------------------------------ pid_setinteg DESCRIPTION Set a new value for the integral term of the pid equation. This is useful for setting the initial output of the pid controller at start up. ------------------------------------------------------------------------*/ void pid_setinteg(struct _pid *pid,float new_integ) { pid->integral = new_integ; pid->last_error = 0; } /*------------------------------------------------------------------------ pid_bumpless DESCRIPTION Bumpless transfer algorithim. When suddenly changing setpoints, or when restarting the PID equation after an extended pause, the derivative of the equation can cause a bump in the controller output. This function will help smooth out that bump. The process value in *pv should be the updated just before this function is used. ------------------------------------------------------------------------*/ void pid_bumpless(struct _pid *pid) { pid->last_error = (pid->sp)-(pid->pv); } /*------------------------------------------------------------------------ pid_calc DESCRIPTION Performs PID calculations for the _pid structure *a. This function uses the positional form of the pid equation, and incorporates an integral windup prevention algorithim. Rectangular integration is used, so this function must be repeated on a consistent time basis for accurate control. RETURN VALUE The new output value for the pid loop. USAGE #include \"control.h\"*/ float pid_calc(struct _pid *pid) { int err; float pterm, dterm, result, ferror; err = (pid->sp) - (pid->pv); if (abs(err) > pid->deadband) { ferror = (float) err; /*do integer to float conversion only once*/ pterm = pid->pgain * ferror; if (pterm > 100 || pterm < -100) { pid->integral = 0.0; } else { pid->integral += pid->igain * ferror; if (pid->integral > 100.0) { pid->integral = 100.0; } else if (pid->integral < 0.0) pid->integral = 0.0; } dterm = ((float)(err - pid->last_error)) * pid->dgain; result = pterm + pid->integral + dterm; } else result = pid->integral; pid->last_error = err; return (result); } void main(void) { float display_value; int count=0; pid = &warm; // printf(\"Enter the values of Process point, Set point, P gain, I gain, D gain \\n\"); // scanf(\"%d%d%f%f%f\&process_point, &set_point, &p_gain, &i_gain, &d_gain); process_point = 30; set_point = 40; p_gain = (float)(5.2); i_gain = (float)(0.77); d_gain = (float)(0.18); dead_band = 2; integral_val =(float)(0.01); printf(\"The values of Process point, Set point, P gain, I gain, D gain \\n\"); printf(\" %6d %6d %4f %4f %4f\\n\process_point, set_point, p_gain, i_gain, d_gain); printf(\"Enter the values of Process point\\n\"); while(count<=20) { scanf(\"%d\ pid_init(&warm, process_point, set_point); pid_tune(&warm, p_gain,i_gain,d_gain,dead_band); pid_setinteg(&warm,0.0); //pid_setinteg(&warm,30.0); //Get input value for process point pid_bumpless(&warm); // how to display output display_value = pid_calc(&warm); printf(\"%f\\n\ //printf(\"\\n%f%f%f%f\ count++; } } . PID调试步骤 没有一种控制算法比PID调节规律更有效、更方便的了。现在一些时髦点的调节器基本源自PID。甚至可以这样说:PID调节器是其它控制调节算法的吗。 为什么PID应用如此广泛、又长久不衰? 因为PID解决了自动控制理论所要解决的最基本问题,既系统的稳定性、快速性和准确性。调节PID的参数,可实现在系统稳定的前提下,兼顾系统的带载能力和抗扰能力,同时,在PID调节器中引入积分项,系统增加了一个零积点,使之成为一阶或一阶以上的系统,这样系统阶跃响应的稳态误差就为零。 由于自动控制系统被控对象的千差万别,PID的参数也必须随之变化,以满足系统的性能要求。这就给使用者带来相当的麻烦,特别是对初学者。下面简单介绍一下调试PID参数的一般步骤: 1.负反馈 自动控制理论也被称为负反馈控制理论。首先检查系统接线,确定系统的反馈为负反馈。例如电机调速系统,输入信号为正,要求电机正转时,反馈信号也为正(PID算法时,误差=输入-反馈),同时电机转速越高,反馈信号越大。其余系统同此方法。 2.PID调试一般原则 a.在输出不振荡时,增大比例增益P。 b.在输出不振荡时,减小积分时间常数Ti。 c.在输出不振荡时,增大微分时间常数Td。 3.一般步骤 a.确定比例增益P 确定比例增益P 时,首先去掉PID的积分项和微分项,一般是令Ti=0、Td=0(具体见PID的参数设定说明),使PID为纯比例调节。输入设定为系统允许的最大值的60%~70%,由0逐渐加大比例增益P,直至系统出现振荡;再反过来,从此时的比例增益P逐渐减小,直至系统振荡消失,记录此时的比例增益P,设定PID的比例增益P为当前值的60%~70%。比例增益P调试完成。 b.确定积分时间常数Ti 比例增益P确定后,设定一个较大的积分时间常数Ti的初值,然后逐渐减小Ti,直至系统出现振荡,之后在反过来,逐渐加大Ti,直至系统振荡消失。记录此时的Ti,设定PID 的积分时间常数Ti为当前值的150%~180%。积分时间常数Ti调试完成。 c.确定积分时间常数Td 积分时间常数Td一般不用设定,为0即可。若要设定,与确定 P和Ti的方法相同,取不振荡时的30%。 d.系统空载、带载联调,再对PID参数进行微调,直至满足要求。 2.PID控制简介 目前工业自动化水平已成为衡量各行各业现代化水平的一个重要标志。同时,控制理论的发展也经历了古典控制理论、现代控制理论和智能控制理论三个阶段。智能控制的典型实例是模糊全自动洗衣机等。自动控制系统可分为开环控制系统和闭环控制系统。一个控制系统包括控制器﹑传感器﹑变送器﹑执行机构﹑输入输出接口。控制器的输出经过输出接口﹑执行机构﹐加到被控系统上﹔控制系统的被控量﹐经过传感器﹐变送器﹐通过输入接口送到控制器。不同的控制系统﹐其传感器﹑变送器﹑执行机构是不一样的。比如压力控制系统要采用压力传感器。电加热控制系统的传感器是温度传感器。目前,PID控制及其控制器或智能PID控制器(仪表)已经很多,产品已在工程实际中得到了广泛的应用,有各种各样的PID控制器产品,各大公司均开发了具有PID参数自整定功能的智能调节器(intelligent regulator),其中PID控制器参数的自动调整是通过智能化调整或自校正、自适应算法来实现。有利用PID控制实现的压力、温度、流量、液位控制器,能实现PID控制功能的可编程控制器(PLC),还有可实现PID控制的PC系统等等。 可编程控制器(PLC) 是利用其闭环控制模块来实现PID控制,而可编程控制器(PLC)可以直接与ControlNet相连,如Rockwell的PLC-5等。还有可以实现PID控制功能的控制器,如Rockwell 的Logix 产品系列,它可以直接与ControlNet相连,利用网络来实现其远程控制功能。 因篇幅问题不能全部显示,请点此查看更多更全内容