Lab 12 - Filter Design: Nikki Tran ECE 351 05/02/2019
Lab 12 - Filter Design: Nikki Tran ECE 351 05/02/2019
Nikki Tran
ECE 351
05/02/2019
Introduction
In this project, we are building a filter for a given noisy signal. The noise from this signal is generated from low
and high frequencies.
Deliverables
1. Identify the noise magnitudes and corresponding frequencies from low frequency vibration and
switching amplifier. Also identify the magnitudes and corresponding frequencies of the position
measurement information.
df = pd.read_csv('NoisySignal.csv')
t = df['0'].values
sensor_sig = df['1'].values
plt.figure(figsize=(15,12))
plt.subplot(3,1,1)
plt.plot(t,sensor_sig)
plt.grid(True)
plt.title('Noisy Input Signal')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude (V)')
plt.show()
In order to find the sampling frequency, fs , for the FFT, we know that the data in the NoisySignal.csv file is
plotted in time increments. Since t = 1/f , the sampling frequency can be determined by finding the step size of
the time increments.
0.0 1e-06
1
fs =
−6
10
fs = 1M H z
In [5]: import numpy as np
import scipy.fftpack
import matplotlib.pyplot as plt
x = sensor_sig
fs = 1/t[1]
def make_stem(ax,x,y,color='k',style='solid',label='',linewidths=1.5,**kwargs
):
ax.axhline(x[0],x[-1],0,color='r')
ax.vlines(x,0,y,color=color,linestyles=style,label=label,linewidths=linewi
dths)
ax.set_ylim([1.05*y.min(),1.05*y.max()])
def fft(x,fs):
N = len(x)
x_fft = scipy.fftpack.fft(x)
x_fft_shifted = scipy.fftpack.fftshift(x_fft)
freq = np.arange(-N/2,N/2) * fs/N
x_mag = abs(x_fft_shifted) / N
x_phi = np.angle(x_fft_shifted)
for i in range(len(x_mag)):
if(x_mag[i]<1e-10):
x_phi[i]=0
fix, ax = plt.subplots(figsize=(12,8))
make_stem(ax,freq,x_mag)
plt.xlim(1,1e5)
plt.grid(True)
plt.xscale('log')
plt.show()
As we can see, the lower frequency noise is around 60H z with a magnitude of 0.75V and the high frequency
noise is at [20, 30, 50, 70, 90, 100]kH z with a magnitude of [0.25, 0.15, 0.75, 0.18, 0.22, 0.15]V ,
respectively.
We can also see that the information signal is at the [1.8, 1.85, 1.9, 1.95, 2]kH z range with a magnitude of
[1.3, 0.75, 0.9, 0.78, 1]V , respectively.
Looking at our signal, we can guess that the center frequency, fc = 1900H z. Since the signal is in the range of
[1.8, 2]kH z, our lower frequency, fL = 1800H z, and our higher frequency, fH = 2000H z.
The filter will be a bandpass filter because we only want to allow signals through the stated frequencies through.
Using the following transfer function, we can solve for the passive component values.
1
s
RC
H (s) =
2 1 1
s + s +
RC LC
We know that:
1
= β
RC
= ωH − ωL
= 2π(fH − fL )
= 2π(200)
1
= 1256.637
RC
Let
R = 1kΩ
then
1
C =
R ∗ 1256.637
C = 83.76575952pF
We know that:
1
2
= ωc
LC
2
= (2πfc )
2
= (2π1900)
1
= 142517087.6
LC
1
L =
C ∗ 142517087.6
L = 83.76575952mH
Since we want realistic passive components, we can round the values calculated such that:
To see if this filter does work, we check the signal once filtered as well as the Fourier transform of the signal.
R = 1000
C = 84e-9
L = 84e-3
steps = 1e2
w = np.arange(10**3,10**6+steps,steps)
num = [0,1/(R*C),0]
den = [1,1/(R*C),1/(L*C)]
x = np.zeros(w_bode.shape)
y = np.zeros(w_bode.shape)
z = np.zeros(w_bode.shape)
for i in range(len(w_bode)):
w_bode[i] = w_bode[i]/(2*np.pi)
x[i] = -0.3
y[i] = -30
z[i] = -21
myFigSize=(12,10)
plt.figure(figsize=myFigSize)
plt.subplot(2,1,1)
plt.semilogx(w_bode,mag_bode)
plt.semilogx(w_bode,x,label='-0.3 dB')
plt.semilogx(w_bode,y,label='-30 dB')
plt.semilogx(w_bode,z,label='-21 dB')
plt.legend(loc='lower right')
plt.grid(True)
plt.ylabel('|H(jw)| (dB)')
plt.title('Part 1 - Task 2')
plt.subplot(2,1,2)
plt.semilogx(w_bode,phase_bode)
plt.grid(True)
plt.ylabel('<H(jw) (deg)')
plt.xlabel('f (Hz)')
C:\Users\nikki\Anaconda3\lib\site-packages\scipy\signal\filter_design.py:155
1: BadCoefficients: Badly conditioned filter coefficients (numerator): the re
sults may be meaningless
"results may be meaningless", BadCoefficients)
y_out = sig.lfilter(num_filt,den_filt,sensor_sig)
myFigSize=(12,10)
plt.figure(figsize=myFigSize)
plt.subplot(3,1,1)
plt.plot(t,y_out)
plt.grid(True)
plt.ylabel('Filtered Signal')
plt.xlabel('t')
Out[41]: Text(0.5,0,'t')
As you can see, there is no noise and the signal is smoothed out.
In [47]: freq, y_mag, y_phi = fft(y_out,fs)
x = np.zeros(freq.shape)
for i in range(len(freq)):
x[i] = 0.05
fix, ax = plt.subplots(figsize=(12,8))
make_stem(ax,freq,y_mag)
plt.xlim(1,1e5)
plt.xscale('log')
plt.grid('True')
plt.plot(freq,x,label='0.05V')
plt.legend(loc='lower right')
plt.show()
C:\Users\nikki\Anaconda3\lib\site-packages\matplotlib\cbook\deprecation.py:10
7: MatplotlibDeprecationWarning: Passing one of 'on', 'true', 'off', 'false'
as a boolean is deprecated; use an actual boolean (True/False) instead.
warnings.warn(message, mplDeprecation, stacklevel=1)
In the Fourier transform, the lower and higher frequency noise has been attenuated such that it is cancelled out.
The magnitude of the information signal also remains almost unchanged, which means the attenuation is very
close to −3dB.
Conclusion
This project was very insightful on seeing how all the components of the previous lab and the lecture worked
together in terms of application. Creating the filter leaves it up to the engineer because you have a lot of
variables to work with such as the passive component values. While this may not be all that is required of an
actual filter, it is helpful to see how you can go about creating a basic filter. This knowledge can be applied to all
types of filters and all types of circuits, which I think is very helpful.