//******************** //PI filter computing created by ok1tin 051115 (ymd) //******************** #include #include #include #include #include #include #include #include #include #include #include #include "usrlib.h" //Upper Case named function inside #pragma option //xxxxxxxxxxxx global vars declaration xxxxxxxxxxxxxxxx complex j = complex(0,1); complex l = complex(1,0); complex Z1,Z2,Z3,Z4,Z5,Z6,Z7,Zo,Zi; //Zo output Z, Zi imput Z complex Fu,Fp; //Fu prenos U, Fp prenos P double C[12]; double L[12]; double Ri,Rz; double x1,x2,y1,y2,x11; //scale axis double Frq,Fr,dF,Om; //dF:deltaFrq Frq,Omega double k=0.02,k1,m1,m2; //increment params ,meritka Zo Fu int ex=0,fl1=0,fl2=1,fl3=0; //flags: fl1=1 show circuit fl2=0 show logchar char c=' ',s1[20],s2[40],s5[50]; //space for names char fname[50]; //space for file name FILE *f1; //forward declaration needed, otherwise Unhandled Exception OD ! void SavPar(); void LoaPar(); void ShowPar(); void DrawScale(); void Optimize(); //************************************************* void ShowCircuitDiagram(void) { printf("\Circuit diagram : "); /* printf("\nÄÄRiÄÄÂÄÄÄZ2ÄÄÄÂÄÄÄZ4ÄÄÄÂÄÄ-Z6ÄÄÄÂÄÄÄÄÂÄÄÄ "); printf("\n Z1 Z3 Z5 Z7 Rz "); printf("\nÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄ "); */ printf("\nÄÄRiÄÄÂÄÄÄC2ÄÄÄÂÄÄÄC4ÄÄÄÂÄÄ-C6ÄÄÄÂÄÄÄÄÂÄÄÄ "); printf("\n L1 L3 L5 L7 Rz "); printf("\nÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄ "); } void Help(void) { // printf("\n prenos vykonu: 10*log(abs(Fp(Frq)))) green"); gotoxy(1,1); ShowCircuitDiagram(); printf("\nMenu: F1,Alt,CurKeys,s,l,c "); printf("\nRemove C4..L7..? (Change it to 1[F] 1[H] "); printf("\nChangeL1?(q,Q) "); printf("\n 1 2 3 4 5 6 7 8 9 "); printf("\n q w e r t y u i z a "); printf("\n------------------------------------- "); printf("\n C1 C2 C3 C4 C5 C6 C7 C8 C9 "); printf("\n L1 L2 L3 L4 L5 L6 L7 Ri Rz "); // printf("\nCyan: vstup impedance Zi(Frq) zoom: + - "); printf("\nZo(Frq) zoom ? + - , Red "); printf("\nFu(Frq) zoom ? Ctrl + - , White "); // printf("\nGreen: prenos komplex Fp(Frq) zoom: + - "); printf("\nCompute: B(-3dB)[kHz] , Q=Frq/B , G[dB] "); printf("\nOptimize?(m) "); printf("\nHelp is in file pi*.hlp "); printf("\nPress any Key ... "); getch(); }; void XchPar(){ //change params for tunning filter c=getch(); flushall(); //flush buffer switch (c) { case 27: ex=1;break; //Esc key case ';': Help();getch();break; //F1 key case 'g': fl2=!fl2;break; //xor switch case 'a': k-=k*0.1;break; //increment/decrement params speed case 'A': k+=k*0.1;break; case 157: x1+=(x1<100E6?1E6:10E6);DrawScale();break; //Alt + cur key -> case 155: x1-=(x1<100E6?1E6:10E6);DrawScale();break; //Alt + cur key <- case 75: x2+=k*x2;DrawScale();break; //cur key <- case 77: x2-=k*x2;DrawScale();break; //cur key -> case 152: y1+=k*y1;DrawScale();break; //Alt + cur key up case 160: y1-=k*y1;DrawScale();break; //Alt + cur key down case 80: y2+=k*y2;DrawScale();break; //cur key down case 72: y2-=k*y2;DrawScale();break; //cur key up case '1': C[1]-=k*C[1];break; case '!': C[1]+=k*C[1];break; case '2': C[2]-=k*C[2];break; case '@': C[2]+=k*C[2];break; case '3': C[3]-=k*C[3];break; case '#': C[3]+=k*C[3];break; case '4': C[4]-=k*C[4];break; case '$': C[4]+=k*C[4];break; case '5': C[5]-=k*C[5];break; case '%': C[5]+=k*C[5];break; case '6': C[6]-=k*C[6];break; case '^': C[6]+=k*C[6];break; case '7': C[7]-=k*C[7];break; case '&': C[7]+=k*C[7];break; case 'q': L[1]-=k*L[1];break; case 'Q': L[1]+=k*L[1];break; case 'w': L[2]-=k*L[2];break; case 'W': L[2]+=k*L[2];break; case 'e': L[3]-=k*L[3];break; case 'E': L[3]+=k*L[3];break; case 'r': L[4]-=k*L[4];break; case 'R': L[4]+=k*L[4];break; case 't': L[5]-=k*L[5];break; case 'T': L[5]+=k*L[5];break; case 'y': L[6]-=k*L[6];break; case 'Y': L[6]+=k*L[6];break; case 'i': Ri-=k*Ri;break; case 'I': Ri+=k*Ri;break; case 'z': Rz-=k*Rz;break; case 'Z': Rz+=k*Rz;break; case '<': dF-=k*dF;break; //speed picture painting case '>': dF+=k*dF;break; case 43: m1+=k*m1;break; //+ zoom Zo red case 45: m1-=k*m1;break; //- case 144: m2+=k*m2;break; //Ctrl + zoom Fu blue case 142: m2-=k*m2;break; //Ctrl - case 's': SavPar();break; //save params to text file case 'l': LoaPar();break; //load params from text file case 'm': Optimize();break; default: ; };//end switch if (x1<=0) x1=1e6; // action on scale border if (x1>=x2) x1-=2e6; // invalid data // if (y1>=y2) y1=y2; ShowPar(); } void ShowPar(){ int i; for (i=1;i<10;i++) { if ((L[i] < 0.9 ) && (L[i] > 1E-19)) { gotoxy(65,i+1); printf("L%d=%10.4e H",i,L[i]);} } for (i=1;i<10;i++) { if ((C[i] < 0.9 ) && (C[i] > 1E-19)) { gotoxy(65,i+11); printf("C%d=%10.4e F",i,C[i]); } } gotoxy(65,++i+11); printf("Ri=%9.0f Ohm",Ri); gotoxy(65,++i+11); printf("Rz=%9.0f Ohm",Rz); // setcolor(LIGHTGRAY); outtextxy(1,470,"Menu: F1"); // sprintf(s2,"%5.3f",k); //float to string zapis do s2 // outtextxy(600,470,s2); setcolor(WHITE); if (c=='c') fl1=!fl1; //xor if (fl1) {gotoxy(1,18);ShowCircuitDiagram();} } void SavPar(){ struct date d; struct time t; if((f1=fopen(fname,"r+"))==NULL){ //for update printf("\nData file %s not exist ...\007\n",fname); //pipne f1=fopen(fname,"a+"); //for create printf("...created\n"); getch();return; } for (int i=1;i<10;i++) { fprintf(f1,"C%d=%5.3e;\n",i,C[i]); fprintf(f1,"L%d=%5.3e;\n",i,L[i]); } fprintf(f1,"Ri=%5.1f;\nRz=%5.1f;\n",Ri,Rz); fprintf(f1,"x1=%5.3e;\nx2=%5.3e;\n" ,x1,x2); fprintf(f1,"y1=%5.3e;\ny2=%5.3e;\n" ,y1,y2); fprintf(f1,"m1=%5.3e;\nm2=%5.3e;\n" ,m1,m2); fprintf(f1,"dF=%5.3e;\n" ,dF); getdate(&d);gettime(&t); //for data identification fprintf(f1,"Date:Time = %02d%02d%02d:" ,d.da_year-2000,d.da_mon,d.da_day); fprintf(f1,"%02d%02d%02d\n",t.ti_hour,t.ti_min,t.ti_sec); fprintf(f1,"xxxxxxxxxxxxxxxxxxxxxxx\n\n\n" ); fclose(f1); printf("\nParams saved in %s",fname); ShowPar(); delay(500); } void LoaPar(){ if((f1=fopen(fname,"r"))==NULL){ //for read printf("\nData file %s not exist,press 's' \007\n",fname); //pipne getch(); return; } // s5="C1=\0" "1e-10" -> 1e-10 zahod vse do konce EOL for (int i=1;i<10;i++) { fgets(s1,4,f1);fscanf(f1,"%lf\n",&C[i]);fgets(s5,10,f1); fgets(s1,4,f1);fscanf(f1,"%lf\n",&L[i]);fgets(s5,10,f1); } fgets(s1,4,f1);fscanf(f1,"%lf\n",&Ri);fgets(s5,10,f1); fgets(s1,4,f1);fscanf(f1,"%lf\n",&Rz);fgets(s5,10,f1); fgets(s1,4,f1);fscanf(f1,"%lf\n",&x1);fgets(s5,10,f1); fgets(s1,4,f1);fscanf(f1,"%lf\n",&x2);fgets(s5,10,f1); fgets(s1,4,f1);fscanf(f1,"%lf\n",&y1);fgets(s5,10,f1); fgets(s1,4,f1);fscanf(f1,"%lf\n",&y2);fgets(s5,10,f1); fgets(s1,4,f1);fscanf(f1,"%lf\n",&m1);fgets(s5,10,f1); fgets(s1,4,f1);fscanf(f1,"%lf\n",&m2);fgets(s5,10,f1); fgets(s1,4,f1);fscanf(f1,"%lf\n",&dF);fgets(s5,10,f1); fclose(f1); printf("\nParams loaded from %s ",fname); ShowPar(); delay(500); } //xxxxxxx main complex evaluation void ZVal(){ //Valuate all Z Z1=j*Om*L[1]; Z2=1/(j*Om*C[2]); //paralel LC Z3=j*Om*L[3]; Z4=1/(j*Om*C[4]); //paralel LC Z5=j*Om*L[5]; Z6=1/(j*Om*C[6]); Z7=1/(1/(j*Om*L[7])+1/Rz); //paralel RC } double Ful(double & Fr){ //main function - voltage transmition complex A,B,C,D,E,F,G; //local tmp vars double Fulog; // method of circuit node voltage was used Om =2*M_PI*Fr; ZVal(); A=(1/Z7+1/Z6)*Z6; // substitution make it easy B=(1/Z5+1/Z4+1/Z6); C=(A*B-1/Z6)*Z4; D=(1/Z3+1/Z2+1/Z4); E=(1/Z1+1/Ri+1/Z2); F=(C*D-A/Z4)*Z2; G=(E*F-C/Z2)*Ri; Fu=1/G; //complex result Fulog=20*log10(abs(Fu)); //main result , tnx C++ ! C=1/(1/Z1+1/Ri); B=1/(1/Z3+1/(Z2+C)); A=1/(1/Z5+1/(Z4+B)); Zo=1/(1/Z7+1/(Z6+A)); //output impedance Zo B= 1/(1/Z5+1/(Z6+Z7)); A= 1/(1/Z3+1/(Z4+B)); Zi=Ri+1/(1/Z1+1/(Z2+A)); //input impedance Zi return Fulog; // main result // Fp=Fu*Fu*Zi/Zo; // power transmition } //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx void DrawVertLines(double x3,double x4){ //soft,rough double x; setcolor(LIGHTGRAY); //vert lines soft for (x=x1;x<=1.5*x2;x+=x3*1E6) DrawLine(x,y1,x,y2); setcolor(WHITE); for (x=x1;x<=1.5*x2;x+=x4*1E6) { DrawLine(x,y1,x,y2); sprintf(s1,"%-5.0f",x/1e6); DrawTextXY(x,y2,s1); } } void DrawScale(){ int i; flushall(); //flush buffer x1=(x1<=0?1E6:x1); Scale(x1,x2,y1,y2); cleardevice(); setcolor(LIGHTGRAY); for (i=-99;i<=+99;i+=3) { //horiz lines soft sprintf(s2,"%d",i); DrawLine(x1,i,x2,i);DrawTextXY(x2,i,s2); }; setcolor(WHITE); for (i=-100;i<=100;i+=20) { //horiz lines sprintf(s2,"%d",i); DrawLine(x1,i,1.5*x2,i);DrawTextXY(x2,i,s2); }; // **************************************************** if (x2< 5E6) DrawVertLines(0.2,1); //soft,rough if ((x2>=5E6) &&(x2<10E6)) DrawVertLines(0.5,1); if ((x2>=10E6) &&(x2<20E6)) DrawVertLines(1,2); if ((x2>=20E6) &&(x2<50E6)) DrawVertLines(1,5); if ((x2>=50E6) &&(x2<100E6)) DrawVertLines(2,10); if ((x2>=100E6) &&(x2<200E6)) DrawVertLines(5,20); if ((x2>=200E6) &&(x2<500E6)) DrawVertLines(10,50); if ((x2>=500E6) &&(x2<1000E6)) DrawVertLines(20,100); if ((x2>=1000E6)&&(x2<2000E6)) DrawVertLines(50,200); if (x2>=2000E6) DrawVertLines(100,500); outtextxy(1,10,"MHz"); outtextxy(480,460,"dB"); DrawCross((x1+x2)/2,+(y1+y2)/2); //centre of Gauss plane } void DrawFul(){ //draw all, Ful(Frq),... double Ful1,Ful1m; double Fr1; int i1; Scale(x1,x2,y1,y2); if (kbhit()) DrawScale(); Ful1m=-10; //dB for(Frq=x1;Frq<1.1*x2;Frq+=dF){ Ful1=Ful(Frq); Plot (Frq,Ful1,WHITE); Plot (real(Fu)*(x2-x1)*m2 + (x1+x2)/2, imag(Fu)*(y2-y1)*m2 + (y1+y2)/2,WHITE); Plot (real(Zo)*(x2-x1)*m1 + (x1+x2)/2, imag(Zo)*(y2-y1)*m1 + (y1+y2)/2,LIGHTRED); if (fabs(imag(Zo)) < 1) { gotoxy(1,25); //last Dos line ! printf("ReZo=%7.0f Ohm ",real(Zo)); } if (kbhit()) { XchPar(); Frq=x1; //redraw from begin if (c==27) return; //Esc } //end kbhit if (Ful1>Ful1m) {Ful1m=Ful1; Fr1=Frq;i1=3;} //find maximum if (((Ful1m-Ful1) > i1) && (Frq>Fr1) && (Fr1>1E6)){ //3dB printf("Frez=%7.3fMHz ",Fr1/1E6); //rez frq printf("B=%7.1fKHz ",2*(Frq-Fr1)/1E3); // B = abt 2*B1 printf("Q =%5.2f ",Fr1/(2*(Frq-Fr1))); //circuit quality. printf("G =%5.1fdB ",Ful1m); //profit setcolor(LIGHTBLUE); DrawLine(Fr1,y1,Fr1,y2); DrawLine(x1,Ful1m-3,x2,Ful1m-3); strcpy(s2,"-3dB") ;DrawTextXY(x2*0.9,Ful1m-3,s2); i1=10000; //used like flag down setcolor(WHITE); if (fabs(Fr1-3.5e6)<0.4e6) fl3=1; else fl3=0; } } //end for } //************************* void Optimize(){ //stupid search the best params double C1[12],C2[12]; //from,to double L1[12],L2[12]; //from,to double Ful1,Ful2,Ful35,Ful70; double Fr1,Fr2; double k1,k2,k3,kc[12],kl[12]; double x,t1; clock_t start, end; int i,i1,i2,i3; ex=0; Ful35= -20; //dB Ful70 = -3; Fr1=(x1+x2)/2; Fr2=Fr1*2; k1=1.05; k3=1; //range if (C[7]<0.2e-12) {k1=1.2; k3=0.05/0.02;} if (C[5]<0.2e-12) {k1=1.5; k3=0.10/0.02;} k2=1.0+k3*k; //step ShowPar(); gotoxy(1,1); cout<<"\nSearching best params for Frq= "<=Ful35) && (Ful2 change freq range [MHz] Alt + CurKey <- -> change start freq [MHz] CurKey | | change vertical scale [dB] Alt + CurKey | | move vertical scale zero [db] s save params to pi3cl3.txt (you can edit it) l load params fr pi3cl3.txt c show circuit diagram +,- zoom komplex output impedance (red)picture Zo(Frq) Ctrl + +,- zoom komplex transnition (white)picture Fu(Frq) 2.2 Keyboard map for params changing 1 2 3 4 5 6 7 8 9 q w e r t y u i z a ------------------------------------- C1 C2 C3 C4 C5 C6 C7 C8 C9 L1 L2 L3 L4 L5 L6 L7 Ri Rz Eexample : q for L1 value down Q for L1 value up 1 for C1 value down ! for C1 value up 2.3 Minor controls Shift + <,> change speed picture drawing a,A for changing step value changing 3. Symbols used : mkH micro Henry ppF piko Farad Om omega dB decibel Om Ohm j SQRT(-1) B = Frq/Q wide of Frq range Q quality Frq frequency */ /* File Pi3cl3.txt contents C1=1.000e+00; L1=1.000e+00; C2=6.800e-12; L2=1.000e+00; C3=9.800e-01; L3=4.400e-08; C4=3.457e-12; L4=1.000e+00; C5=1.000e+00; L5=4.400e-08; C6=6.800e-12; L6=1.000e+00; C7=1.000e+00; L7=1.000e+00; C8=1.000e+00; L8=1.000e+00; C9=1.000e+00; L9=1.000e+00; Ri= 75.0; Rz= 75.0; x1=2.500e+07; x2=4.011e+08; y1=-5.318e+01; y2=5.526e+00; m1=4.000e-03; m2=4.000e-01; dF=7.500e+04; Date:Time = 051117:173336 xxxxxxxxxxxxxxxxxxxxxxx */ /* File Usrlib.h contents //********************************************************** // usrlib.h C++ //********************************************************** //unit usrlib; //interface //uses graph; //far // overlay //type matice24=array[1..24,1..24+1] of real; // vektor24=array[1..24] of real; //procedure RSLR(rad:byte;m:matice24;var v:vektor24;error:boolean); //function hex(i:longint):string; //function wrd(w:Word):string; //function byt(b:Byte):string; //function Bin(Dec:longint):string; //function tg(x:real):real; //function cotg(x:real):real; //function log(x:real):real; //function xny(x,y:real):real; #include "d:\home\mickal\cpp\usrlib.cpp" //path in OPTION void OpenGraph(void); void Scale(double Xmin,double Xmax,double Ymin,double Ymax); void MoveTo(double x,double y); void Plot(double X,double Y,int Barva); void DrawLine(double x1,double y1,double x2,double y2); void DrawLineTo(double x1,double y1); void DrawCross(double x,double y); void DrawTextXY(double x,double y,char *Pismo); void DrawCircle(double x1,double y1,double r1); double **createarray(int radky,int sloupce); void releasearray(double **p_p_x,int radky); long int hpck(long int li); //heapcheck */ /* File Usrlib.cpp contents //************************************************} // usrlib C++ } //************************************************} //{$O+,F+} {overlay} //unit usrlib; //implementation #include #include #define __colors #include #include #include #include //#define _windows //#ifndef _windows #include //#include "usrlib.h" extern double px=1; //global extern double py=1; extern double pz=1; extern double mx=1; extern double my=1; extern double mz=1; void OpenGraph(void){ /* request auto detection */ int gdriver = DETECT, gmode, errorcode ; initgraph(&gdriver, &gmode, ""); errorcode = graphresult(); if (errorcode != grOk) { printf("\nGraphics error: %s", grapherrormsg(errorcode)); printf("\nThis program needs files from directory ..\BGI\*.bgi or ..\*.chr "); printf("\nMake some better path in your batch file for this program"); printf("\nPress any key...\n"); getch(); exit(1); /* terminate with an error code */ } } void Scale(double Xmin,double Xmax,double Ymin,double Ymax){ // Transformacni rovnice pro NZ px,mx,py,my // px+Xmax*mx=getmaxx() // px+Xmin*mx=0 // py+Ymax*my=0 // py+Ymin*my=getmaxy() if ((Xmax-Xmin)>=0) { // mx=getmaxx()/(Xmax-Xmin); mx=getmaxy()/(Xmax-Xmin); //linearita kruznice=kruznice! px=-Xmin*mx; } else outtextxy(0,0,"Scale Parametr Error"); if ((Ymax-Ymin)>=0) { my=-getmaxy()/(Ymax-Ymin); py=-Ymax*my; } else outtextxy(0,0,"Scale Parametr Error"); // printf(" mx=%f px=%f my=%f py=%f \n",mx,px,my,py); // getch(); } void MoveTo(double x,double y) { moveto((int)(px+x*mx),(int)(py+y*my)); } void Plot(double x,double y, int Barva) { putpixel((int)(px+x*mx),(int)(py+y*my),(int)(Barva)); } void DrawLine(double x1,double y1,double x2,double y2){ line ((int)(px+mx*x1),(int)(py+my*y1),(int)(px+mx*x2),(int)(py+my*y2)); } void DrawLineTo(double x1,double y1){ lineto((int)(px+mx*x1),(int)(py+my*y1)); } void DrawCross(double x,double y) { int SizeCross=3; line ((int)(px+mx*x-SizeCross),(int)(py+my*y), (int)(px+mx*x+SizeCross),(int)(py+my*y)); line ((int)(px+mx*x), (int)(py+my*y-SizeCross), (int)(px+mx*x), (int)(py+my*y+SizeCross)); } void DrawTextXY(double x,double y,char *Pismo) { outtextxy((int)(px+mx*x),(int)(py+my*y),Pismo); } void DrawDoubleXY(double x,double y,double d1) { //nefunguje char s1[32]; sprintf(s1,"%d",d1); // printf("%d ",d1); DrawTextXY(x,y,s1); } void DrawCircle(double x1,double y1,double r1){ ellipse((int)(px+mx*x1),(int)(py+my*y1),0,360,(int)(r1*mx),(int)(r1*mx)); } //#endif //_windows //************************************************ double **createarray(int radky,int sloupce) { int err=0; double **p_p_x,i; // if ((p_p_x=(double **)malloc(radky * sizeof(double *)))==NULL) err=1; if (!(p_p_x= new double*[radky])) err=1; for (i=0; i20)? why=1:why++; textcolor(WHITE); gotoxy(1,why+1);cout << "\n---------------- "; gotoxy(1,why) ;cout << message; delete message; } */