Subversion Repositories pentevo

Rev

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