Pour obtenir le diagramme de Bode de la réponse fréquentielle, le filtre LC est branché sur le convertisseur analogique/numérique SysamSP5.
Figure pleine pageLes valeurs utilisées sont , et .
Le convertisseur Eurosmart SysamSP5 est piloté avec le module pycan.
import pycan.main as pycan import numpy import math import time
La fonction suivante effectue l'analyse du filtre à une fréquence donnée, pour une amplitude choisie de la sinusoïde d'entrée. Elle renvoit le gain en décibel, le cosinus du déphasage et le déphasage.
def analyser(sys,f,a): print("Frequence = %f"%f) ne = 50 T=1.0/f te=T/ne v1 = numpy.zeros(ne,numpy.double) for k in range(ne): phi = 2*math.pi/ne*k v1[k] = a*math.sin(phi) sys.config_sortie(1,te*10**6,v1,-1) sys.config_entrees([0,1],[10.0,10.0]) np=100 # nombre de périodes de l'acquisition nea = ne*np duree = nea*te sys.config_echantillon(te*10**6,nea) sys.declencher_sorties(1,0) time.sleep(1) # régime transitoire sys.acquerir() # première acquisition pour connaitre l'amplitude de la sortie sys.stopper_sorties(1,0) t=sys.temps() u=sys.entrees() max1 = u[1].max() sys.config_entrees([0,1],[10.0,max1]) # ajustement du gain pour la sortie sys.config_echantillon(te*10**6,nea) sys.declencher_sorties(1,0) time.sleep(1) # régime transitoire sys.acquerir() sys.stopper_sorties(1,0) t=sys.temps() u=sys.entrees() mu0 = numpy.mean(u[0]) mu1 = numpy.mean(u[1]) rms0 = numpy.std(u[0]) rms1 = numpy.std(u[1]) g = rms1/rms0 gdb = 20.0*math.log10(g) print("GdB = %f"%(gdb)) cosphi = numpy.mean((u[0]-mu0)*(u[1]-mu1))/(rms0*rms1) print("cosphi = %f"%cosphi) phi = math.acos(cosphi)*180.0/math.pi print("phi = %f deg"%phi) return gdb,cosphi,phi
On ouvre l'interface avec le SysamSP5, on génère le tableau des fréquences et on effectue la boucle de calcul. Les résultats sont sauvegardés dans un fichier.
sys = pycan.Sysam("SP5") freq = numpy.logspace(start=2,stop=4,num=80) gdb = numpy.zeros(freq.size,dtype=numpy.float32) cosphi = numpy.zeros(freq.size,dtype=numpy.float32) phi = numpy.zeros(freq.size,dtype=numpy.float32) amplitude = 1.0 # à choisir en fonction du filtre, pour ne pas dépasser 10 V en sortie for k in range(freq.size): gdb[k],cosphi[k],phi[k] = analyser(sys,freq[k],amplitude) sys.fermer() numpy.savetxt("filtrePasseBande.txt",[freq,gdb,cosphi])
Les points expérimentaux sont représentés sous forme d'un diagramme de Bode pour le gain en décibel et le cosinus du déphasage. Une fonction de transfert est définie en ajoutant une résistance interne r à l'inductance. Les paramètres L,C et r sont ajustées pour obtenir la superposition des courbes avec les points expérimentaux.
import numpy as np import math import matplotlib.pyplot as plt import cmath [freq,gdb,cosphi]=np.loadtxt("filtrePasseBande.txt") R=1000 C=0.98e-6 L=44e-3 r=30 def H(f): # fonction de transfert du filtre w=2*math.pi*f z=1.0/(1.0/(1j*L*w+r)+1j*C*w) return z/(R+z) def GdB(f): return 20*np.log10(np.absolute(H(f))) def CosPhi(f): return math.cos(cmath.phase(H(f))) ufunc_cosphi = np.frompyfunc(CosPhi,1,1) freq_theo = np.logspace(start=2,stop=4,num=1000) gdb_theo = GdB(freq_theo) cosphi_theo = ufunc_cosphi(freq_theo) plt.figure() plt.semilogx(freq,gdb,'ro') plt.semilogx(freq_theo,gdb_theo) plt.xlabel("f (Hz)") plt.ylabel("G") plt.figure() plt.semilogx(freq,cosphi,'ro') plt.semilogx(freq_theo,cosphi_theo) plt.xlabel("f (Hz)") plt.ylabel("cos(phi)") plt.show()
L'oscillateur est construit à partir du filtre précédent. Pour cela, la sortie du filtre est amplifiée pour être appliquée à l'entrée. Le gain de l'amplificateur doit compenser le gain maximal du filtre, soit -4 dB. Il doit donc avoir un gain G=1.6 environ. Un potentiomètre permet de faire un réglage fin du gain.
Figure pleine pageLe programme effectue une acquisition de l'entrée (voie EA0) et de la sortie (voieEA1) du filtre. L'analyse spectrale de la sortie est effectuée.
import pycan.main as pycan import numpy import math import time import matplotlib.pyplot as plt import numpy.fft sys = pycan.Sysam("SP5") te=10.0e-6 ne=100000 duree=te*ne sys.config_entrees([0,1],[10.0,10.0]) sys.config_echantillon(te*1e6,ne) sys.acquerir() t=sys.temps() u=sys.entrees() sys.fermer() tfd=numpy.fft.fft(u[1]) f=numpy.arange(tfd.size) for k in range(f.size): f[k] = 1.0*k/duree spectre=20*numpy.log10(numpy.absolute(tfd)) plt.figure() plt.plot(t[0],u[0],label="EA0") plt.plot(t[1],u[1],label="EA1") plt.xlabel("t (s)") plt.ylabel("u (V)") plt.axis([0,0.01,-10.0,10.0]) plt.grid() plt.legend() plt.figure() plt.plot(f,spectre) plt.axis([0,10000.0,0,numpy.amax(spectre)]) plt.grid() plt.xlabel("f (Hz)") plt.ylabel("A") plt.show()
Dans le premier exemple, on ajuste le gain de l'amplificateur pour obtenir des oscillations sinusoïdales en sortie de l'amplificateur (en entrée du filtre).
Le spectre montre une oscillation pratiquement harmonique. On observe une harmonique de rang 3 d'amplitude -60 dB par rapport au fondamental.
Dans le deuxième exemple, on ajuste le gain pour obtenir une saturation en sortie de l'amplificateur.
Ce réglage a l'avantage d'être plus stable que le précédent. Le facteur de qualité relativement élevé du filtre (environ 4,5) permet d'obtenir une oscillation pratiquement sinusoïdale en sortie du filtre, avec un taux de distortion inférieur à -50 dB.