Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1221 | lvd | 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 |