📄 superpid.c
字号:
//This is a pid controller.
//With a special technique, this program has realized ON-LINE parameter
//adjustment,that is, when you modify the parameter,the system can continue
//the control process.
#include"dos.h"
#include "conio.h"
#include"graphics.h"
#include"string.h"
#include"math.h"
#define pen_x x(hori[j]+60)
#define pen_y y(vert[i]+10)
#define dt 0.4945055
#define BOTM 240
#define LEFT 65
#define AMP 1.65
int startflag=0;
int MX,MY,tysyy;
float P,Td,Ti,E_SUM,EP,DATA,VSET,VCHK;
void interrupt (*old_int1c)();
void interrupt work();
void *draw_move;
int hori[2]={360,450},vert[4]={330,365,400,435};
int status[5]={320,250,280,410,440};
int tmpnt,calc,begn;
char *text[8]={" V_set"," Kp "," Ti"," Td"," Start"," Stop","Default"," Exit"};
char *scale[10]={" 10"," 20"," 30"," 40"," 50"," 60"," 70"," 80"," 90","100"};
//////////////////////////////////////////////////////////////////////
/// NOTICE: What you should do is to cmplete the PID calcu- ///
/// lation.There is a subfunction named "PID()",in which you ///
/// can place your calculation code.Other works such as sam- ///
/// leing,response curve drawing are completed by the system ///
/// designer. ///
//////////////////////////////////////////////////////////////////////
float pid(float value_set,float value_sample) /*//PID calculation sub_function*/
{
/*E_SUM is a external varible,it records the integral malue
EP is a external varible,it holds the past error value for the
differential calculation.
Please add your PID calculation code here.
After the calculation,you must retun the result, which is to be sent
to the D/A converter to control the oven;*/
int i,j,k;
float e,vv=0,vd;
e=value_set-value_sample; //VSET=set value; VCHK=sampled value; e=error
if(e<0.1&&e>-0.1)e=0; //prevent noise from bothering the system
if(e>10)return(5); //if sampled value is below the set value too much,
//write the maximum signal to the D/A board
if(e<-5)return(0);
E_SUM+=e*dt; //E_SUM is an integral varible
vv+=E_SUM/Ti;
vd=(e-EP)*Td/dt;
vv+=vd;
vv+=e;
vv*=P;
if(vv>20)vv=20;
vv/=4;
EP=e;
return(vv);
}
/*--------------------------------*/
float in() /*/fetch a value betwen 0 and 100 from I/O board*/
{
int ad,adr=0x0310;
float result;
outport(adr+2,0);
delay(1);
ad=inp(adr+3);
result=(float)ad*100/255;
return(result);
}
/*/////////////////////////////*/
void out(float daa) /*/write a value betwen 0 and 5 to I/O board*/
{int da,adr=0x0310;
if(daa>=0&&daa<=5)da=daa*51;
else da=0;
outport(adr+1,da);
inp(adr);
}
/*////////////////////////////*/
int x(int x) /*/change scale to meet with different screen mode,*/
{int f; /*/ and so do the next one*/
float aaaa;
aaaa=(float)MX/639*x;
f=(int)aaaa;
return(f);
}
/*///////////////////////////*/
int y(int y)
{
int g;
float bbbb;
bbbb=(float)y*MY/479; /* Mx My ??? */
g=(int)bbbb;
return(g);
}
/*///////////////////////////*/
void draw_setline(int vset)
{
int g;
g=getcolor();
setcolor(7);
setwritemode(1);
setlinestyle(1,0,1);
line(LEFT,BOTM-vset*AMP,LEFT+515,BOTM-vset*AMP);
setlinestyle(0,0,1);
setwritemode(0);
setcolor(g);
}
void draw_window()
{
int i,g;
g=getcolor();
setcolor(4);
setfillstyle(1,3);
bar(45,45,596,256);
moveto(x(LEFT-10),y(BOTM));
lineto(x(LEFT+520),y(BOTM)); //draw X_axis
moveto(x(LEFT),y(BOTM+10));
lineto(x(LEFT),y(BOTM-185)); //draw Y_axis
moveto(x(LEFT+510),y(BOTM-2));
lineto(x(LEFT+520),y(BOTM));
lineto(x(LEFT+510),y(BOTM+2));//draw X_arrow
moveto(x(LEFT-2),y(BOTM-175));
lineto(x(LEFT),y(BOTM-185));
lineto(x(LEFT+2),y(BOTM-175));//draw Y_arrow
settextstyle(2,0,4);
outtextxy(x(565),y(240),"time");
settextstyle(2,0,4);
outtextxy(x(68),y(45),"temperature");
for(i=10;i<101;i+=10){
line(x(LEFT),y(BOTM-i*AMP),x(LEFT+2),y(BOTM-i*AMP));
outtextxy(x(LEFT-20),y(BOTM-i*AMP-6),scale[i/10-1]);
}
setcolor(g);
}
/*////////////////////////////////*/
void draw_curve() //This is a part of the interrupt service process
{
int i,g,d,h;
g=getcolor();
h=getbkcolor();
setcolor(15);
if(tmpnt==0){
DATA=VCHK;
tmpnt++;
}
else if(tmpnt<=250&&tmpnt>0){
if(tmpnt==250){
setfillstyle(1,3);
draw_setline(VSET);
bar(x(LEFT+3),y(BOTM-170),x(LEFT+510),y(BOTM-1));
draw_setline(VSET);
tmpnt=0;
}
d=VCHK;
setlinestyle(0,0,1);
line(x(LEFT+tmpnt*2+3),y(BOTM-DATA*AMP-1),x(LEFT+tmpnt*2+5),y(BOTM-d*AMP-1));
setlinestyle(0,0,1);
DATA=d;
tmpnt++;
}
setcolor(g);
setbkcolor(h);
}
/*----------------------------*/
void interrupt work() /*/the interrupt service programe for INT_1c*/
{
float data_out,c;
int i,j;
if(tysyy==9){
VCHK/=9;
data_out=pid(VSET,VCHK);
out(data_out); //output control signal
draw_curve(); //draw response curve
VCHK=0; //inintialize VCHK for the next cycle
tysyy=0; //tysyy is a counter
}
else { //if tysyy!=9,the program only sample the
c=0; //output signal and aggregate.This is a
for(j=0;j<30;j++){ //soft low_pass filter
c+=in();
for(i=0;i<300;i++);
}
c/=30;
VCHK+=c;
tysyy=tysyy+1;
}
}
/*/////////////////////////////*/
void button(int x,int y,int w,int h,int color1,int color2,int deepth)
{
register i;
setcolor(8);
setlinestyle(SOLID_LINE,0,1);
rectangle(x,y,x+w,y+h);
setfillstyle(1,LIGHTGRAY);
bar(x+1,y+1,x+w-1,y+h-1);
for(i=2;i<deepth;i++){
setcolor(color1);
line(x+i,y+h-i,x+w-i,y+h-i);
line(x+w-i,y+i,x+w-i,y+h-i);
setcolor(color2);
line(x+i,y+i,x+i,y+h-i);
line(x+i,y+i,x+w-i,y+i);
}
}
/*////////////////////////////////////*/
void click(int i,int
j)
{
int k,kk;
void pen(int i,int j);
button(x(hori[j]),y(vert[i]),70,25,15,8,4);
setcolor(1);
settextstyle(0,0,1);
outtextxy(x(hori[j]+10),y(vert[i]+13),text[i*2+j]);
pen(i,j);
delay(100);
button(x(hori[j]),y(vert[i]),70,25,8,15,4);
setcolor(1);
outtextxy(x(hori[j]+10),y(vert[i]+10),text[i*2+j]);
pen(i,j);
}
void face()
{
void pen(int i,int j);
int i,j;
setbkcolor(7);
cleardevice();
button(0,20,639,459,15,8,4);
setfillstyle(1,1);
setcolor(7);
bar3d(x(0),y(0),x(639),y(20),0,1);
settextstyle(2,0,6);
setlinestyle(0,0,3);
outtextxy(x(10),y(0)," PID controller ");
settextstyle(0,0,1);
setlinestyle(0,0,1);
outtextxy(x(250),y(5)," version: 1.0 By Hailin Zhou");
rectangle(x(0),y(0),x(639),y(479));
setfillstyle(1,7);
button(x(40),y(40),560,220,15,8,5);
draw_window();
button(x(105),y(320),160,25,15,8,4);
button(x(105),y(350),160,25,15,8,4);
button(x(105),y(380),160,25,15,8,4);
button(x(105),y(410),160,25,15,8,4);
button(x(105),y(440),160,25,15,8,4);
setfillstyle(1,3);
bar(x(109),y(324),x(261),y(341));
bar(x(109),y(354),x(261),y(371));
bar(x(109),y(384),x(261),y(401));
bar(x(109),y(414),x(261),y(431));
bar(x(109),y(444),x(261),y(461));
setcolor(4);
settextstyle(0,0,1);
outtextxy(x(110),y(330)," V_SET =");
outtextxy(x(110),y(360)," Kp =");
outtextxy(x(110),y(390)," Ti =");
outtextxy(x(110),y(420)," Td =");
setcolor(8);
outtextxy(x(110),y(450)," waiting");
settextstyle(0,0,1);
setcolor(15);
setlinestyle(0,0,1);
rectangle(x(350),y(310),x(530),y(470));
rectangle(x(95),y(310),x(275),y(470));
setcolor(8);
rectangle(x(349),y(309),x(529),y(469));
rectangle(x(94),y(309),x(274),y(469));
putpixel(x(95),y(469),15);
putpixel(x(274),y(310),15);
putpixel(x(350),y(469),15);
putpixel(x(529),y(310),15);
putpixel(x(275),y(309),8);
putpixel(x(530),y(309),8);
setlinestyle(0,0,3);
setcolor(0);
line(x(357),y(310),x(473),y(310));
line(x(105),y(310),x(213),y(310));
setcolor(4);
settextstyle(1,0,1);
outtextxy(x(363),y(295),"control box");
outtextxy(x(113),y(295),"status box");
settextstyle(0,0,1);
for(i=0;i<4;i++)
for(j=0;j<2;j++){
button(x(hori[j]),y(vert[i]),70,25,8,15,4);
setcolor(1);
outtextxy(x(hori[j]+10),y(vert[i]+10),text[i*2+j]);
}
}
/*/////////////////////////////////////*/
void interface()
{
int i,n;
setbkcolor(0);
cleardevice();
MX=getmaxx();
MY=getmaxy();
setcolor(1);
settextstyle(0,0,3);
outtextxy(150,150,"Welcom to use");
setcolor(1);
settextstyle(1,0,8);
for(i=0;i<14;i++){
setcolor(15);
outtextxy(x(60-i),y(200+i),"PID controller");
if(i<11){
delay(80);
setcolor(1);
}
outtextxy(x(60-i),y(200+i),"PID controller");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -