/*Interdigital Bandpass Filter design program V 1.01 [Linux version] Conversion from Basic to C++ by Dale Heatherington, WA4DSY, 5-16-1996 -------------------------------------------------------------------- May 19 2004 Fixed a little error in cheb() pointed out by Federico Massaioli and changed some of the includes so this will compile on current versions of GNU C++ . ----------------------------------------------------------------------- This version is designed as a CGI program to allow it to run from a HTTP server where it can be accessed by Web Browsers. It outputs HTML formated text. Input is from the Browsers FORM. The original BASIC program was published in the January 1985 issue of Ham Radio magazine on page 12. The authors are Jerry Hinshaw, N6JH and Shahrokh Monemzadeh. Converted from OS/2 to Linux 8-13-97 by Dale Heatherington Compile with this command: $g++ -o idbpf idbpf.cpp Note: The input to this program comes from environment variable "QUERRY_STRING" which is supplied by the www server. */ #include #include #include #include #include #include #include #include using namespace std; //These arrays are copied directly from the BASIC code but start at zero instead of 1. double G[200],C[200], RK[200], AK[200], FR[40],ALOSS[40], A[200], B[200] ; //-------------- // These globals supply the program input data int elements; //number of elements double ripple; //ripple if cheby double FZGC,BWMC,R; //f center in GHZ, BW in mhz, load resistance in ohms double H,D,E; // Height above gnd, rod dia, end spacing int NFR; //number of frequency rejection points in graph double STP; //frequency step size //-------------- const double PI = 3.14159265; const char instructions[] = "Fill out the form below to design a bandpass filter as" " described in the January 1985 issue of Ham Radio Magazine." " These filters are generally limited to frequencies above 200 MHZ " " because their size is slightly longer than 1/4 wavelength. " " Click here for a drawing of " " a generic filter." " You may also download the " " C++ source for this program"; //-------------------------------------------------------------- double FuncFNRJ(double ta, double b, double c, double d) { return ((b*c)-(ta*d)) / ((c*c) + (d*d)); } //-------------------------------------------------------------- void cheb(int ele, double rip) { double beta,gamma,c; int k; c = (2 * rip) / 17.37; beta = log((exp(c)+1) / (exp(c) -1)); gamma = 0.5 * (exp(beta/(2*ele)) - exp(-beta / (2*ele))); for(k=0;k 65) Aloss = 65 ; else Aloss = (int)ALOSS[i]; double fr = FR[i] * 1000; double Alos = ALOSS[i]; // Print loss vs frequency graph. cout << setw(Aloss+1) << "*" << setprecision(1) << setw(72-Aloss) << fr << setw(7) << Alos << endl; } //line 1060 double wo = 2 * PI * FZGC * 1e+9; double f = D / H; double cf = (-0.0000422 + 0.0857397 * f + 0.0067853 * f * f - 9.092165e-2 * pow(f,3) + 0.169088 * pow(f,4)) * PI * H * 2.54; double ww = wo * 1e-12; double b2 = PI * aq / ( 2 * qwvl); double gg = 1 / R; double bb = -cos(b2) / (ze * sin(b2)); double el1 = 0.8 * qwvl; double ang = el1 * PI / (2 * qwvl); double b1 = ang - b2; double yl = -cos(ang) / (zm * sin(ang)); double cp = ww * (cf + 0.17655 * D * D / (qwvl - el1)); double y1 = cp + yl; double el2 = 0.87 * qwvl; ang = el2 * PI / ( 2* qwvl); double b4 = ang - b2; yl = -cos(ang) / (zm * sin(ang)); double cd = ww * (cf + 0.17655 * D * D / (qwvl - el2)); double y2 = cd + yl; double el3 = 0.95 * qwvl; ang = el3 * PI / (2 * qwvl); double b5 = ang - b2; yl = -cos(ang) / ( zm * sin(ang)); double cq = ww * (cf + 0.17655 * D * D / (qwvl - el3)); double y3 = cq + yl; double elem = y3 * y2 * el1 / ((y1 - y2) * (y1-y3)) + y1 * y3 * el2 / ((y2-y1)*(y2-y3)) + y1 * y2 * el3 / ((y3-y1) * (y3-y2)); double tann = sin(b1) / cos(b1); yl = FuncFNRJ(gg, bb+tann/ze, 1-ze*bb*tann, ze*gg*tann); y1 = cp + yl; tann = sin(b4) / cos(b4); yl = FuncFNRJ(gg, bb+tann/ze, 1-ze*bb*tann, ze*gg*tann); y2 = cd + yl; tann = sin(b5) / cos(b5); yl = FuncFNRJ(gg, bb+tann/ze, 1-ze*bb*tann, ze*gg*tann); y3 = cq + yl; double eleq = y3 * y2 * el1 / ((y1 - y2) * (y1 - y3)) + y1 * y3 * el2 / ((y2 - y1) * (y2 - y3)) + y1 * y2 * el3 / ((y3 - y1) * (y3 - y2)); cout << setprecision(3) << setw(30) << "Quarter wavelength = " << qwvl << " inches\n" << setw(30) << "Length of interior elements = " << elem << " inches\n" << setw(30) << "Length of end elements = " << eleq << " inches\n" << setw(30) << "Ground plane space = " << H << " inches\n" << setw(30) << "Rod diameter = " << D << " inches\n\n" << "End plates are " << E << " inches from center of end rod.\n" << "Tap external lines up " << aq << " inches from shorted end.\n" << "Line impedances: End rod: " << ze << ", other: " << zm << " Ext. lines: " << R << " Ohms\n"; int Tab = 10; cout << "Dimensions (inches)\n" << setw(Tab) << "El. No." << setw(Tab) << "End to C" << setw(Tab) << "C to C" << setw(Tab) << "G[k]" << setw(Tab) << "Q/Coup\n" ; double dom = E; int goo = 1; cout << setw(Tab) << "0" << endl << setw(Tab) << "1" << setw(Tab) << E << setw(Tab) << C[0] << setw(Tab) << G[0] << setw(Tab) << AK[0] << endl; for(i=0;i 12)) return "Elements"; if ((ripple < 0) || (ripple > 4)) return "Ripple"; if (FZGC <= 0) return "Frequency"; if (BWMC <= 0) return "Bandwidth"; if (R < 1) return "Impedance"; if ((H <= 0) || (H <= D)) return "Ground plane space"; if (D <= 0) return "Rod Dia"; if (E <= (D/2)) return "End plate to rod"; if (NFR < 3) return "Points to graph"; if (STP <= 0) return "Step size"; return NULL; } //------------------------------------------------------------ //query_string format : name=value&name2=value2&name3=value3&.....name10=value10 void ProcQuery(char *cp) { char* arg; char* name; float val=0.0; char *s = strtok(cp,"&"); //s = name,value pair into s while(s != NULL) { name = s; arg = strchr(s,'='); *arg = (char)NULL; arg++; sscanf(arg,"%f",&val); if (strcmp(name,"ele") == 0) elements = (int)val; if (strcmp(name,"rip") == 0) ripple = (double)val; if (strcmp(name,"fzmc") == 0) FZGC = (double)val/1000; if (strcmp(name,"bwmc") == 0) BWMC = (double)val; if (strcmp(name,"R") == 0) R = (double)val; if (strcmp(name,"H") == 0) H = (double)val; if (strcmp(name,"D") == 0) D = val; if (strcmp(name,"E" ) == 0) E =(double)val; if (strcmp(name,"NFR") == 0) NFR = (int)val; if (strcmp(name,"STP") == 0) STP = (double)val; s = strtok(NULL,"&"); //get next name,value pair } } //------------------------------------------------------------- void SendForm(void) { cout << "
" << "

Design a custom Interdigital Bandpass Filter

" << instructions << "

Number of elements" << "
Ripple in DB " << "
Center Frequency in MHZ " << "
Bandwidth in MHZ" << "
I/O Impedance in OHMS" << "
Ground plane space in INCHES" << "
Rod diameter in INCHES" << "
End plate to rod in INCHES" << "
Points to graph (max = 40) " << "
Frequency step size in MHZ" << "

" << "


" << "
" << endl; } //----------------------------------------------------------- //This is a http CGI program. Input is from the environment variable QUERY_STRING. int main(int argc, char *argv[]) { char *cp; char *query_string = getenv("QUERY_STRING"); if (query_string == NULL) query_string = ""; cout << "Content-type: text/html" << endl << endl << "Interdigital Bandpass Filter Designer" << "" ; if (strlen(query_string) == 0) { SendForm(); } else { ProcQuery(query_string); //Parse the query string cp = Validate(); //validate user input if ( cp == NULL) { cout << "
\n";
              Compute();               //Compute filter dimensions
              cout << "
\n"; } else cout << "

Invalid data entered: " << cp << " error

\n"; } cout << "" << flush; return 0; }