0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonで学ぶΔΣ ADC

0
Last updated at Posted at 2025-09-12

image.png

1. 入力信号 Vin

  • アナログ入力信号。
  • この信号をディジタル値に変換するのが最終目的。

2. 加算器

  • 入力 Vin とフィードバック信号(DAC出力)との差をとる。

  • 出力は「誤差信号 e[n]」。

  • 数式で表すと:

    e[n] = Vin[n] - y_dac[n]
    

3. デジタル積分器

  • 誤差信号を時間的に累積(積分)する。

  • 積分により、低周波成分を強調し、量子化誤差を高周波に押し上げる(ノイズシェーピング)。

  • z領域での伝達関数:

    H(z) = 1 / (1 - z^-1)
    

4. 量子器(Quantizer)

  • 積分器の出力を有限ビット(典型的には1ビット)に丸める。
  • 実際にはコンパレータのような動作で、出力は「+Vref または -Vref」。
  • 出力がそのままディジタル出力 Dout となる。

5. DAC(フィードバック経路)

  • 量子器の出力を再びアナログ値に戻す。
  • これを加算器に戻すことで、ループが閉じる。
  • ループにより誤差が補正され、入力信号が正しく追従される。

6. 出力 Dout

  • 量子器の出力を取り出したもの。
  • 1ビットストリームの形だが、後段のデジタルフィルタとデシメーションで高分解能の多ビットディジタル信号に変換できる。

まとめ

  • Vin → 加算器 → 積分器 → 量子器 → Dout
  • さらに Dout → DAC → フィードバック → 加算器
    というループ構成。
  • このループにより「量子化雑音が高周波に追いやられ(ノイズシェーピング)、帯域内では高SNRを実現」するのがΔΣ型ADCの基本原理。

# Program Name: delta_sigma_adc_blocks.py
# Creation Date: 20250912
# Overview: Visualize each block of a first-order Delta-Sigma ADC (adder, integrator, quantizer, DAC, digital filter)
# Usage: Run this script. It shows each signal in matplotlib plots.

!pip install numpy matplotlib scipy

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import firwin, lfilter

# ================= Parameters =================
fs    = 48000      # サンプリング周波数 [Hz]
fin   = 1000       # 入力サイン波の周波数 [Hz]
A     = 0.5        # 入力振幅 [V] (最大±0.5Vのサイン波)
N     = 1024       # 総サンプル数(シミュレーションの長さ)
Vref  = 1.0        # DACの基準電圧(±Vrefで1ビット出力を表現)
decim = 16         # デシメーション比(フィルタ後に16分の1へ間引き)

# ================= Input Signal =================
# 時間軸を生成(0 ~ (N-1)/fs)
t = np.arange(N) / fs
# 入力アナログ信号(サイン波)
x = A * np.sin(2*np.pi*fin*t)

# ================= Delta-Sigma Modulator =================
# 状態変数の初期化
v_int = 0.0              # 積分器内部状態
y_dac = 0.0              # フィードバック信号(DAC出力)
e_arr = np.zeros(N)      # 加算器出力(誤差信号)の記録
v_arr = np.zeros(N)      # 積分器出力の記録
y_out = np.zeros(N)      # 量子化器(1ビット)出力の記録

for n in range(N):
    # --- 加算器 (Σ部) ---
    # 入力信号とDAC出力(フィードバック)との差を取る
    # 数式: e[n] = x[n] - y[n-1]
    e = x[n] - y_dac
    e_arr[n] = e

    # --- 積分器 (Δ部) ---
    # 誤差信号を逐次的に積分する
    # 数式: v[n] = v[n-1] + e[n]
    v_int += e
    v_arr[n] = v_int

    # --- 量子化器 (Comparator, 1-bit) ---
    # 積分器出力を±Vrefに変換(1ビット符号化)
    # 数式: y[n] = Q{ v[n] } = ±Vref
    if v_int >= 0:
        y_out[n] = Vref
    else:
        y_out[n] = -Vref

    # --- DAC (フィードバック経路) ---
    # 量子化出力をアナログ値(±Vref)に戻し、次サイクルの入力と比較する
    y_dac = y_out[n]

# ================= デジタルフィルタ (FIR + Decimation) =================
# FIRローパスフィルタを設計
# cutoff=1/decim → 帯域内信号を通し、帯域外ノイズを抑える
numtaps = 63
fir = firwin(numtaps, cutoff=1/decim, window="hamming")
# 1ビット出力にFIRフィルタを適用(帯域外ノイズ除去)
y_filt = lfilter(fir, 1.0, y_out)
# デシメーション(サンプルを decim 倍間引き)
y_dec  = y_filt[::decim]
t_dec  = t[::decim]

# ================= Plot =================
plt.figure(figsize=(12,14))

# 入力信号
plt.subplot(6,1,1)
plt.plot(t*1000, x, label="Input x[n]")
plt.ylabel("Vin [V]"); plt.grid(); plt.legend()

# 加算器出力(誤差信号)
plt.subplot(6,1,2)
plt.plot(t*1000, e_arr, label="Adder Output e[n]")
plt.ylabel("e[n]"); plt.grid(); plt.legend()

# 積分器出力
plt.subplot(6,1,3)
plt.plot(t*1000, v_arr, label="Integrator Output v[n]")
plt.ylabel("v[n]"); plt.grid(); plt.legend()

# 量子化器出力(±Vrefの1ビット)
plt.subplot(6,1,4)
plt.step(t*1000, y_out, where="mid", label="Quantizer Output y_out[n]")
plt.ylabel("y_out"); plt.grid(); plt.legend()

# FIRフィルタ後の波形
plt.subplot(6,1,5)
plt.plot(t*1000, y_filt, label="Filtered Output")
plt.ylabel("FIR Out"); plt.grid(); plt.legend()

# デシメーション後の波形(多ビット相当)
plt.subplot(6,1,6)
plt.plot(t_dec*1000, y_dec, label="Decimated Output")
plt.xlabel("Time [ms]"); plt.ylabel("Decimated"); plt.grid(); plt.legend()

plt.suptitle("Delta-Sigma ADC Block Visualization")
plt.tight_layout()
plt.show()

コメント解説のポイント

  1. 数式との対応を明示

    • e[n] = x[n] - y[n-1]
    • v[n] = v[n-1] + e[n]
    • y[n] = Q{v[n]} = ±Vref
    • など、理論式をそのままコードに対応させる。
  2. 信号の流れをブロックごとに整理

    • 入力サイン波 → 加算器(誤差) → 積分器(蓄積) → 量子化器(1ビット) → DAC(FB) → デジタルフィルタ(帯域内抽出)。
  3. プロットで各ブロックの役割を可視化

    • 上から順に信号が処理されていく流れが見える。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?