EECalc

This light-weight Electronics Engineering Calculator app is pretty neat and good. It works on many platforms such as Android, Linux, and Windows. The app contains every calculator found on the calculator page on this site. The android version is not on google play yet, and I don’t know if it ever will. You can download the apk file and open it up on your Android File Manager. The file manager on my phone was called “Downloads”. Also, did I mention EECalc is open source written for Delphi or FreePascal?

Program eecalc;
//Android apk package com.delphieecalc
Uses sysutils,classes,math;
{$DEFINE Android}//Define that the os is android.

{$IFDEF Android}
const data_dir='/storage/emulated/0/eecalc.dir';
{$ENDIF}
{$IFNDEF Android}
const data_dir='eecalc.dir';
{$ENDIF}
{$IFDEF Windows}
//dont forget to compile it as a console app. use $APPTYPE Compiler Directive.
const dir_char='\';
{$ENDIF}
{$IFNDEF Windows}
const dir_char='/';
{$ENDIF}
Type 
  TEECommand = Record
    proc: tprocedure;
    help: string;
    percentage: extended;
  End;
  PEECommand = ^TEECommand;
  TMetricExponent = -12..12;

Const number_fmt = '#,###.000';

Var command: string;
  commands: tstringlist;
  cmd: peecommand;

Function getNumber(msg:String;Var y:extended): boolean;

Var s: string;
  expo: tmetricexponent;
  noExpo: boolean;
Begin
  s := '';
  noExpo := false;
  write(msg,':');
  readln(s);
  s := trim(s);
  expo := 0;
  If length(s)>0 Then
    Case s[length(s)] Of 
      'p','P': expo := -12;
      'n','N': expo := -9;
      'u','U': expo := -6;
      'm': expo := -3;
      'k','K': expo := 3;
      'M': expo := 6;
      'g','G': expo := 9;
      't','T': expo := 12;
      Else noexpo := true;
    End;
  If Not noexpo Then delete(s,length(s),1);
  y := strtofloatdef(trim(s),0)*power(10,expo);
  getNumber := (y=0);
End;

Procedure displayNumber(name:String;x:extended);

Var y: string;
  C: char;
  expo: tmetricexponent;
Begin
  expo := -12;
  If x>=power(10,-9)Then expo := -9;
  If x>=power(10,-6)Then expo := -6;
  If x>=power(10,-3)Then expo := -3;
  If x>=1 Then expo := 0;
  If x>=power(10,3)Then expo := 3;
  If x>=power(10,6)Then expo := 6;
  If x>=power(10,9)Then expo := 9;
  If x>=power(10,12)Then expo := 12;
  Case expo Of 
    -12: C := 'p';
    -9: c := 'n';
    -6: c := 'u';
    -3: c := 'm';
    0: c := ' ';
    3: c := 'k';
    6: c := 'M';
    9: c := 'G';
    12: c := 'T';
  End;
  writeln(name,':',formatfloat(number_fmt,x/power(10,expo)),c);
End;
Function divide(n,d:extended): extended;
Begin
  divide := 0;
  If d=0 Then
    Begin
      writeln(' Divide by 0 error');
      exit;
    End;
  divide := n/d;
End;

Function CommandPercentage(s1,s2:String): extended;

Var i: integer;
Begin
  commandpercentage := 0;
  For i :=1 To min(length(s1),length(s2)) Do
    If lowercase(s1[i])=lowercase(s2[i]) Then
      commandpercentage := commandpercentage+1;
  commandpercentage := (commandpercentage/length(s2))*100;
End;

Procedure VDivide;

Var vin,vout,r1,r2: extended;
Begin
  writeln('Leave one answer blank,except for voltage in');
  getnumber('Voltage In',vin);
  getnumber('Voltage Out',vout);
  getnumber('R1',r1);
  getnumber('R2',r2);
  If vout=0 Then
    Begin
      vout := divide(r2,r1+r2)*vin;
      displaynumber('Voltage Out',vout);
      exit;
    End;
  If r1=0 Then
    Begin
      r1 := divide(vin,vout)*r2;
      displaynumber('R1',r1);
      exit;
    End;
  r2 := r1*divide(1,divide(vin,vout)-1);
  displaynumber('R2',r2);
End;

Procedure monostable;

Var r,kt,c,t: extended;
  k,ts: string;
  sec: tdatetime;
Begin
  sec := encodetime(0,0,1,0);
  write('Enter Time constant(number or t for 555 timer or q for transistor):');
  k := '0';
  readln(k);
  kt := strtofloatdef(k,0);
  If (kt=0)And(length(k)>0)Then
    Case trim(k)[1] Of 
      't','T': kt := 1.1;
      'q','Q': kt := 0.7;
    End;
  If kt<=0 Then
    Begin
      writeln('Constant must be a number and > 0 or a defines letter');
      exit;
    End;
  Writeln('Leave one answer blank');
  getnumber('Enter Period(in seconds)',t);
  getnumber('Enter Resistance',r);
  getnumber('Enter Capacitance',c);
  If t=0 Then
    Begin
      t := r*c*kt;
      writeln('Duration: '+formatdatetime('hh:mm:ss',t*sec));
      displaynumber('Time Period',t);
    End;
  If r=0 Then displaynumber('Resistance',divide(t/sec,kt*c));
  If c=0 Then displaynumber('Capacitance',divide(t/sec,r*kt));
End;

Function prompt: boolean;

Var index,i: integer;
Begin
  write('EECalc>');
  readln(command);
  prompt := (uppercase(trim(command))<>'EXIT');
  If Not prompt Then exit;
  index := -1;
  For i:= 0 To commands.count-1 Do
    Begin
      cmd := pointer(commands.objects[i]);
      If commandpercentage(command,commands[i])>=cmd^.percentage Then index := i;
    End;
  If index=-1 Then
    Begin
      writeln('Bad command');
      exit;
    End;
  cmd := pointer(commands.objects[index]);
  cmd^.proc;
End;

Procedure help;

Var i: integer;
Begin
  writeln('Heres all ',commands.count,' commands:');
  For i:= 0 To commands.count-1 Do
    Begin
      cmd := pointer(commands.objects[i]);
      writeln(commands[i],' ',cmd^.help);
    End;
  writeln;
  writeln('All commands have no parameters');
End;

Procedure adc;

Var v,vref: extended;
  s: string;
  n,a: integer;
Begin
  getnumber('Voltage Referemce',vref);
  write('Enter Number Of Bits:');
  readln(s);
  n := strtointdef(s,0);
  writeln('Leave One answer blank');
  S := '';
  write('Enter Analog Value:');
  readln(s);
  a := strtointdef(s,-1);
  If a>-1 Then
    Begin
      displaynumber('Voltage Out',a*Divide(vref,power(2,n)-1));
      exit;
    End;
  write('Enter Voltage:');
  s := '';
  readln(s);
  v := strtofloatdef(s,-1);
  a := trunc(divide(power(2,n)-1,vref)*v);
  writeln('Analog Value: ',a);
End;

Procedure combo;

Var x,y: extended;
  count: integer;
Begin
  y := 0;
  count := 1;
  writeln('Enter a blank value when done');
  While Not getNumber(format('Value#%d',[count]),x) Do
    Begin
      y := y+x;
      inc(count);
    End;
  displaynumber('Result',y);
End;

Procedure fuses;

Const fusearray: array[1..16] Of extended = (30,25,20,15,10,8,6,5,4,3,2.5,2,1.5,1,0.5,0.25);

Var i,index: integer;
  currentfuse,volts,amps,watts: Extended;
Begin
  index := 0;
  getnumber('Enter Voltage',volts);
  getnumber('Enter Amps',amps);
  watts := volts*amps;
  currentfuse := (watts/volts)*1.25;
  For i:=1 to 16 Do
    If fusearray[i]>currentfuse Then index := i;
  If index = 0 Then
    Begin
      writeln('Fuse not found');
      exit;
    End;
  writeln('Fuse Rating: '+formatfloat('0.0',fusearray[index])+'A');
End;

Procedure recipcombo;

Var x,y: extended;
  count: integer;
Begin
  y := 0;
  count := 1;
  writeln('Enter a blank value when done');
  While Not getNumber(format('Value#%d',[count]),x) Do
    If x>0 Then
      Begin
        inc(count);
        y := y+(1/x);
      End;
  displaynumber('Result',divide(1,y));
End;

Procedure ohmslaw;

Var v,a,r,w: extended;
  s: string;
Begin
  v := 0;
  a := 0;
  r := 0;
  writeln('Leave one answer blank');
  getnumber('Enter Voltage',v);
  getNumber('Enter Current',a);
  If a*v>0 Then
    Begin
      r := divide(v,a);
      w := v*a;
      displaynumber('Resistance',r);
      displaynumber('Power',w);
      exit;
    End;
  getnumber('Enter Resistance',r);
  If v=0 Then
    Begin
      v := a*r;
      displaynumber('Voltage',v);
    End;
  If a=0 Then
    Begin
      a := divide(v,r);
      displaynumber('Curent',a);
    End;
  w := v*a;
  displaynumber('Power',w);;
End;

procedure Astable;
var r1,r2,c,f,hit,lot:extended;
begin
	getnumber('Enter R1',r1);
	getnumber('Enter R2',r2);
	getnumber('Enter Capacitance',c);
	f:=divide(1,ln(2)*c*(r1+2*r2));
	hit:=divide(1,f);
	lot:=ln(2)*c*r2;
	displaynumber('Frequency',f);
	displaynumber('High Time',hit);
	displaynumber('Low Time',lot);	
end;

Procedure AmpHours;

Var t,ch: tdatetime;
  a,ah: extended;
  S: string;
Begin
  ch := encodetime(1,0,0,0);
  getnumber('Enter Amp Hour Rating',ah) ;
  getNumber('Enter Load',a);
    t := ch*(ah/a);
  writeln('Duration: ',trunc(t),' days, ',formatdatetime('hh:mm:ss',t));
End;

Procedure ledcalc;

Var vin,vf,af,r: extended;
  s: string;
Begin
  getnumber('Enter Voltage In',vin);
  getnumber('Enter Forward Voltage Drop',vf);
  s := '';
  write('Enter current in mA:');
  readln(s);
  af := strtofloatdef(s,0);
  r := divide(vin-vf,af*0.001);
  displaynumber('Resistance',r);
  displaynumber('Power',sqr(af*0.001)*r);
End;

Procedure creact;
Var xc,c,f: extended;
Begin
  writeln('Leave one value blank');
  getnumber('Reactance(Xc)',xc);
  getnumber('Capacitance',c);
  getnumber('Frequency',f);
  If xc=0 Then displaynumber('Reactance',divide(1,pi*2*f*c));
  If c=0 Then displaynumber('Capacitance',divide(divide(1,xc),pi*2*f));
  If f=0 Then displaynumber('Frequency',divide(divide(1,xc),2*pi*c));
End;

procedure lreact;
var xl,f,l:extended;
begin
writeln('Leave one answer blank');
getnumber('Reactance(Xl)',xl);
  getnumber('Inductance',l);
  getnumber('Frequency',f);
  If xl=0 Then displaynumber('Reactance',pi*2*f*l);
  If l=0 Then displaynumber('Inductance',divide(xl,2*pi*f));
  If f=0 Then displaynumber('Frequency',divide(xl,2*pi*l));
End;

Procedure rcode;

Type tcolorcode = Record
  digit: byte;
  multipler,tolerance: extended;
End;
PColorCode = ^TColorCode;

Var scode: string;
  y,tolerance: extended;
  colors: tstringlist;
  i: integer;
  pcc: pcolorcode;
  bands: array[1..5] Of pcolorcode;
Begin
  colors := tstringlist.create;
  new(pcc);
  pcc^.digit := 0;
  pcc^.multipler := 1;
  pcc^.tolerance := 0;
  colors.addobject('Black',tobject(pcc));
  new(pcc);
  pcc^.digit := 1;
  pcc^.multipler := 10;
  pcc^.tolerance := 1;
  colors.addobject('Brown',tobject(pcc));
  new(pcc);
  pcc^.digit := 2;
  pcc^.multipler := 100;
  pcc^.tolerance := 2;
  colors.addobject('Red',tobject(pcc));
  new(pcc);
  pcc^.digit := 3;
  pcc^.multipler := 1000;
  pcc^.tolerance := 0;
  colors.addobject('Orange',tobject(pcc));
  new(pcc);
  pcc^.digit := 4;
  pcc^.multipler := 10000;
  pcc^.tolerance := 0;
  colors.addobject('Yellow',tobject(pcc));
  new(pcc);
  pcc^.digit := 5;
  pcc^.multipler := 100000;
  pcc^.tolerance := 0.5;
  colors.addobject('Green',tobject(pcc));
  new(pcc);
  pcc^.digit := 6;
  pcc^.multipler := 1000000;
  pcc^.tolerance := 0.25;
  colors.addobject('Blue',tobject(pcc));
  new(pcc);
  pcc^.digit := 7;
  pcc^.multipler := 10000000;
  pcc^.tolerance := 0.1;
  colors.addobject('Violet',tobject(pcc));
  new(pcc);
  pcc^.digit := 8;
  pcc^.multipler := 100000000;
  pcc^.tolerance := 0.05;
  colors.addobject('Gray',tobject(pcc));
  new(pcc);
  pcc^.digit := 9;
  pcc^.multipler := 1000000000;
  pcc^.tolerance := 0;
  colors.addobject('White',tobject(pcc));
  new(pcc);
  pcc^.digit := 10;
  pcc^.multipler := 0.1;
  pcc^.tolerance := 5;
  colors.addobject('Gold',tobject(pcc));
  new(pcc);
  pcc^.digit := 10;
  pcc^.multipler := 0.01;
  pcc^.tolerance := 10;
  colors.addobject('Silver',tobject(pcc));
  writeln('Enter its code with the following digit, including tolerance digit');
  For i:=0 To colors.count-1 Do
    write(inttohex(i,1),'=',colors[i],',');
  writeln;
  write('Enter 4 or 5 band color code:');
  readln(scode);
  If (length(scode)<>4)And (length(scode)<>5)Then
    Begin
      writeln('No such thing as a ',length(scode),' band resistor');
      exit;
    End;
  For i := 1 To length(scode) Do
    If strtointdef('$'+scode[i],colors.count)>=colors.count Then
      Begin
        writeln('Band#',i,' is not a valid band');
        exit;
      End
    Else bands[i] := pointer(colors.objects[strtoint('$'+scode[i])]);
  If length(scode)=4 Then
    Begin
      If bands[1]^.digit=10 Then
        Begin
          writeln('Misused band 1');
          exit;
        End;
      If bands[2]^.digit=10 Then
        Begin
          writeln('Misused band 2');
          exit;
        End;
      y := ((bands[1]^.digit*10)+bands[2]^.digit)*bands[3]^.multipler;
      tolerance := bands[4]^.tolerance;
    End;
  If length(scode)=5 Then
    Begin
      If bands[1]^.digit=10 Then
        Begin
          writeln('Misused band 1');
          exit;
    
        End;
      If bands[2]^.digit=10 Then
        Begin
          writeln('Misused band 2');
          exit;
        End;
      If bands[3]^.digit=10 Then
        Begin
          writeln('Misused band 3');
          exit;
        End;
      y := ((bands[1]^.digit*100)+(10*bands[2]^.digit)+bands[3]^.digit)*bands[4]^.multipler;
      tolerance := bands[5]^.tolerance;
    End;
  displaynumber('Resistance',y);;
  writeln('Tolerance: ',floattostr(tolerance),'%');
  For i:=0 To colors.count-1 Do
    Begin
      pcc := pointer(colors.objects[i]);
      dispose(pcc);
    End;
  colors.free;
End;

procedure nop;
begin
	//do nothing
end;

function LookForFile(ext:string):string;
var sr:tsearchrec;
filelist:tstringlist;
index,i:integer;
begin
	lookforfile:='?';
	writeln('Files ending with ',ext,' in ',data_dir,' :');
	if findfirst(data_dir+dir_char+'*'+ext,faanyfile,sr)<>0 then exit;
	filelist:=tstringlist.create;filelist.add(Sr.name);
	while findnext(sr)=0 do filelist.add(sr.name);
	for i:=0 to filelist.count-1 do writeln(i,'. ',filelist[i]);
	write('Enter number  or  -1 to cancel: ');
	readln(index);
	findclose(sr);
	if index=-1 then begin filelist.free; exit;end;
	lookforfile:=filelist[index];
	filelist.free;
end;

procedure vreg;
var dv,dvMin,dvmax,vin,vref,vout,r1,r2:extended;
choice,vrgname:string;
vrgfile:tstringlist;
begin
dv:=0;dvmin:=0;dvmax:=0;vref:=0;
vrgfile:=nil;
write('Load settings for LM317(y for yes, n for no, f from a file, or x for exit):');
readln(choice);
if length(choice)=0 then exit;
case choice[1] of
'y','Y':BEGIN dvmin:=3;dvmax:=40;vref:=1.25;end;
'n','N':nop;
'f','F':begin vrgname:=data_dir+dir_char+lookforfile('.vrg');
if not fileexists(vrgname) then begin writeln('File  not found');exit;end;
vrgfile:=tstringlist.create;
vrgfile.loadfromfile(vrgname); vref:=strtofloatdef(vrgfile.values['Vref'],-1);dvmin:=strtofloatdef(vrgfile.values['dvMin'],-1);dvmax:=strtofloatdef(vrgfile.values['dvMax'],-1);
if (vref=-1)or (dvmin=-1) or (dvmax=-1)then begin
	writeln('File is missing some  variables. It needs a Vref, dvMin and a dvMax variable');exit;
end;
vrgfile.free; end;
'x','X':exit;
end;
if dvmin=0 then
if not getnumber('Enter Differnetial Min(or just press enter for no differnetial voltage)',dvmin) then
getnumber('Enter Differnetial Voltage Max',dvmax);
if dvmin*dvmax>0 then getnumber('Voltage In',vin);
if vref=0 then getnumber('Voltage Reference',vref);
getnumber('R1',r1);
writeln('Leave one answer blank');
getnumber('Voltage Out',vout);
getnumber('R2',r2);
if r2=0 then displaynumber('R2',divide(r1*(vout-vref),vref));
if vout=0 then displaynumber('Vout',vref*divide(1+r2,r1));
if vin*dvmin*dvmax>0 then dv:= vin-vout;
if (dv>dvmax)and (vin*dvmin*dvmax>0) then writeln('Input Voltage too high');
if (dv<dvmin)and (vin*dvmin*dvmax>0)then writeln('Warning! Input voltage may be too low');
end;

Begin
  createdir(data_dir);
   writeln('delphijustin EECalc v1.0');
  writeln('For a list of commands type "help"');
  commands := tstringlist.create;
  commands.sorted := true;
new(cmd);
  cmd^.percentage := 100;
  cmd^.help := 'Inductive Reactance';
  cmd^.proc := tprocedure(@lreact);
  commands.addobject('lreact',tobject(cmd));
new(cmd);
  cmd^.percentage := 100*(3/4);
  cmd^.help := 'Voltage Regulator';
  cmd^.proc := tprocedure(@vreg);
  commands.addobject('vreg',tobject(cmd));
        new(cmd);
  cmd^.help := 'Calculates resistor color code';
  cmd^.proc := tprocedure(@rcode);
  cmd^.percentage := 100*(3/5);
  commands.addobject('rcode',tobject(cmd));
  new(cmd);
  cmd^.help := 'Analog Digital Converter';
               cmd^.proc := tprocedure(@adc);
  cmd^.percentage := 100;
  commands.addobject('adc',tobject(cmd));
  new(cmd);
  cmd^.help := 'Starts Ohms law calculator';
  cmd^.proc := tprocedure(@ohmslaw);
  cmd^.percentage := 75;
  commands.Addobject('ohmslaw',tobject(cmd));
  new(cmd);
  cmd^.help := 'Parallel resistance';
  cmd^.proc := tprocedure(@recipcombo);
  cmd^.percentage := 100;
  commands.Addobject('presistor',tobject(cmd));
  new(cmd);
  cmd^.percentage := 100;
  cmd^.help := 'Series capacitance';
  cmd^.proc := tprocedure(@recipcombo);
  commands.Addobject('scap',tobject(cmd));
 new(cmd);
  cmd^.percentage := 100*(3/4);
  cmd^.help :='Fuse rating';
  cmd^.proc := tprocedure(@fuses);
  commands.Addobject('fuse',tobject(cmd));
  new(cmd);
  cmd^.percentage := 100;
  cmd^.help := 'Series resistance';
  cmd^.proc := tprocedure(@combo);
  commands.Addobject('sresistor',tobject(cmd));
  new(cmd);
  cmd^.percentage := 100;
  cmd^.help := 'Parallel capacitance';
  cmd^.proc := tprocedure(@recipcombo);
  commands.Addobject('pcap',tobject(cmd));
  new(cmd);
  cmd^.percentage := 40;
  cmd^.help := 'Calculates duration of a battery';
  cmd^.proc := tprocedure(@amphours);
  commands.Addobject('amphours',tobject(cmd));
  new(cmd);
  cmd^.percentage := 100;
  cmd^.help := 'Capacitive Reactance';
  cmd^.proc := tprocedure(@creact);
  commands.Addobject('creact',tobject(cmd));
  new(cmd);
  cmd^.percentage := 100;
  cmd^.help := 'LED Resistor calculator';
  cmd^.proc := tprocedure(@ledcalc);
  commands.Addobject('led',tobject(cmd));
  new(cmd);
  cmd^.percentage := 100;
  cmd^.help := 'Ends EECalc';
  cmd^.proc := Nil;
  commands.addobject('exit',tobject(cmd));
new(cmd);
  cmd^.percentage := 60;
  cmd^.help :='555 Astable Multivibrator';
  cmd^.proc := tprocedure(@astable);;
  commands.addobject('astable',tobject(cmd)); 
  new(cmd);
  cmd^.help := 'Voltage Divider';
  cmd^.percentage := 100;
  cmd^.proc := tprocedure(@vdivide);
  commands.addobject('vd',tobject(cmd));
  new(cmd);
  cmd^.help := 'Displays this screen';
  cmd^.percentage := 100*(3/4);
  cmd^.proc := tprocedure(@help);
  commands.addobject('help',tobject(cmd));
  new(cmd);
  cmd^.help := 'Monostable multivibrator';
  cmd^.percentage := 75;;
  cmd^.proc := tprocedure(@monostable);
  commands.addobject('mono',tobject(cmd));
  While prompt Do
End.
Icons made by Freepik from www.flaticon.com

Published by Justin Roeder

I am an electronics engineer and computer programmer that has autism. I learned by myself

Leave a comment

Your email address will not be published. Required fields are marked *