// BODE.C - draws bode plots for RC filter circuits // #include #include #include #include #include "n:/course/elec/include/gfxlib1.h" void draw_axes(void) { int x; char label[5]; cleardevice(); // clear the screen moveto(0,0); setcolor(GREEN); // vertical gridlines for(x=120; x<=600; x+=120) { line(20+x,450,20+x,40); } // horizontal gridlines for (x=0; x<=400; x+=80) { line(15,40+x,620,40+x); } setcolor(YELLOW); line(15,40,620,40); // x-axis line(20,40,20,450); // y-axis for (x=0; x>=-50; x-=10) { sprintf(label,"%d",x); outtextxy(0,(x*-8)+42,label); } outtextxy(20,455,"10"); outtextxy(140,455,"100"); outtextxy(260,455,"1k"); outtextxy(380,455,"10k"); outtextxy(500,455,"100k"); outtextxy(620,455,"1M"); outtextxy(10,10,"Transfer Function dBV"); outtextxy(280,470,"Frequency Hz"); setcolor(WHITE); } double calculate_value(double r, double c, double freq) { double output; // raw value for transfer function double output_dB; //20 log10 of output output=sqrt(1/(1+pow(2*M_PI*freq,2)*pow(c,2)*pow(r,2))); output_dB=20*log10(output); //printf("Frequency=%lf o/p=%lf dB=%lf\n", freq, output, output_dB); return output_dB; } void plot_value(double logfreq, double output_dB) { int xpoint, ypoint; static int oldx=-1, oldy=-1; if (logfreq==-1 && output_dB==-1) // special case to reset old variables... { oldx=-1; oldy=-1; logfreq=1; output_dB=0; } xpoint=20+((logfreq-1)*120); // scale frequency value to axis setcolor(WHITE); if (output_dB>0) // constrain top end of dB axis { output_dB=0; setcolor(YELLOW); } if (output_dB<-50) { output_dB=-50; // constrain bottom end of dB axis setcolor(GREEN); } ypoint=(output_dB*-8)+40; // scale dB value to axis if (oldx!=-1 && oldy!=-1) { line(oldx,oldy,xpoint,ypoint); } oldx=xpoint; oldy=ypoint; } void get_values(char *r_str, char*c_str) { printf("Welcome to the RC Bode Plotter\n\n"); printf("Please enter component values. You may use engineering\n"); printf("(M, k, m, u, n, p) suffixes to your values.\n\n"); printf("For example, 100pF may be entered as 100p\n\n"); printf("Please enter a value for the resistance "); scanf("%s" ,r_str); printf("\nPlease enter a value for the capacitance "); scanf("%s", c_str); return; } double eng_to_float(char *input) { int length; char number[20]; double output=0; double multiplier=1; length=strlen(input); switch (input[length-1]) { case 'M' : multiplier=1E6; break; case 'k' : multiplier=1E3; break; case 'm' : multiplier=1E-3; break; case 'u' : multiplier=1E-6; break; case 'n' : multiplier=1E-9; break; case 'p' : multiplier=1E-12; break; } if (multiplier!=1) { strncpy(number,input,length-1); number[length-1]=0; } else strcpy(number,input); // printf("Number=%s, Multiplier=%lf",number, multiplier); output=atof(number)*multiplier; return output; } int main(void) { // declare variables double freq; // frequency double logfreq; // logarithm of frequency (to base 10) double r; // resistance double c; // capacitance double breakfreq; // break frequency double output; // raw value for transfer function double output_dB; //20 log10 of output char r_str[20]; //string value of R char c_str[20]; //string value of C char labels[80]; char quit; // endprogram = FALSE int endprogram = 0; // while (endprogram is FALSE) while (endprogram==0) { // initialise variables logfreq=0; // read in component values get_values(r_str, c_str); //printf("R=%s C=%s", r_str, c_str); // Process component values r=eng_to_float(r_str); c=eng_to_float(c_str); //printf("r=%lf c=%lf", r,c); //while(!(kbhit())); //r=1E4; //c=1E-7; // Go to graphics mode & draw axes graphics_on(); draw_axes(); breakfreq=1/(2*M_PI*r*c); // calculate break frequency // put some labels on! sprintf(labels, "R=%s, C=%sF, Break frequency=%.0lf Hz",r_str, c_str,breakfreq); outtextxy(200,10,labels); // reset the plot... plot_value(-1,-1); // for (increasing values of frequency until we reach 1MHz) for(logfreq=1; logfreq<=6; logfreq+=0.1) { // calculate the value at this point freq=pow(10,logfreq); output_dB=calculate_value(r,c,freq); // draw the line plot_value(logfreq,output_dB); // end of the above loop } // ask user if they want to do it again outtextxy(150,25,"Draw another plot ? Press y for yes or any other key to exit."); quit=getch(); // if no, endprogram = TRUE if(quit=='y' || quit=='Y') endprogram=0; else endprogram=1; // quit! // graphics off graphics_off(); // end of main while loop } // deinitialise variables & clear up // that's all, folks! return 0; }