PID实验报告.docx
《PID实验报告.docx》由会员分享,可在线阅读,更多相关《PID实验报告.docx(19页珍藏版)》请在冰豆网上搜索。
![PID实验报告.docx](https://file1.bdocx.com/fileroot1/2023-2/7/d7150ab9-100f-484f-8b7c-80ca33135bea/d7150ab9-100f-484f-8b7c-80ca33135bea1.gif)
PID实验报告
1、实习内容及其要求
通过温度或转速的设定值和反馈值,计算其偏差,并使用PID控制算法输出控制信号,整定PID参数,使被控的温度或转速达到设定值。
具体实训内容包括AC6611过程卡的接线和测试、数据采集程序设计、PID算法程序设计、控制输出程序设计、人机界面程序设计、PID参数整定、实训报告。
目的:
通过实训,让学生了解计算机控制系统的基本组成,提出计算机控制系统的设计思路,初步学会计算机控制系统软硬件设计及调试的方法,具备技术实现能力;基本上能够处理实践过程中出现的问题并提出解决办法,进一步提高学生的计算机应用水平。
要求:
完成一个温度或转速单回路控制系统的设计和调试过程。
2、AC6611多功能过程通道卡
2.1功能特点与技术指标
功能:
AC6611是一款廉价通用A/D、D/A板,AD工作在查询方式,采用PCI总线支持即插即用、无需地址跳线。
AC6611具有16路单端模拟输入、32路开关量(16路输入及16路输出)、一路12位D/A。
AC6611采用大规模可编程门阵列设计。
A/D转换指标:
A/D转换器:
120KHZ12位A/DADS7816;保持器:
A/D芯片内置采样保持器;
工作方式:
软件查询;
通道数:
16路单端输入;
输入阻抗:
1MΩ,
最大输入耐压电压:
<+12V/-5.5V;
瞬时输入耐压:
-25V-+30V;
双极性输入范围:
5V;
单极性输入幅度:
5伏、10伏;
连接器:
DB25(孔式)。
D/A转换指标:
通道数:
1路
分辨率:
12位
精度:
0.2%
最大输出电流:
5毫安。
输出零点误差:
<±10mV。
输出范围:
10伏、±10伏,使用跳线器进行选择。
输出建立时间小于:
50微秒;
连接器:
DB25(孔)
开关量输入/输出指标:
输入通道数:
16路(2个8位)
输出通道数:
16路(2个8位)
电平:
TTL电平(兼容3伏逻辑)
连接器:
40脚扁平电缆插座
开关量输出复位后输出:
低电平“0”。
输出高电压>2.5V,低电压<0.5V
最大输出电流:
8mA
输入电流:
<0.1mA
输入高电压门限:
>2V,低电压:
<0.8V。
输入耐压:
高电平:
8V,低电平:
-0.4V。
2.2应用方法和步骤
1)关闭计算机的电源;
2)将AC6611板卡插入PCI槽中;
3)打开计算机电源,启动Windows2000/XP;
4)Windows2000/XP将会显示找到新硬件,可按找到新硬件向导进行下一步;
5)选择搜索适用与我的设备的驱动程序(推荐),下一步;
6)选择驱动所在目录,进行安装(\ac6611\driver\);
7)按找到新硬件向导的提示进行下一步;
8)Windows2000/XP将显示完成添加/删除硬件向导,单击完成即可完成安装过程。
在完成上述操作后,打开AC6611的静态测试程序,在通道选择处选择你所需要的起始和停止通道,输入选择处选择0到10伏的电压,输出选择处也选择0到10伏电压。
起操作界面如下:
在静态测试完成后,就可以编程对AC6611进行测试,其步骤如下:
1)加载DLL;
2)调用AC6611_CreateDevice();
3)调用AC6611_AD();
4)调用AC6611_DA();
5)调用AC6611_DI();
6)调用AC6611_DO();
7)AC6611_CloseDeivce()。
3、方案设计
3.1加热器的过程特性
在本次实验中,使用的加热器其加热上限是100℃。
在加热的过程中,通过计算机的控制,其温度不断地逼近设定值,并在允许的偏差范围内有较小的波动。
其在工作的时候是通过外在的控制器给予它一个模拟的信号,来驱动加热器工作,在此同时它也会向控制器反馈它此时的温度状态。
3.2加热器温度控制系统的实现方案
对于加热器温度控制系统,在硬件上我们采用的是AC6611板卡、AC157和一个用于实训的加热器。
在软件上我们采用的标准的PID控制算法对其进行的控制输出。
从而有机的把软硬件整合成为一个整体,构成一个比较简易的加热器温度控制系统。
3.3AC6611和加热器接线图设计
AC6611是通过AC157和加热器相连接的,在加热器的输出和地之间还需要接一个500Ω的电阻,将4到20毫安的电流转换成2到10伏的电压。
其具体的实物接线图和模块图如下:
模块图
实物图
3.4控制程序的方案设计和模块划分
控制程序的设计具体包括:
界面设计、数据采集处理程序的设计,实时控制程序设计等。
界面设计包括趋势曲线、棒图的显示和报警显示等。
数据采集和处理和处理程序设计包括AC6611数据采集程序、D/A输出程序、标度换算、数字滤波、报警程序等相应的程序设计。
实时控制程序包括PID算法、输出限幅等程序的设计。
1)在趋势曲线和棒图的显示时,我们分别用红、蓝、绿三种颜色的线条显示SP、PV和MV的相应实时值,其值来自PID的算法程序的输出。
2)在编辑栏中我们可以修改PID控制算法的相应的参数P、I、D等。
当修改完成后,我们可以点击确认按钮,将修改后的参数送入到算法程序中去。
4、数据采集与输出程序设计
加热器的温度的变化范围是0到100℃,AC6611只用到了其一半的量程,也就是说其代码只用了0到2047。
其具体的书记采集和温度的换算程序如下:
HS=100.0,LS=0.0;
unsignedlongad;
unsignedlongda;
AC6611_AD(hDevice,3,&ad);
PV=(ad-819.0)*(HS-LS)/(4095.0-819.0);
En=SP-PV;
Edit2->Text=FloatToStrF(En,0,4,4);
DeltaUn=q0*En+q1*En1+q2*En2;
Un=Un1+DeltaUn;
if(Un>100.0)Un=100.0;
if(Un<0)Un=0;
Un1=Un;
En2=En1;
En1=En;
da=(unsignedshortint)(Un*2048.0/100.0);
if(da>2048)da=2048;
AC6611_DA(hDevice,da);
5、控制算法程序设计
5.1温度设定曲线的程序实现
在进行温度设定曲线的绘制时,我们需要将温度的设定曲线和程序中的采样程序结合起来才能够体现出程序的实时性,具体的程序如下:
Image1->Picture->LoadFromFile("QUSHI.bmp");
Image1->Canvas->Pen->Width=1;
Image1->Canvas->Pen->Color=clBlack;
Image1->Canvas->MoveTo(0,300);
for(inti=0;i<480;i++)Image1->Canvas->LineTo(i,300-sptrend[i]);
Image1->Canvas->Pen->Color=clBlue;
Image1->Canvas->MoveTo(0,300);
for(inti=0;i<480;i++)Image1->Canvas->LineTo(i,300-pvtrend[i]);
Image1->Canvas->Pen->Color=clGreen;
Image1->Canvas->MoveTo(0,300);
for(inti=0;i<480;i++)Image1->Canvas->LineTo(i,300-mvtrend[i]);
Edit15->Text=FloatToStrF(PV,0,4,4);
Edit16->Text=FloatToStrF(Un,0,4,4);
5.2PID控制算法的程序设计
在此加热器温度控制系统我们所采算法是标准的PID控制算法,程序设计如下(附流程图):
AC6611_AD(hDevice,9,&ad);
PV=(ad-819.0)*(HS-LS)/(4095.0-819.0);
En=SP-PV;
Edit2->Text=FloatToStrF(En,0,4,4);
DeltaUn=q0*En+q1*En1+q2*En2;
Un=Un1+DeltaUn;
if(Un>100.0)Un=100.0;
if(Un<0)Un=0;
Un1=Un;
En2=En1;
En1=En;
6、控制程序的调试
6.1主要调试的内容
在程序编写完成后,为验证系统的稳定性和可靠性,此时我们需要让系统运行起来,经过反复的操作和验证后的系统才是一个稳定可靠的系统。
在系统的调试中,我们调试的主要内容包括:
硬件调试、各个部分子程序的调试、PID参数的整定调试等。
6.2调试方法
硬件:
在进行硬件调试的时候,我们可以让硬件在极限条件进行工作,观察其性能是否稳定,其个方面的指标是否有较大的波动,以验证其性能的优劣。
子程序:
在操作界面上对开发的系统进行各种各样的试探性操作,观察程序是否存在没有考虑到的漏洞,以对其进行修改和调试。
PID参数的整定:
在这次实训中PID参数的整定是最重要的环节,也是系统调试的核心内容。
其参数整定的方法是根据被控过程的特性来确定PID控制器的比例系数、积分时间和微分时间的大小。
PID参数的整定的方法主要有两大类:
一是理论计算整定法,主要是通过系统的数学模型进行理论计算得到控制器参数,但还必须通过工程实际进行相应的调整和修改。
二是工程整定发,这种方法主要依靠的是操作者的经验直接在控制系统的试验中进行。
PID控制器参数的工程整定方法,主要有临界比例法、反应曲线法和衰减法。
这些工程参数整定的方法对操作的经验依赖性大,一般只适用于有较长工作年限的操作者。
但是不管事哪种参数整定的方法,都必须在实际的系统中进行相应的调试、修改和完善,才能够找到控制的最佳参数。
6.3PID参数整定
PID参数整定的口诀:
参数整定找最佳,先是比例后积分,
自后再把微分加,曲线震荡很频繁,
比例参数应增加,曲线偏离回复慢,
积分时间往下拉,曲线波动周期长,
积分时间再加长,曲线震荡频率快,
先把积分降下来,动差大来波动慢,
积分时间应加长,理想曲线两个波,
前四后一不能多,一看二调多思考,
从小到大顺序查,调节效果才会好。
根据上面的口诀所诉的步骤我们依次对PID控制器的参数进行整定,从而得到较好的控制效果。
6.4整定结果和分析
在进行PID参数的整定过程中,我们将以P=20、I=10、D=5为一个参照的基本参数,来说明在整定的过程中P、I、D三个参数对控制器性能的影响,在此过程中,每次的整定都只将改变其中的一个参数,其他的参数不变,这样我们便能够清晰的从整定实时趋势曲线的输出直观的判断出各个参数在控制器中所扮演的角色。
从而更加深刻的加强我们对PID控制器的认知。
图一
图二
图三
图四
通过以上我们对单一参数的调节,我们可以清楚知道,在PID控制器中:
比例控制能迅速反应误差,从而减小误差,但比例控制不能消除稳态误差,比例系数的增大会系统的不稳定;积分控制的作用是,只要系统存在误差,积分控制作用就不断的积累,输出控制量以消除误差,因而只要哟足够长的时间,积分控制将能完全消除误差,积分作用太强会使系统超调加大,甚至使系统出现震荡;微分控制可以减小超调量,克服震荡,使系统的稳定性提高,同时加快系统的动态响应速度,减小调整时间,从而改善系统的动态性能。
7、技术小结
在本次实训中,我们利用C++Builder编写的基于AC6611板卡的单回路加热器温度控制系统。
在进行了PID参数的整定后各项指标基本上能够满足实训的要求。
在数字PID控制器中采样周期越小,其控制效果就越接近于连续PID的控制效果。
在系统的动态过程中,比例系数增加时,系统的动作灵敏,响应速度加快,但是比例系数偏大,会导致系统的震荡次数增多,调节时间会加长,也就是当比例系数过大时会引起系统的不稳定;当比例系数太小时,又会使系统动作过于迟缓。
积分控制可以消除稳态误差,提高系统控制的精度,但是当积分时间太大时,积分的作用过于微弱,以至于不能够完全的消除系统的稳态误差。
微分作用可以改善系统的动态性能,但是当微分时间偏大或是偏小,都会导致系统的超调增大,从而使得系统的调节时间比较长。
所以在PID参数整定的过程中一定要,严格的遵循参数整定的方法,以便达到高效率、高精度的控制。
8、心得体会
在为期两周的计算机控制技术实训中,通过老师的讲解和我们自身的不断学习,我们顺利的完成本次实训的基本任务。
由于自己的基础较差,所以在本次实训中也遇到了不少的困难,很多东西都需要自己在实训中学习,不过在老师和同学的帮助下,在本次实训中我学到了很多的东西,使我受益匪浅。
通过本次的实训,我对C++Builder开发软件有了一定的了解和掌握,也学会了一些简单的命令语言,对控制系统的硬件组成和组装连线等一些列的基本操作也有了很好的掌握。
在进行PID参数整定的时候,我熟悉了PID各个参数对系统性能的影响。
这加深了我对PID控制器的理解,在今后的学习和工作中都将给我带来相当的影响。
在实训了,老师和同学给了我很多的帮助,这也是我能够顺利的完成实训的一个重要的前提。
虽然说能够顺利的完成本次实训,大部分功劳在于自己的努力,但和老师、同学的帮助是密不可分,在这里很感谢在此次实训中帮助过我的老师和同学。
参考文献
[1]于海生.微型计算机控制技术[M].北京:
清华大学出版社,1999.
[2]王锦标.计算机控制系统[M].北京:
清华大学出版社,2004.
[3]叶蓓华.数字控制技术[M].北京:
清华大学出版社,2002.
[4]张晋格.计算机控制原理与应用[M].北京:
电子工业出版社,1995.
[5]疏松贵.计算机控制系统理论与应用[M].北京:
科学出版社,1998.
附录:
控制程序清单
//---------------------------------------------------------------------------
#include
#include
#pragmahdrstop
#include"Unit1.h"
//---------------------------------------------------------------------------
#pragmapackage(smart_init)
#pragmaresource"*.dfm"
floatadcsave[100];
floatavg=0;
floatSP,PV=0.0;
intpvtrend[480];
intsptrend[480];
intmvtrend[480];
floatHS=100.0,LS=0.0,HL=7.5,LL=2.5,DH=0.2;
floatPID_DB=2,P=20,I=10,D=5,KD=5;
floatUn=0.0,DeltaUn=0.0,Un1=0.0,En=0.0,En1=0.0,En2=0.0;
floatq0,q1,q2;
floatTS=1.0;
TForm1*Form1;
inttrend[480];
//---------------------------------------------------------------------------
__fastcallTForm1:
:
TForm1(TComponent*Owner)
:
TForm(Owner)
{
//-------------------------------------------------------------------
hDLL=LoadLibrary("ac6611.dll");
if(hDLL!
=NULL)Label2->Caption="AC6611.dllloadok!
";(FARPROC&)AC6611_CreateDevice=GetProcAddress(hDLL,"AC6611_CreateDevice");//创建驱动句柄(FARPROC&)AC6611_CloseDevice=GetProcAddress(hDLL,"AC6611_CloseDevice");//关闭驱动句柄
(FARPROC&)AC6611_DI=GetProcAddress(hDLL,"AC6611_DI");//数字量输入,port=0-1两个通道,8位数据由DiData返回
(FARPROC&)AC6611_DO=GetProcAddress(hDLL,"AC6611_DO");//数字量输出,port=0-1两个通道,8位数据由DoData输出
(FARPROC&)AC6611_DiBit=GetProcAddress(hDLL,"AC6611_DiBit");//数字量输入,port=0-1两个通道,指定位输入
(FARPROC&)AC6611_DoBit=GetProcAddress(hDLL,"AC6611_DoBit");//数字量输出,port=0-1两个通道,指定位输出
(FARPROC&)AC6611_DA=GetProcAddress(hDLL,"AC6611_DA");//DA输出,0-4095
(FARPROC&)AC6611_VoltageToDA=GetProcAddress(hDLL,"AC6611_VoltageToDA");
(FARPROC&)AC6611_AD=GetProcAddress(hDLL,"AC6611_AD");//通用AD采样(FARPROC&)AC6611_AD_CHN=GetProcAddress(hDLL,"AC6611_AD_CHN");//设置AD通道0-15
(FARPROC&)AC6611_ADS=GetProcAddress(hDLL,"AC6611_ADS");//直接AD采样,为单通道AD采样设计(FARPROC&)AC6611_ADToVoltage=GetProcAddress(hDLL,"AC6611_ADToVoltage");
hDevice=AC6611_CreateDevice(0,&ErrorOf6611);//创建驱动,选择第0块卡
if(hDevice!
=-1){
Label1->Caption="AC6611CardIsExist!
";
}else{
Label1->Caption="AC6611CardIsnotExist!
";
}
}
//---------------------------------------------------------------------------
void__fastcallTForm1:
:
Timer1Timer(TObject*Sender)
{
HS=100.0,LS=0.0;
unsignedlongad;
unsignedlongda;
AC6611_AD(hDevice,9,&ad);
//Edit1->Text=IntToStr(ad);
PV=(ad-819.0)*(HS-LS)/(4095.0-819.0);
En=SP-PV;
Edit2->Text=FloatToStrF(En,0,4,4);
DeltaUn=q0*En+q1*En1+q2*En2;
Un=Un1+DeltaUn;
if(Un>100.0)Un=100.0;
if(Un<0)Un=0;
Un1=Un;
En2=En1;
En1=En;
da=(unsignedshortint)(Un*2048.0/100.0);
if(da>2048)da=2048;
AC6611_DA(hDevice,da);
if(PV>=HL)
{
Edit5->Color=clRed;
}
else
{
Edit5->Color=clGreen;
}
if(PV<=LL)
{
Edit6->Color=clRed;
}
else
{
Edit6->Color=clGreen;
}
for(inti=0;i<479;i++)
{
pvtrend[i]=pvtrend[i+1];
pvtrend[479]=300*PV/(HS-LS);
sptrend[i]=sptrend[i+1];
sptrend[479]=300*SP/(HS-LS);
mvtrend[i]=mvtrend[i+1];
mvtrend[479]=300*Un/100.0;
}
//绘制磅图
Image2->Picture->LoadFromFile("BT.bmp");
Image2->Canvas->Pen->Color=clBlack;
Image2->Canvas->Pen->Width=5;
Image2->Canvas->MoveTo(30,294);
Image2->Canvas->LineTo(30,294-SP*288.0/(HS-LS));
Image2->Canvas->Pen->Color=clBlue;
Image2->Canvas->MoveTo(55,294);
Image2->Canvas->LineTo(55,294-PV*288/(HS-LS));
Image2->Canvas->Pen->Color=clGreen;
Image2->Canvas->MoveTo(70,294);
Image2->Canvas->LineTo(70,294-Un*288/100.0);
//绘制趋势曲线
Image1->Picture->LoadFromFile("QUSHI.bmp");
Image1->Canvas->Pen->Width=1;
Image1->Canvas->Pen->Color=clBlack;
Image1->Canvas->MoveTo(0,300);
for(inti=0;i<480;i++)Image1->Canvas->LineTo(i,300-sptrend[i]);
Image1->Canvas->Pen->Color=clBlue;
Image1->Canvas->MoveTo(0,300);
for(inti=0;i<480;i++)Image1->Canvas->LineTo(i,300-pvtrend[i]);
Image1->Canvas->Pen->Color=clGreen;
Image1->Canvas->MoveTo(0,300);
for(inti=0;i<480;i++)Image1->Canvas->LineTo(i,300-mvtrend[i]);
Edit15->Text=FloatToStrF(PV,0,4,4);
Edit16->Text=FloatToStrF(Un,0,4,4);
}
//---------------------------------------------------------------------------
void__fastcallTForm1:
:
Button2Click(TObject*Sender)