mline-scripts/filter.py

124 lines
3.3 KiB
Python

#!/usr/bin/python3
import numpy as np
import scipy.optimize as opt
import microstrip as ms
def Butterworth(n):
'''
Return koefficents of Butterworth n-th order filter
g0 and gn+1 are assumed to be 1
[g0, g1, ... gn, gn+1] = Buttherworth(n)
'''
gi = 2*np.sin((2*np.arange(1,n+1)-1)*np.pi/2/n)
return np.hstack([1,gi,1])
def Tchebysheff(n, ripple):
'''
Return coefficents of Tchebysheff n-th order filter
with specified ripple in passband.
[g0, g1, ... gn, gn+1] = Tchebysheff(n, ripple)
n <- order of filter
ripple <- ripple in passband (dB)
'''
b = np.log(1/np.tanh(ripple/17.37))
k = np.sinh(b/2/n)
g = np.ones(n+2)
g[1] = 2/k*np.sin(np.pi/2/n)
for i in range(2,n+1):
g[i] = 1/g[i-1]*4*np.sin((2*i-1)*np.pi/2/n)*np.sin((2*i-3)*np.pi/2/n)/\
(k**2+np.sin((i-1)*np.pi/n)**2)
if n % 2 == 0:
g[-1] = 1/np.tanh(b/4)**2
return g
def mclBPF(h, e_r, fbw, gk, f0):
'''
Calculate dimensions of microstrip coupled lines bandpass
filter.
h <- height of substrate (mm)
e_r <- dielectric constant of substrate
fbw <- fractional bandwidth of bpf
gk <- filter coefficents
f0 <- central frequency (GHz)
'''
n = len(gk)-2
J = np.ones(n+1)
J[0] = np.sqrt(np.pi*fbw/2/gk[0]/gk[1])
J[-1] = np.sqrt(np.pi*fbw/2/gk[-2]/gk[-1])
for j in range(1,n):
J[j] = np.pi*fbw/2/np.sqrt(gk[j]*gk[j+1])
Zo = np.zeros(n+1)
Ze = np.zeros(n+1)
for j in range(n+1):
Ze[j] = 50*(1+J[j]+J[j]**2)
Zo[j] = 50*(1-J[j]+J[j]**2)
lambda4 = 3e8/f0/1e9/4 *1e3
W = np.zeros(n+1)
s = np.zeros(n+1)
l = np.zeros(n+1)
for j in range(n+1):
x = ms.get_mcl(Ze[j],Zo[j],h,e_r,f0)
W[j] = x[0]
s[j] = x[1]
dl = ms.open_end(W[j],h,e_r,f0)
eps = ms.mcl_eps(W[j],h,s[j],e_r,f0)
# popravek z upostevanjem disperzije
l[j] = lambda4/np.sqrt(np.sqrt(eps[0]*eps[1]))-dl
#print(l[j])
# popravek s staticnim eps
l[j] = lambda4/np.sqrt(np.sqrt(eps[2]*eps[3]))-dl
#print(l[j])
return {'W':W, 's':s, 'l':l, 'f':f0, 'fbw':fbw}
def prtmclBFP(bfp):
'''
Print filter in readable format
'''
n = len(bfp['W'])
print("Microstrip coupled line bandpass filter:\nAll dimensions in mm.")
print("\tW\ts\tl")
for i in range(n):
print("{}:\t{:.2f}\t{:.2f}\t{:.2f}".format(i+1,bfp['W'][i],\
bfp['s'][i],bfp['l'][i]))
print("Length of filter: {} mm".format(sum(bfp['l'])))
print("Width of filter: {} mm".format(sum(bfp['W'])+sum(bfp['s'])))
if __name__ == '__main__':
gk = Tchebysheff(7,0.05)
#bfp = mclBPF(1.54, 3.66, 0.1, gk, 10.2)
bfp = mclBPF(0.76, 3.66, 0.1, gk, 10.2)
#prtmclBFP(bfp)
print(ms.getWf(50, 0.76, 3.66, 10.2))
print("=== interstage filter za bfp840 ===")
gk = Butterworth(7)
bfp = mclBPF(0.8, 3.66, 0.3, gk, 10.5)
prtmclBFP(bfp)
print("=== interstage filter za bfp840 ===")
gk = Butterworth(5)
bfp = mclBPF(0.8, 3.66, 0.3, gk, 10.5)
prtmclBFP(bfp)
print("=== interstage filter za bfp840 ===")
gk = Butterworth(5)
bfp = mclBPF(0.8, 3.66, 0.05, gk, 10.5)
prtmclBFP(bfp)
print("=== interstage filter za bfp840 ===")
gk = Butterworth(3)
bfp = mclBPF(0.8, 3.66, 0.05, gk, 10.5)
prtmclBFP(bfp)