Rev 1232 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1230 | lvd | 1 | #!/usr/bin/env python |
2 | |||
3 | import sys |
||
4 | from sympy import * |
||
5 | |||
6 | e24 = [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]; |
||
7 | e6 = [1.0, 1.5, 2.2, 3.3, 4.7, 6.8 ]; |
||
8 | |||
9 | |||
10 | |||
11 | def calc_mfb_lowpass(): |
||
12 | |||
1231 | lvd | 13 | # as in sloa049, fig.7-1 |
1233 | lvd | 14 | r1,r2,r3,c1,c2 = symbols('r1 r2 r3 c1 c2', real=True, positive=True) |
1230 | lvd | 15 | |
1231 | lvd | 16 | # v is input voltage, u is output, x is voltage at r1/c2/r2/r3 node |
17 | u,v,x = symbols('u v x') |
||
1230 | lvd | 18 | |
1231 | lvd | 19 | # currents through appropriate elements. |
20 | # ir1,ir2,ir3 flow into the node x, |
||
21 | # ic2 flows out of the node x |
||
22 | ir1,ic2,ir2,ir3 = symbols('ir1,ic2,ir2,ir3') |
||
1230 | lvd | 23 | |
1231 | lvd | 24 | # angular frequency (omega) |
1233 | lvd | 25 | w = symbols('w', real=True, positive=True) |
1230 | lvd | 26 | |
1231 | lvd | 27 | # make set of equations to calculate H |
28 | # |
||
29 | # current through r1 |
||
30 | h_eq1 = Eq( ir1, (v-x)/r1 ) |
||
31 | # |
||
32 | # current through c2 |
||
33 | h_eq2 = Eq( ic2, x/(1/(I*w*c2)) ) |
||
34 | # |
||
35 | # current through r2 |
||
36 | h_eq3 = Eq( ir2, (u-x)/r2 ) |
||
37 | # |
||
38 | # current through r3/c1 |
||
39 | h_eq4 = Eq( ir3, (u-x)/(r3 + 1/(I*w*c1)) ) |
||
40 | # |
||
41 | # node x charge conservation |
||
42 | h_eq5 = Eq( ir1+ir2+ir3, ic2 ) |
||
43 | # |
||
44 | # opamp NFB condition |
||
45 | h_eq6 = Eq( u-ir3*(1/(I*w*c1)), 0 ) |
||
1230 | lvd | 46 | |
1231 | lvd | 47 | # solve the set |
48 | u_solve = solve( [h_eq1, h_eq2, h_eq3, h_eq4, h_eq5, h_eq6], [x,u,ir1,ic2,ir2,ir3], dict=True, domain=S.Complexes ) |
||
1230 | lvd | 49 | |
1231 | lvd | 50 | if len(u_solve)!=1: |
51 | sys.stderr.write("Many or no solutions: {} !\n".format(u_solve)) |
||
52 | exit(1) |
||
53 | |||
54 | u_expr = u_solve[0] |
||
1230 | lvd | 55 | |
1231 | lvd | 56 | h_expr = u_expr[u]/v |
1230 | lvd | 57 | |
1231 | lvd | 58 | print(h_expr) |
1230 | lvd | 59 | |
60 | |||
61 | |||
1231 | lvd | 62 | # now make more substitutions |
63 | # |
||
1233 | lvd | 64 | h = symbols('h') |
65 | k = symbols('k', real=True, negative=True) |
||
66 | q,wc = symbols('q wc', real=True, positive=True) |
||
1231 | lvd | 67 | # |
68 | # filter gain |
||
69 | s_eq1 = Eq( k, -r2/r1 ) |
||
70 | # |
||
71 | # cutoff angular frequency |
||
72 | s_eq2 = Eq( wc, 1/sqrt(r2*r3*c1*c2) ) |
||
73 | # |
||
74 | # quality |
||
1233 | lvd | 75 | s_eq3 = Eq( q, sqrt(r2*r3*c1*c2)/(r3*c1+r2*c1-r3*c1*k) ) |
76 | #s_neq3 = Lt( k, 0 ) |
||
1231 | lvd | 77 | # |
78 | # new H expression |
||
79 | s_eq4 = Eq( h, h_expr ) |
||
1230 | lvd | 80 | |
1231 | lvd | 81 | # solve |
82 | h_solve = solve( [s_eq1, s_eq2, s_eq3, s_eq4], [h, r1, r2, r3, c1, c2], dict=True ) |
||
1230 | lvd | 83 | |
1231 | lvd | 84 | if len(h_solve)!=1: |
85 | sys.stderr.write("Many or no solutions: {} !\n".format(h_solve)) |
||
86 | exit(1) |
||
87 | |||
88 | h_expr = h_solve[0] |
||
89 | h_result = h_expr[h] |
||
90 | |||
1232 | lvd | 91 | init_printing() |
1233 | lvd | 92 | print('') |
1232 | lvd | 93 | pprint(h_expr) |
1233 | lvd | 94 | print('') |
1232 | lvd | 95 | pprint(h_result) |
1231 | lvd | 96 | |
97 | #breakpoint() |
||
98 | |||
99 | |||
100 | |||
101 | |||
1230 | lvd | 102 | def main(): |
103 | |||
104 | calc_mfb_lowpass() |
||
105 | |||
106 | |||
107 | if __name__=="__main__": |
||
108 | main() |
||
109 |