#!/usr/bin/env perl

## Series RLC circuits

## This file Copyright 2000 <contact@gbppr.org> under the GPL
## NO WARRANTY. Please send bug reports / patches / reports.

use Math::Complex;

sub Stupid_Diagram {
print "\33[H\33[J".
      "   +------------/\\/\\/\\-----------+                \n".
      "   |                             |                   \n".
      "   |                   R         -  C                \n".
      "   |                             -                   \n".
      "   @ AC Input                    |                   \n".
      "   |                            ( )  L               \n".
      "   |                            ( )                  \n".
      "   |                            ( )                  \n".
      "   |                             |                   \n".
      "   +-----------------------------+                   \n";
printf "     R = %.4f %s                                    \n", $rval, $runit;
printf "     L = %.6f %s                                    \n", $lval, $lunit;
printf "     C = %.6f %s                                    \n", $cval, $cunit;
printf "     Q = %.2f    Bandwidth = %.6f kHz               \n\n", $q, $bw / 1000;
}

sub Print {
printf "            Frequency : %.6f Hz\n".
       "                      : %.6f kHz\n".
       "                      : %.6f MHz\n", $fr, $fr / 1000, $fr / 1000000;
printf "      Total impedance : %.4f ohms\n".
       "  Inductive reactance : %.4f ohms\n".
       "  Capactive reactance : %.4f ohms\n", $zt, $xl, $xc; 
print  "      This circuit is : $react\n\n";
}

sub Cap {
undef $_; undef $c; undef $unit;
while (!m/^([0-9.]+)(u|U|p|P|n|N+)$/) {
        print "\nu = microfarads\n".
	      "n = nanofarads\n".
              "p = picofarads\n\n".
              "Enter value of C  [value][u,n,p]: ";
        chomp($_ = <STDIN>);

if (m/^([0-9.]+)(u|U|p|P|n|N+)$/) {
        $c1 = $1;
        $unit = $2;
}
if ($unit =~ /u/i) {
	 $unit = "microfarads";
         $c = $c1 / 1000000;
}
elsif ($unit =~ /n/i) {
	 $unit = "nanofarads";
         $c = $c1 / 1000000000;
}
elsif ($unit =~ /p/i) {  
	  $unit = "picofarads";
          $c = $c1 / 1000000000000;
  }
 }
}         

sub Res {
undef $_; undef $r; undef $unit;
while (!m/^([0-9.]+)(k|K|m|M|o|O+)$/) {
        print "\nk = kilohms\n".
	      "m = megaohms\n".
	      "o = just ohms\n\n".
	      "Enter value of R  [value][k,m,o]: ";
	chomp($_ = <STDIN>);

if (m/^([0-9.]+)(k|K|m|M|o|O+)$/) {
        $r1 = $1;
        $unit = $2;
}
if ($unit =~ /k/i) {
	$unit = "kilohms";
        $r = $r1 * 1000;
}
elsif ($unit =~ /m/i) {
	$unit = "megaohms";
        $r = $r1 * 1000000;
}
elsif ($unit =~ /o/i) {
	$unit = "ohms";
        $r = $r1;
  } 
 }
}

sub Ind {
undef $_; undef $l; undef $unit;
while (!m/^([0-9.]+)(n|N|m|M|u|U+)$/) {
        print "\nn = nanohenries\n".
	      "u = microhenries\n".
	      "m = millihenries\n\n".
	      "Enter value of L  [value][n,u,m]: ";
	chomp($_ = <STDIN>);

if (m/^([0-9.]+)(n|N|m|M|u|U+)$/) {
        $l1 = $1;
        $unit = $2;
}
if ($unit =~ /n/i) {
	$unit = "nanohenries";
        $l = $l1 / 1000000000;
}
elsif ($unit =~ /u/i) {
       $unit = "microhenries";
       $l = $l1 / 1000000;
}
elsif ($unit =~ /m/i) {
       $unit = "millihenries";
       $l = $l1 / 1000;
  }      
 }
}

sub Freq {
undef $_; undef $fr; undef $unit;
while (!m/^([0-9.]+)(k|K|m|M|h|H+)$/) {
        print "\nk = kilohertz\n".
	      "m = megahertz\n".
	      "h = just hertz\n\n".
	      "Enter frequency  [value][k,m,h]: ";
        chomp($_ = <STDIN>);

if (m/^([0-9.]+)(k|K|m|M|h|H+)$/) {
        $fr = $1;
        $unit = $2;
}                    
if ($unit =~ /k/i) {
        $fr = $fr * 1000;
}
elsif ($unit =~ /m/i) {
        $fr = $fr * 1000000;
}
elsif ($unit =~ /h/i) {
        $fr = $fr;
  }
 }
}              

&Stupid_Diagram;

&Res;
  $rval = $r1;
  $runit = $unit;

print "\n";

while (!$cans) {
	print "Do you need to calculate the value of C? [y|n]: ";
	chomp($cans = <STDIN>);
	$cans =~ tr/ynYN//csd;
}

if ($cans =~ /y/i) {

	&Freq;
	&Ind;
          $lval = $l1;
	  $lunit = $unit;
	
        $xl = 2 * pi * $fr * $l;
	$xc = $xl;
	$c = 1 / (2 * pi * $fr * $xl);
          $cval = $c * 1000000;
	  $cunit = "microfarads";

	printf "\nC is equal to %.6f uF\n", $cval;

	$fr = (1 / (2 * pi * (sqrt ($c * $l))));
	$zt = $r;
	$q = $xl / $r;
	$bw = $fr / $q; 

        &Stupid_Diagram;
        &Print($react = "resonant (Zt = R)");      
	exit;
}

else {

	&Cap;
	  $cval = $c1;
	  $cunit = $unit;
}

print "\n";

while (!$lans) {
        print "Do you need to calculate the value of L? [y|n]: ";
        chomp($lans = <STDIN>);
        $lans =~ tr/ynYN//csd;
}            

if ($lans =~ /y/i) {

        &Freq;

	$xc = 1 / (2 * pi * $fr * $c);
	$xl = $xc;
	
	$l = $xl / (2 * pi * $fr);
	  $lval = $l * 1000000;
	  $lunit = "microhenries";

	printf "\nL is equal to %.6f uH\n", $lval;

	$fr = (1 / (2 * pi * (sqrt ($c * $l))));
	$zt = $r;
	$q = $xl / $r;
	$bw = $fr / $q;

        &Stupid_Diagram;
        &Print($react = "resonant (Zt = R)");   
	exit;
}

else {
	&Ind;
	  $lval = $l1;
	  $lunit = $unit;
}

print "\n";

while (!$fans) {
        print "Do you want to enter your own frequency? [y|n]: ";
	chomp($fans = <STDIN>);
	$fans =~ tr/ynYN//csd;
}           

if ($fans =~ /y/i) {

	&Freq;

        $xl = 2 * pi * $fr * $l;
        $xc = 1 / (2 * pi * $fr * $c);
	$zt = sqrt (($r ** 2) + (($xl - $xc) ** 2));
	$q = $xl / $r;
        $bw = $fr / $q;

	if ($xc > $xl) {
		$react = "capacitive";
	}

	else {
		$react = "inductive";
	}

	&Stupid_Diagram;
	&Print; 
}

else {

	$fr = (1 / (2 * pi * (sqrt ($c * $l))));
	$xl = 2 * pi * $fr * $l;
	$xc = $xl;
	$zt = $r;
	$q = $xl / $r;
	$bw = $fr / $q;

	&Stupid_Diagram;
	&Print($react = "resonant (Zt = R)");
}
