Op-amp filter
For the op-amp filter shown in the figure, find $R_2$ and $C$ so as to get a cut-off frequency of $200\,$Hz and high-frequency gain of $14\,$dB.
In [1]:
from IPython.display import Image
Image(filename =r'EC_filter_1_fig_1.png', width=280)
Out[1]:
In [2]:
# run this cell to view the circuit file.
%pycat EC_filter_1_orig.in
We now replace strings such as \$R2 with the values of our choice by running the python script given below. It takes an existing circuit file EC_filter_1_orig.in and produces a new circuit file EC_filter_1.in, after replacing \$R2, etc. with the values of our choice.
In [3]:
import gseim_calc as calc
s_R1 = '1k'
s_R2 = '8k' # to be changed by user
s_C = '1.8e-6' # to be changed by user
s_NPD = '100'
f_start = 10.0
f_stop = 1.0e4
s_FSTART = ("%11.4E"%(f_start)).strip()
s_FSTOP = ("%11.4E"%(f_stop)).strip()
l = [
('$R1', s_R1),
('$R2', s_R2),
('$C', s_C),
('$NPD', s_NPD),
('$FSTART', s_FSTART),
('$FSTOP', s_FSTOP),
]
calc.replace_strings_1("EC_filter_1_orig.in", "EC_filter_1.in", l)
print('EC_filter_1.in is ready for execution')
EC_filter_1.in is ready for execution
Execute the following cell to run NGSPICE on EC_filter_1.in.
In [4]:
import ngspice_calc as ngcalc
ngcalc.run_ngspice('EC_filter_1.in')
Circuit: op-amp filter frequency response Doing analysis at TEMP = 27.000000 and TNOM = 27.000000 No. of Data Columns : 3 No. of Data Rows : 301 Total analysis time (seconds) = 0.001 Total elapsed time (seconds) = 0.002 Total DRAM available = 7739.719 MB. DRAM currently available = 2538.383 MB. Total ngspice program size = 19.594 MB. Resident set size = 9.469 MB. Shared ngspice pages = 7.824 MB. Text (code) pages = 5.789 MB. Stack = 0 bytes. Library pages = 1.844 MB.
Out[4]:
'EC_filter_1.raw'
In [5]:
# get output file information from the circuit file
s = ngcalc.slv('EC_filter_1.in')
for i in range(s.num_plots()):
print(f" plot {i}: {s.plotname(i)} | type: {s.analysis_type(i)} | vars: {s.variables(i)}")
plot 0: AC Analysis | type: tran | vars: ['frequency', 'v(a)', 'v(d)']
In [6]:
freq = s.get_array('frequency')
v_in = s.get_array('v(a)')
v_out = s.get_array('v(d)')
H = v_out/v_in
gain_db = ngcalc.to_db(H)
phase1 = ngcalc.to_degree(H)
phase = [x if x < 0 else (x-360.0) for x in phase1]
print(f'Frequency points : {len(freq)}')
print(f'Freq range : {freq[0]:.2f} Hz to {freq[-1]:.2e} Hz')
flag_flat = False
print(f'gain_db[-1]: {gain_db[-1]:.2f} dB')
print(f'gain_db[-2]: {gain_db[-2]:.2f} dB')
if abs(gain_db[-1]-gain_db[-2]) < 0.02:
flag_flat = True
gain_3db = gain_db[-1] - 3.0
print(f'gain_max: {gain_db[-1]:.2f} dB')
f_c = ngcalc.interp_at(gain_db, freq, gain_3db)
print(f'f_c: {f_c:.2e}')
print(f'gain_3db: {gain_3db:.2f}')
else:
print('fc is outside the simulation frequency range')
Frequency points : 301 Freq range : 10.00 Hz to 1.00e+04 Hz gain_db[-1]: 18.06 dB gain_db[-2]: 18.06 dB gain_max: 18.06 dB f_c: 8.86e+01 gain_3db: 15.06
In [7]:
import matplotlib.pyplot as plt
color1 = 'blue'
color2 = 'green'
color3 = 'red'
fig, ax = plt.subplots(2, sharex=True, figsize=(6, 5))
plt.subplots_adjust(hspace=0.08)
plt.xlim(f_start, f_stop)
# ── Gain plot ────────────────────────────────────────────────
ax[0].semilogx(freq, gain_db, color=color1, linewidth=1.0, label='gain')
if flag_flat:
ax[0].axvline(x=f_c, color=color2, linestyle='--', linewidth=0.8, dashes=(5,5), label='fc')
ax[0].axhline(y=gain_3db, color=color3, linestyle='--', linewidth=0.8, dashes=(5,5), label='3 dB')
ax[0].legend(fontsize=9)
ax[0].set_ylabel('Gain (dB)', fontsize=11)
ax[0].grid(color='#CCCCCC', linestyle='solid', linewidth=0.5, which='both')
ax[0].tick_params(labelbottom=False)
# ── Phase plot ───────────────────────────────────────────────
ax[1].semilogx(freq, phase, color=color1, linewidth=1.0, label='NGSPICE')
ax[1].set_ylabel('Phase (deg)', fontsize=11)
ax[1].set_xlabel('Frequency (Hz)', fontsize=11)
ax[1].grid(color='#CCCCCC', linestyle='solid', linewidth=0.5, which='both')
fig.suptitle('Filter Frequency Response', fontsize=12)
plt.tight_layout()
plt.show()
This notebook was contributed by Prof. M. B. Patil, IIT Bombay. He may be contacted at mbpatil@ee.iitb.ac.in.
In [ ]: