はじめに
電子工作や回路の実装に興味はあるけれど、「ちょっと難しそう」「とっつきにくい」と感じたことはありませんか?
私自身も、理論だけでは手応えがなく、逆に手を動かすだけでは背景の理解が追いつかない——そんなもどかしさを感じてきました。
今回は、NJM4580DDを使ったヘッドホンアンプキットを題材に、電子回路と理論をつなぐ試みとして記事を書いてみました。
さらに、ITエンジニアやデータ分析に関わる方にも馴染みのあるPythonを使って、増幅の数式や回路の挙動を視覚的に理解できるように工夫しています。
はじめての投稿となりますが、もしご意見やアドバイスがありましたら、ぜひフィードバックいただけると嬉しいです。
参考リンクまとめ
- キットPDF説明書(PDF)
https://akizukidenshi.com/goodsaffix/AE-KIT45-HPA.pdf
-
NJM4580DD データシート(PDF)
https://akizukidenshi.com/goodsaffix/NJM4580_j.pdf -
データシートの読み方(動画)
https://www.youtube.com/watch?v=eWIHCRR4xGk
データシートとPythonコード
回路構成の条件と要素のまとめ(NJM4580DDキット 非反転増幅回路)
項目 | 内容・役割 |
---|---|
回路の基本 | 非反転増幅回路(オペアンプ使用) |
電源方式 | 片電源(+側のみ)で動作させるため、仮想GNDをR1・R2で生成 |
仮想GND電圧 | 電源電圧の半分(電圧分圧により生成) |
GND電位 | 回路全体では GND = 0V として扱う |
C1, C2 | 仮想GNDを安定化するためのバイパス(デカップリング)コンデンサ |
R4, R5, R8, R9 | オペアンプの増幅率(ゲイン)を決定する抵抗 本キットでは 5.7倍に設定 |
R3, R7 | 入力抵抗が高いオペアンプのための仮想入力抵抗 → 安定動作を助けるためのダミー抵抗 |
R6, R10 | 出力保護抵抗(短絡や負荷からオペアンプを保護) |
C3, C4, C5, C6 |
直流カット用のカップリングコンデンサ → 交流信号のみを通過させる |
関連リンク集(参考資料)
-
カップリングコンデンサとは?(直流をカットして交流だけを通す役割)
https://analogista.jp/coupling-capacitor/ -
直流カット用コンデンサの基礎(TDK 技術マガジン)
https://www.tdk.com/ja/tech-mag/condenser/003 -
出力保護抵抗の役割と使用方法
https://www.marutsu.co.jp/contents/shop/marutsu/mame/110.html?srsltid=AfmBOooAuNF5IX5_2UMaimF6PB3V36yJfjnTB6lxHxsTgjskUdVnkPLY -
抵抗による電子回路の保護方法
https://t-design-free.com/protection-by-resistance/
コード
import numpy as np
import matplotlib.pyplot as plt
# --- Parameters / パラメータ定義 ---
Ra = 100 # 抵抗A / Resistance A [Ω]
Rb = 10 # 抵抗B / Resistance B [Ω]
A = 5.7 # 増幅率 / Amplification factor
fs = 10000 # サンプリング周波数 / Sampling rate [Hz]
f1 = 261.63 # 周波数1(ド)/ Frequency 1: C note [Hz]
f2 = 293.66 # 周波数2(レ)/ Frequency 2: D note [Hz]
t_end = 0.02 # 時間長さ / Duration [s]
Z_load = 8.0 # スピーカーインピーダンス / Speaker impedance [Ω]
Z_out = 0.5 # 出力インピーダンス / Amp output impedance [Ω]
# --- Voltage Divider / 分圧計算 ---
v_ratio = Rb / (Ra + Rb)
v_db = 20 * np.log10(v_ratio)
print("① Voltage ratio =", v_ratio)
print("① Voltage ratio [dB] =", v_db, "dB")
# --- Damping Factor / ダンピングファクター ---
DF = Z_load / Z_out
print("① Damping Factor (DF) =", DF)
# --- Gain to dB / 増幅率のdB表示 ---
A_dB = 20 * np.log10(A)
print("② Gain A in dB =", A_dB, "dB")
# --- Time axis / 時間軸の生成 ---
t = np.linspace(0, t_end, int(fs * t_end))
# --- Sine wave input/output / サイン波 入力と出力 ---
input_wave = np.sin(2 * np.pi * f1 * t)
output_wave = A * input_wave
period = 1 / f1
print("② Period of input sine wave =", period, "s")
# --- Plot: Time domain waveform / 時間領域の波形 ---
plt.figure(figsize=(10, 4))
plt.plot(t, input_wave, label="Input (1V sine)")
plt.plot(t, output_wave, label=f"Output (×{A})")
plt.title("② Time Domain: Input and Output Wave")
plt.xlabel("Time [s]")
plt.ylabel("Voltage [V]")
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()
# --- FFT Function / FFT用関数定義 ---
def compute_fft(signal, fs):
N = len(signal)
fft_vals = np.fft.fft(signal)
fft_freq = np.fft.fftfreq(N, 1 / fs)
fft_mag = np.abs(fft_vals) / N * 2 # 振幅正規化 / Normalize amplitude
return fft_freq[:N // 2], fft_mag[:N // 2]
# --- FFT Calculation / 入力・出力波形のFFT解析 ---
freq_input, mag_input = compute_fft(input_wave, fs)
freq_output, mag_output = compute_fft(output_wave, fs)
# --- Plot: Frequency domain / 周波数領域の波形 ---
plt.figure(figsize=(10, 4))
plt.plot(freq_input, mag_input, label="Input FFT")
plt.plot(freq_output, mag_output, label="Output FFT")
plt.title("② Frequency Domain: FFT of Input and Output")
plt.xlabel("Frequency [Hz]")
plt.ylabel("Amplitude")
plt.xlim(0, 2000)
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()
# --- Trigonometric identities / 三角関数の公式による波形 ---
x1 = np.sin(2 * np.pi * f1 * t)
x2 = np.sin(2 * np.pi * f2 * t)
sum_wave = A * (x1 + x2) # 加法定理 / Sum formula
double_wave = A * (2 * np.sin(np.pi * f1 * t) * np.cos(np.pi * f1 * t)) # 2倍角の公式 / Double angle
prod_wave = A * (0.5 * (np.cos(2 * np.pi * (f1 - f2) * t) - np.cos(2 * np.pi * (f1 + f2) * t))) # 積和公式
wa_wave = A * (2 * np.sin(np.pi * (f1 + f2) * t) * np.cos(np.pi * (f1 - f2) * t)) # 和積公式
# --- Plot: Trigonometric formula waveforms / 三角関数公式のプロット ---
plt.figure(figsize=(12, 8))
plt.subplot(4, 1, 1)
plt.plot(t, sum_wave)
plt.title("③ Sum Formula: A × (sin(f1) + sin(f2))")
plt.ylabel("Amplitude")
plt.grid(True)
plt.subplot(4, 1, 2)
plt.plot(t, double_wave)
plt.title("③ Double Angle Formula: A × 2sin(a)cos(a)")
plt.ylabel("Amplitude")
plt.grid(True)
plt.subplot(4, 1, 3)
plt.plot(t, prod_wave)
plt.title("③ Product-to-Sum: A × [cos(a−b) − cos(a+b)] / 2")
plt.ylabel("Amplitude")
plt.grid(True)
plt.subplot(4, 1, 4)
plt.plot(t, wa_wave)
plt.title("③ Sum-to-Product: A × 2sin((a+b)/2)cos((a−b)/2)")
plt.xlabel("Time [s]")
plt.ylabel("Amplitude")
plt.grid(True)
plt.tight_layout()
plt.show()
結果
ゲイン付きの一次遅れ系として、全体のボード線図をかいてみよう
コード
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
# --- Parameters / パラメータ定義 ---
dB_target = 40 # 与えられたデシベル / Target gain in dB
A = 10 ** (dB_target / 20) # A = 10^(dB/20) で変換 / Convert dB to gain
T = 0.01 # 時定数 / Time constant [s]
# --- Transfer Function: A / (sT + 1) ---
num = [A]
den = [T, 1]
system = signal.TransferFunction(num, den)
# --- Frequency range / 周波数軸 [rad/s] ---
w = np.logspace(1, 5, 1000) # 10^1 to 10^5 rad/s
# --- Bode plot calculation ---
w, mag, phase = signal.bode(system, w)
# --- カットオフ周波数(rad/sとHz)を計算 / Compute cutoff frequency ---
omega_c = 1 / T
f_c = omega_c / (2 * np.pi)
# --- Plot Gain / ゲインプロット ---
plt.figure(figsize=(10, 4))
plt.semilogx(w, mag) # Bode magnitude plot
plt.title("Bode Plot (Magnitude)")
plt.xlabel("Frequency [rad/s]")
plt.ylabel("Gain [dB]")
plt.grid(True, which="both")
plt.axhline(y=dB_target, color="r", linestyle="--", label=f"{dB_target} dB Line")
plt.axvline(x=omega_c, color="g", linestyle="--", label=f"Cutoff: {omega_c:.1f} rad/s")
plt.legend()
plt.tight_layout()
plt.show()
# --- Plot Phase / 位相プロット ---
plt.figure(figsize=(10, 4))
plt.semilogx(w, phase) # Bode phase plot
plt.title("Bode Plot (Phase)")
plt.xlabel("Frequency [rad/s]")
plt.ylabel("Phase [degrees]")
plt.grid(True, which="both")
plt.tight_layout()
plt.show()
# --- プリント出力 / Console output ---
print("=== カットオフ周波数とゲイン情報 / Cutoff Frequency and Gain Info ===")
print(f"目標ゲイン / Target gain: {dB_target} dB")
print(f"電圧倍率 / Voltage gain (linear): {A:.2f}")
print(f"時定数 / Time constant T: {T} s")
print(f"カットオフ周波数 / Cutoff frequency: {omega_c:.2f} rad/s ≈ {f_c:.2f} Hz")
結果