参考にした資料
# プログラム名: clock_filter_fft_analysis.py
# Program Name: clock_filter_fft_analysis.py
# 内容: クロック信号(1V/0V)のローパスフィルタリング(RC, IIR, 移動平均)とFFTスペクトルを個別に可視化
# Description: Apply various low-pass filters to a 1V/0V clock signal and visualize each output and its FFT spectrum separately
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import butter, lfilter
# --- クロック信号の生成 / Generate 1V/0V square wave clock signal ---
fs = 1000 # サンプリング周波数 / Sampling frequency [Hz]
T = 1 # 波形長 / Duration [s]
t = np.linspace(0, T, fs * T, endpoint=False)
f_clk = 5 # クロック周波数 / Clock frequency [Hz]
signal = 1.0 * (np.sin(2 * np.pi * f_clk * t) > 0) # クロック信号(矩形波) / Clock signal (square wave)
# --- アナログRCフィルタ(離散版) / Discrete RC Low-pass filter (analog style) ---
def rc_lowpass(x, dt, RC):
alpha = dt / (RC + dt)
y = np.zeros_like(x)
for i in range(1, len(x)):
y[i] = y[i - 1] + alpha * (x[i] - y[i - 1])
return y
RC = 1 / (2 * np.pi * 10) # カットオフ周波数10Hz相当 / Equivalent to 10 Hz cutoff
dt = 1 / fs
signal_rc = rc_lowpass(signal, dt, RC)
# --- デジタルIIRフィルタ(Butterworth) / Digital IIR filter (Butterworth) ---
def butter_lowpass(cutoff, fs, order=4):
nyq = 0.5 * fs
norm_cutoff = cutoff / nyq
b, a = butter(order, norm_cutoff, btype='low')
return b, a
b, a = butter_lowpass(10, fs)
signal_iir = lfilter(b, a, signal)
# --- 移動平均フィルタ / Moving average filter ---
def moving_average(x, N):
return np.convolve(x, np.ones(N) / N, mode='same')
signal_ma = moving_average(signal, N=150) # 平滑化サイズを150点に設定 / Smoothing over 150 samples
# --- FFT計算関数 / FFT computation function ---
def compute_fft(x, fs):
N = len(x)
f = np.fft.fftfreq(N, 1/fs)
X = np.fft.fft(x)
return f[:N//2], np.abs(X[:N//2]) # 片側振幅スペクトル / Single-sided amplitude spectrum
# --- FFTプロット関数 / Plot FFT result individually ---
def plot_fft(x, fs, title):
f, amp = compute_fft(x, fs)
plt.figure()
plt.plot(f, amp)
plt.title(f'FFT Spectrum - {title}')
plt.xlabel('Frequency [Hz]')
plt.ylabel('Amplitude')
plt.xlim(0, 100)
plt.grid()
# --- 元のクロック信号波形 / Plot original clock waveform ---
plt.figure()
plt.plot(t, signal)
plt.title('Original Clock Signal')
plt.xlabel('Time [s]')
plt.ylabel('Voltage [V]')
plt.grid()
# --- 各種フィルタ出力の波形 / Plot filtered waveforms separately ---
plt.figure()
plt.plot(t, signal_rc)
plt.title('RC Low-pass Filter Output')
plt.xlabel('Time [s]')
plt.ylabel('Voltage [V]')
plt.grid()
plt.figure()
plt.plot(t, signal_iir)
plt.title('Digital IIR Filter Output')
plt.xlabel('Time [s]')
plt.ylabel('Voltage [V]')
plt.grid()
plt.figure()
plt.plot(t, signal_ma)
plt.title('Moving Average Filter Output')
plt.xlabel('Time [s]')
plt.ylabel('Voltage [V]')
plt.grid()
# --- 各フィルタ処理後のFFTスペクトルを個別プロット / Plot FFT spectra for each case ---
plot_fft(signal, fs, 'Original Clock')
plot_fft(signal_rc, fs, 'RC Filtered')
plot_fft(signal_iir, fs, 'IIR Filtered')
plot_fft(signal_ma, fs, 'Moving Average Filtered')
# --- すべてのプロットを表示 / Show all plots ---
plt.show()
結果