Doorbell, Frequency Domain, 003 Use DFT/FFT approximation to Fourier transform (FT) to estimate frequency domain parameters of the doorbell signal and to move it to baseband. In [1]: # Import the Python modules that we need import numpy as np import matplotlib.pyplot as plt from scipy.signal import lfilter In [2]: %matplotlib notebook fsz = (7, 4) # full figure size fsz2 = (fsz[0],fsz[1]/2.0) # half figure size In [3]: # Read the binary file of one button push (1 sec) and create a time axis name = 'doorbell_001_inclass_r1t' fname = name + '.bin' Fs = int(5e6) rt = np.fromfile(fname, dtype=np.complex64) L= len(rt) tt = np.arange(L)/float(Fs) # time axis in seconds print(L) 5000000 Doorbell_FreqDomain_003 http://localhost:8888/nbconvert/html/Doorbell_FreqDomain_003.ipynb... 1 of 13 10/4/2019, 9:28 AM
13
Embed
Doorbell, Frequency Domain, 003ecee.colorado.edu/.../classnotes/python/Doorbell_FreqDomain_003.pdf · Doorbell, Frequency Domain, 003 Use DFT/FFT approximation to Fourier transform
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Doorbell, Frequency Domain, 003
Use DFT/FFT approximation to Fourier transform (FT) to estimate frequency domain parameters of the doorbell signal and to
move it to baseband.
In [1]: # Import the Python modules that we needimport numpy as npimport matplotlib.pyplot as pltfrom scipy.signal import lfilter
In [2]: %matplotlib notebookfsz = (7, 4) # full figure sizefsz2 = (fsz[0],fsz[1]/2.0) # half figure size
In [3]: # Read the binary file of one button push (1 sec) and create a time axisname = 'doorbell_001_inclass_r1t'fname = name + '.bin'Fs = int(5e6)rt = np.fromfile(fname, dtype=np.complex64)L = len(rt)tt = np.arange(L)/float(Fs) # time axis in secondsprint(L)
In [4]: # Plot the signal in the time domaininc1 = 100plt.figure(3, figsize=fsz)plt.subplot(211)plt.plot(tt[::inc1], np.real(rt[::inc1]), '-b', label='real part')plt.ylabel('Re[$r(t)$]')plt.title('Doorbell Signal File: {}, $F_s$={} kHz'.format(fname, Fs/1000))plt.legend()plt.grid()plt.subplot(212)plt.plot(tt[::inc1], np.imag(rt[::inc1]), '-r', label='imag part')plt.ylabel('Im[$r(t)$]')plt.xlabel('$t$ [sec]')plt.legend()plt.grid()plt.tight_layout()
In [5]: # Compute the FT approximationRf = np.fft.fft(rt)/float(Fs)N = Rf.size # blocklength of FFTDf = Fs/float(N) # frequency resolutionff = Df*np.arange(N) # generate frequency axis
In [6]: # Doorbell Signal in the frequency domain using dB for magnitudeinc3 = 10plt.figure(11, figsize=fsz)plt.subplot(211)plt.plot(ff[::inc3]/1000.0, 20*np.log10(abs(Rf[::inc3])), '-b', label='magnitude [dB]')plt.ylabel('$|R(f)|$ [dB]')plt.title('Doorbell Signal File: {}, $F_s$={} kHz'.format(fname, Fs/1000))plt.legend()plt.grid()plt.subplot(212)plt.plot(ff[::inc3]/1000.0, 180/np.pi*np.angle(Rf[::inc3]), '-r', label='phase')plt.ylabel('$\\angle R(f)$ [deg]')plt.xlabel('$f$ [kHz]')plt.legend()plt.grid()plt.tight_layout()
There is a spectral component at about 988 kHz visible. Since the recording was made with a center frequency of 314 MHz,
this probably means that the carrier frequency of the doorbell transmitter was a little less than 315 MHz. We will shift the
signal down to about 20 kHz and then use a lowpass filter followed by downsampling for further processing at a lower
sampling rate.
In [15]: # Shifting signal down in frequency domainfx1 = 968e3 # local oscillator frequency for downshiftingrx1t = rt*np.exp(-1j*2*np.pi*fx1*tt)
In [18]: # Now we can downsample by a factor of M and compute the FT againM = 50 # downsampling factorFs1 = Fs/M # new sampling raterxLP1t = rxLPt[::M]tt1 = np.arange(rxLP1t.size)/float(Fs1) # New time axisRxLP1f = np.fft.fft(rxLP1t)/float(Fs1)N1 = RxLP1f.size # blocklength of new FFTDf1 = Fs1/float(N1) # new frequency resolutionff1 = Df1*np.arange(N1) # generate frequency axis
In [19]: # Display the result from the new FFTplt.figure(19, figsize=fsz)plt.subplot(211)plt.plot(ff1/1000.0, 20*np.log10(abs(RxLP1f)), '-b', label='magnitude [dB]')plt.ylabel('$|R(f)|$ [dB]')plt.title('Doorbell Signal File: {}, $F_s$={} kHz'.format(fname, Fs1/1000))plt.legend()plt.grid()plt.subplot(212)plt.plot(ff1/1000.0, 180/np.pi*np.angle(RxLP1f), '-r', label='phase')plt.ylabel('$\\angle R(f)$ [deg]')plt.xlabel('$f$ [kHz]')plt.legend()plt.grid()plt.tight_layout()
Now the carrier is at about 20.7 kHz and the sampling rate is kHz. We repeat the process of downshifting the
carrier, this time to about 5 kHz, followed by lowpass filtering and downsampling to kHz.
In [20]: # Shifting signal down in frequency domainfx2 = 15.7e3 # local oscillator frequency for downshiftingrx2t = rxLP1t*np.exp(-1j*2*np.pi*fx2*tt1)
In [33]: # Now we can downsample by a factor of M2 and compute the FT againM2 = 5 # downsampling factorFs2 = Fs1/M2 # new sampling raterxLP2t = rxLP21t[::M2]tt2 = np.arange(rxLP2t.size)/float(Fs2) # New time axisRxLP2f = np.fft.fft(rxLP2t)/float(Fs2)N2 = RxLP2f.size # blocklength of new FFTDf2 = Fs2/float(N2) # new frequency resolutionff2 = Df2*np.arange(N2) # generate frequency axis
In [34]: # Display the result from the new FFTplt.figure(27, figsize=fsz)plt.subplot(211)plt.plot(ff2/1000.0, 20*np.log10(abs(RxLP2f)), '-b', label='magnitude [dB]')plt.ylabel('$|R(f)|$ [dB]')plt.title('Doorbell Signal File: {}, $F_s$={} kHz'.format(fname, Fs2/1000))plt.legend()plt.grid()plt.subplot(212)plt.plot(ff2/1000.0, 180/np.pi*np.angle(RxLP2f), '-r', label='phase')plt.ylabel('$\\angle R(f)$ [deg]')plt.xlabel('$f$ [kHz]')plt.legend()plt.grid()plt.tight_layout()
In [92]: plt.figure(39, figsize=fsz)plt.subplot(311)plt.plot(tt3, 180/np.pi*phase_rxBP3tu, label='unwrapped')plt.title('Phase and Frequency of Received Signal $r(t)=s(t)\cos(\psi(t))$')plt.ylabel('$\psi(t)$ [deg]')plt.legend()plt.grid()plt.subplot(312)plt.plot(tt3[1:], phase_rxBP3tu[1:]/(2*np.pi*tt3[1:]), label='freq')plt.ylim([4800,5000])plt.ylabel('$\psi(t)/(2\pi t)$ [Hz]')plt.legend()plt.grid()plt.subplot(313)plt.plot(tt3[1:], Fs2*np.diff(phase_rxBP3tu)/(2*np.pi), label='inst freq')plt.ylim([4700,5300])plt.ylabel('$f_i(t)$ [Hz]')plt.xlabel('t [sec]')plt.legend()plt.grid()plt.tight_layout()
The quantity is the instantaneous frequency of the received doorbell signal , where or
In [91]: ts71, ts72 = 0.0, 1.0ixs7 = np.where(np.logical_and(tt2>=ts71, tt2<ts72))[0]plt.figure(59, figsize=fsz2)plt.plot(tt2[ixs7], np.real(rxtenv[ixs7]), '-b', label='abs')plt.title('Absolute Value of I and Q Waveforms')plt.ylabel('$|r(t)|$')plt.legend()plt.grid()plt.xlabel('t [sec]')plt.legend()plt.tight_layout()
In [93]: # Zooming ints81, ts82 = 0.377, 0.424ixs8 = np.where(np.logical_and(tt2>=ts81, tt2<ts82))[0]plt.figure(63, figsize=fsz2)plt.plot(tt2[ixs8], np.real(rxtenv[ixs8]), '-b', label='abs')plt.title('Absolute Value of I and Q Waveforms')plt.ylabel('$r(t)$')plt.legend()plt.grid()plt.xlabel('t [sec]')plt.legend()plt.tight_layout()