Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. #!/usr/bin/env python
  2.  
  3.  
  4. e12=[1.0, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2.0, 2.2, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.3, 4.7, 5.1, 5.6, 6.2, 6.8, 7.5, 8.2, 9.1];
  5.  
  6.  
  7. def calc_rdiv(vo=None, vup=None, vdn=None, rup=None, rdn=None):
  8.  
  9.         args = {'vo':vo, 'vup':vup, 'vdn':vdn, 'rup':rup, 'rdn':rdn}
  10.  
  11.  
  12.         # only 2 'None' args otherwise failure
  13.         # only ints and floats, otherwise failure
  14.         none_nums = 0
  15.         for a in args:
  16.                 a_arg = args[a]
  17.  
  18.                 if a_arg==None:
  19.                         none_nums += 1
  20.                 else:
  21.                         if not isinstance(a_arg,float):
  22.                                 assert isinstance(a_arg,int)
  23.  
  24.                                 args[a] = float(a_arg)
  25.                                 continue
  26.         assert none_nums==2;
  27.  
  28.         # there might be a conversion from ints to floats, so reload args
  29.         vo =  args['vo']
  30.         vup = args['vup']
  31.         vdn = args['vdn']
  32.         rup = args['rup']
  33.         rdn = args['rdn']
  34.  
  35.         # there should be at least one resistance value given, otherwise no way to select both
  36.         assert rdn!=None or rup!=None;
  37.  
  38.  
  39.         result=args
  40.  
  41.         # when both resistances are known
  42.         if rup!=None and rdn!=None:
  43.  
  44.                 if vo!=None:
  45.                         i = vo/(rup+rdn)
  46.                         result['vup'] = i*rup;
  47.                         result['vdn'] = i*rdn;
  48.                         return result
  49.                 elif vup!=None:
  50.                         i = vup/rup
  51.                         vdn = i*rdn
  52.                         vo = vup+vdn
  53.                         result['vdn']=vdn
  54.                         result['vo'] =vo
  55.                         return result
  56.                 elif vdn!=None:
  57.                         i = vdn/rdn
  58.                         vup = i*rup
  59.                         vo = vup+vdn
  60.                         result['vup']=vup
  61.                         result['vo'] =vo
  62.                         return result
  63.         # any r unknown
  64.         elif rup==None or rdn==None:
  65.                 # restore voltages
  66.                 if vo==None:
  67.                         vo=vdn+vup
  68.                         result['vo']=vo
  69.                 elif vup==None:
  70.                         vup=vo-vdn;
  71.                         result['vup']=vup
  72.                 elif vdn==None:
  73.                         vdn=vo-vup
  74.                         result['vdn']=vdn
  75.  
  76.                 # recalc resistor values
  77.                 if rup==None:
  78.                         i=vdn/rdn
  79.                         rup = vup/i
  80.                         result['rup']=rup
  81.                         return result
  82.                 elif rdn==None:
  83.                         i=vup/rup
  84.                         rdn = vdn/i
  85.                         result['rdn']=rdn
  86.                         return result
  87.  
  88.         # we shouldn't be here
  89.         assert False
  90.  
  91.  
  92. def select_nearest(r):
  93.  
  94.         global e12;
  95.  
  96.  
  97.         exp=1.0;
  98.  
  99.         # select range
  100.         if r < min(e12):
  101.                 while r < min(e12):
  102.                         if r < max(e12)/10.0:
  103.                                 r = r*10.0;
  104.                                 exp = exp * 0.1;
  105.                         else:
  106.                                 break;
  107.         elif r > max(e12):
  108.                 while r > max(e12):
  109.                         if r > min(e12)*10.0:
  110.                                 r = r/10.0;
  111.                                 exp = exp * 10.0;
  112.                         else:
  113.                                 break;
  114.  
  115.  
  116.         # select nearest values
  117.         e12_a = [0.91]+e12+[10.0];
  118.         for i in range(len(e12_a)-1):
  119.                 rdn = e12_a[i];
  120.                 rup = e12_a[i+1];
  121.                 if rdn<=r and r<=rup:
  122.                         break;
  123.  
  124.         return (rdn*exp, rup*exp);
  125.  
  126. def select_lo(r):
  127.         x = select_nearest(r);
  128.         return x[0];
  129.  
  130. def select_hi(r):
  131.         x = select_nearest(r);
  132.         return x[1];
  133.  
  134. def r_fix(r,r_e24):
  135.         # select parallel or series additional resistor for r to be closest to r_e24
  136.         if r>=r_e24: # series
  137.                 r_exact = r-r_e24
  138.                 (rlo,rhi)=select_nearest(r_exact)
  139.                 if abs(r_exact-rlo)<abs(r_exact-rhi):
  140.                         return (r_e24+rlo,rlo,'series')
  141.                 else:
  142.                         return (r_e24+rhi,rhi,'series')
  143.  
  144.         else: # parallel (r<r_e24)
  145.                 r_exact = 1.0/(1.0/r - 1.0/r_e24)
  146.                 (rlo,rhi)=select_nearest(r_exact)
  147.                 r_rlo = 1.0/(1.0/r_e24+1.0/rlo)
  148.                 r_rhi = 1.0/(1.0/r_e24+1.0/rhi)
  149.                 if abs(r_rlo-r)<abs(r_rhi-r):
  150.                         return (r_rlo,rlo,'parallel')
  151.                 else:
  152.                         return (r_rhi,rhi,'parallel')
  153.  
  154.  
  155.  
  156. def main():
  157.        
  158.         global e12;
  159.  
  160.         vref=2.5;
  161.         vo=6.0;
  162.  
  163.         print("\n>>> :: Vref={}, Vout={}\n".format(vref,vo))
  164.  
  165.         variants=[]
  166.  
  167.         for rdn in e12:
  168.                 r = calc_rdiv(vo=vo, vdn=vref, rdn=rdn)
  169.                 rup = r['rup'] 
  170.  
  171.                 rup_lo = select_lo(rup);
  172.                 rup_hi = select_hi(rup);
  173.  
  174.                 print("rdn_e12={}, rup_exact={}".format(rdn,rup));
  175.  
  176.                 r=calc_rdiv(vdn=vref,rdn=rdn,rup=rup_hi)
  177.                 vo_hi = r['vo']
  178.                 print("\trup_hi={}, vo={}".format(rup_hi,vo_hi))
  179.                 variants += [(rdn,rup_hi,vo_hi)]
  180.  
  181.                 fix=r_fix(rup,rup_hi)
  182.                 r=calc_rdiv(vdn=vref,rdn=rdn,rup=fix[0])
  183.                 print("\t\trup {} {} {}, vo={}".format(fix[1],fix[2],rup_hi,r['vo']))
  184.                 variants += [(rdn,'{} {} {}'.format(fix[1],fix[2],rup_hi),r['vo'])]
  185.  
  186.                 r=calc_rdiv(vdn=vref,rdn=rdn,rup=rup_lo)
  187.                 vo_lo = r['vo']
  188.                 print("\trup_lo={}, vo={}".format(rup_lo,vo_lo))
  189.                 variants += [(rdn,rup_lo,vo_lo)]
  190.  
  191.                 fix=r_fix(rup,rup_lo)
  192.                 r=calc_rdiv(vdn=vref,rdn=rdn,rup=fix[0])
  193.                 print("\t\trup {} {} {}, vo={}".format(fix[1],fix[2],rup_lo,r['vo']))
  194.                 variants += [(rdn,'{} {} {}'.format(fix[1],fix[2],rup_lo),r['vo'])]
  195.  
  196.  
  197.  
  198.         # sort by best approximaation
  199.         variants.sort(key = lambda tup: abs(tup[2]-vo))
  200.  
  201.         for i in variants:
  202.                 print(i)
  203.  
  204.  
  205. if __name__=="__main__":
  206.         main()
  207.  
  208.