LABO 3

Plot dei dati di uno scan in frequenza, fit guadagno e sfasamento

Import dei moduli necessari

In [1]:
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
...
In [2]:
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

In [3]:
gain = abs(v2/v1)

Creazione di funzioni guadagno e sfasamento usando il formalismo complesso

In [4]:
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

In [5]:
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

In [6]:
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))
Risultato dei fit:
C da fit guadagno   --> 211.294579 nF
C da fit sfasamento --> 215.645739 nF

Plot delle funzioni guadagno e sfasamento sopra i precedenti

In [7]:
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()