import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize as opt
Lettura dati da file csv (comma separated value) che contiene 4 colonne con i valori di frequenza f, ampiezza di segnali di input e output v1, v2 e differenza di fase dp:
...
20.466804243832847,1.9986168839393785,0.025251550993580306,88.665119665759704
20.944503797768707,1.9985771527719591,0.025834264428911811,88.643674001849973
21.433352960657288,1.9986278102134793,0.026444519394448984,88.623750871106211
...
f,v1,v2,dp = np.loadtxt('dati/passa_alto.csv', delimiter=',', unpack=True, skiprows=1)
I dati provengono da uno scan in frequenza (5 Hz -- 10 kHz), il circuito è un RC passa alto con frequenza a 3dB di 716 Hz.
Creazione di un array per il guadagno
gain = abs(v2/v1)
Creazione di funzioni guadagno e sfasamento usando il formalismo complesso
def gainf(f,c):
res = 1e3 # Ohm
omega = 2*np.pi*f
zr = res + 0j # complex impedance of the resistor
zc = 0 - 1j/(omega*c) # complex impedance of the capacitor
gain = zr/(zr+zc)
return abs(gain)
def sfasf(f,C):
res = 1e3 # Ohm
omega = 2*np.pi*f
return np.arctan(1/(omega*res*C))/(2*np.pi)*360
Plot di guadagno e sfasamento in funzione della frequenza
plt.figure(figsize=(12,5))
plt.suptitle('Guadagno e sfasamento in funzione della frequenza') # super title
plt.subplot(1,2,1)
plt.yscale('log')
plt.xscale('log')
plt.xlabel('frequenza')
plt.ylabel('guadagno')
plt.grid()
plt.plot(f,gain, label='dati')
plt.plot(f,gainf(f,220e-9),linestyle='--',label='funzione teorica')
plt.legend(fontsize=14)
plt.subplot(1,2,2)
plt.xscale('log')
plt.ylabel('Sfasamento [gradi]')
plt.xlabel('frequenza')
plt.grid()
plt.plot(f,dp, label='dati')
plt.plot(f,sfasf(f,220e-9),linestyle='--',label='funzione teorica')
plt.legend(fontsize=14)
plt.show()
Fit per verificare il valore della capacità C
parsG, cov = opt.curve_fit(gainf, f,gain,p0=200e-9)
parsS, cov = opt.curve_fit(sfasf, f,dp,p0=200e-9)
print('Risultato dei fit:')
print('C da fit guadagno --> %f nF' % (parsG[0]*1e9))
print('C da fit sfasamento --> %f nF' % (parsS[0]*1e9))
Plot delle funzioni guadagno e sfasamento sopra i precedenti
fig = plt.figure(figsize=(15,6))
plt.suptitle('Guadagno e sfasamento in funzione della frequenza (filtro RC passa alto)', fontsize=14) # super title
plt.subplot(1,2,1)
plt.yscale('log')
plt.xscale('log')
plt.xlabel('frequenza')
plt.ylabel('guadagno')
plt.grid()
plt.plot(f,gain, label='dati')
plt.plot(f,gainf(f,220e-9),linestyle='--',label='funzione teorica (C=220 nF)')
plt.plot(f,gainf(f,parsG[0]),':r',label='risultato fit (C=%.1f nF)'% (parsG[0]*1e9))
plt.legend(fontsize=14)
plt.subplot(1,2,2)
plt.xscale('log')
plt.ylabel('Sfasamento [gradi]')
plt.xlabel('frequenza')
plt.grid()
plt.plot(f,dp, label='dati')
plt.plot(f,sfasf(f,220e-9),linestyle='--',label='funzione teorica (C=220 nF)')
plt.plot(f,sfasf(f,parsS[0]),':r',label='risultato fit (C=%.1f nF)'% (parsS[0]*1e9))
plt.legend(fontsize=14)
fig.savefig('passa_alto.png')
plt.show()