はじめに
本記事では、逐次比較型ADC(SAR ADC)風のアルゴリズムを用いて、
入力信号(サイン波)に対して 比較 → ビット出力 → 残差生成 → 再帰処理 を行う
Pythonコードについて詳しく解説します。
このコードを使うことで、以下のような処理が視覚的に確認できます:
各ステップでのビット判定(0 or 1)
各ステップで生成される残差電圧の推移
最終的なデジタル出力の再構成
すべてのビット・残差を時間軸に沿ってプロット表示
逐次比較型ADCの学習や可視化、シミュレーションに最適な内容となっております。
Pythonコード
import numpy as np
import matplotlib.pyplot as plt
def comparator_and_residue(Vin, Vref):
"""
コンパレータと残差出力
Comparator and residue output
"""
if Vin > Vref:
Bit = 1
Vout = 2 * (Vin - Vref)
else:
Bit = 0
Vout = 2 * Vin
return Bit, Vout
# ---- 初期設定 / Initialization ----
fs = 1000 # サンプリング周波数 [Hz]
f = 5 # サイン波周波数 [Hz]
t = np.arange(0, 1, 1/fs) # 時間軸
Vin_all = 0.5 * np.sin(2 * np.pi * f * t) + 0.5 # [0,1]範囲のサイン波
Vref = 0.5 # 比較用基準電圧
n_steps = 8 # 8ビット比較ステップ
# ---- データ記録用 / Data storage ----
bits_matrix = []
residues_matrix = []
digital_values = []
# ---- SAR処理: ビット生成 + 各残差を記録 ----
for Vin in Vin_all:
current_Vin = Vin
bits = []
residues = []
for _ in range(n_steps):
bit, current_Vin = comparator_and_residue(current_Vin, Vref)
bits.append(bit)
residues.append(current_Vin)
bits_matrix.append(bits)
residues_matrix.append(residues)
digital = int("".join(map(str, bits)), 2)
digital_values.append(digital)
# ---- NumPy配列に変換 / Convert to arrays ----
bits_array = np.array(bits_matrix) # shape: (samples, 8)
residues_array = np.array(residues_matrix) # shape: (samples, 8)
# ---- プロット / Plot section ----
plt.figure(figsize=(16, 18))
# 元の入力とデジタル値のプロット / Input and reconstructed value
plt.subplot(n_steps + 2, 1, 1)
plt.plot(t, Vin_all, label='Input (sine wave)')
plt.plot(t, np.array(digital_values) / (2**n_steps - 1), label='Reconstructed Digital Value')
plt.title("Input and Reconstructed Digital Output (8-bit)")
plt.ylabel("Voltage")
plt.legend()
plt.grid(True)
# 各残差ステップのプロット / Plot all residues
for i in range(n_steps):
plt.subplot(n_steps + 2, 1, i + 2)
plt.plot(t, residues_array[:, i], label=f"Residue after Step {i+1}", color='C' + str(i % 10))
plt.ylabel(f"Vout {i+1}")
plt.grid(True)
plt.legend()
plt.xlabel("Time [s]")
plt.tight_layout()
plt.show()
# ---- 最初の数個の残差を表示 / Print first 10 residues ----
print("First 10 samples (residues per step):")
for i in range(10):
residue_str = ', '.join(f"{r:.4f}" for r in residues_matrix[i])
print(f"t = {t[i]:.4f}s, Vin = {Vin_all[i]:.3f}, Residues = [{residue_str}]")
# ---- プロット / Plot section ----
plt.figure(figsize=(14, 14))
# 元の入力とデジタル出力の比較 / Input vs Digital Output
plt.subplot(n_steps + 2, 1, 1)
plt.plot(t, Vin_all, label='Input (sine wave)')
plt.plot(t, np.array(digital_values) / (2**n_steps - 1), label='Reconstructed Digital Value')
plt.title("Input and Reconstructed Digital Output (8-bit)")
plt.ylabel("Voltage")
plt.legend()
plt.grid(True)
# 各ビットのプロット / Bit plot
for i in range(n_steps):
plt.subplot(n_steps + 2, 1, i + 2)
plt.plot(t, bits_array[:, i], drawstyle='steps-post')
plt.ylim(-0.2, 1.2)
plt.ylabel(f"Bit {n_steps - 1 - i}")
plt.grid(True)
# 最終段の下に残差の最終値をプロット / Last residue
plt.subplot(n_steps + 2, 1, n_steps + 2)
plt.plot(t, residues_array[:, -1], label='Final Residue', color='purple')
plt.ylabel("Residue (Step 8)")
plt.xlabel("Time [s]")
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()