🖥️ Simulation numérique d’un oscillateur de Wien ★

Notebook Capytale de cet exercice : 42b7-11678447

Dans cet exercice, on cherche à simuler numériquement l’évolution des tensions dans l’oscillateur de Wien à l’aide de la méthode d’Euler.

On note 𝑠(𝑡) la sortie de l’amplificateur non-inverseur et 𝑣(𝑡) la tension de sortie du filtre de Wien.

Les fonctions de transfert de l’amplificateur et du filtre sont respectivement :

𝑆(𝑝)𝑉(𝑝)=1+𝑅2𝑅1𝑉(𝑝)𝑆(𝑝)=131+13(𝑅𝐶𝑝+1𝑅𝐶𝑝)

1/ Montrer que la sortie 𝑠(𝑡) de l’amplificateur non-inverseur vérifie l’équation différentielle

d2𝑠d𝑡2+2−𝑅2𝑅1𝑅𝐶d𝑠d𝑡+1(𝑅𝐶)2𝑠(𝑡)=0
Corrigé

La première fonction de transfert donne simplement

𝑠(𝑡)=(1+𝑅2𝑅1)𝑣(𝑡)

La seconde peut se réécrire

(1+13(𝑅𝐶𝑝+1𝑅𝐶𝑝))𝑉(𝑝)=13𝑆(𝑝)

soit, en multipliant par 3𝑅𝐶𝑝

3𝑅𝐶𝑝𝑉(𝑝)+(𝑅𝐶𝑝)2𝑉(𝑝)+𝑉(𝑝)=𝑅𝐶𝑝𝑆(𝑝)

ce qui donne en temporel

3𝑅𝐶d𝑣d𝑡+(𝑅𝐶)2d2𝑣d𝑡2+𝑣(𝑡)=𝑅𝐶d𝑠d𝑡

La méthode d’Euler ne s’applique qu’à des équations différentielles du premier ordre. Il est alors nécessaire de transformer ces équations en équations d’ordre 1. Pour cela, on introduit 𝑠𝑝=d𝑠d𝑡 et 𝑣𝑝=d𝑣d𝑡.

2/ Montrer que les deux équations de la question précédente peuvent se réécrire sous la forme suivante :

{𝑠=(1+𝑅2𝑅1)𝑣(𝑡)d𝑠d𝑡=𝑠𝑝(𝑡)d𝑣d𝑡=𝑣𝑝(𝑡)d𝑣𝑝d𝑡=−3𝑅𝐶𝑣𝑝(𝑡)−1(𝑅𝐶)2𝑣(𝑡)+1𝑅𝐶𝑠𝑝(𝑡)
Coup de pouce 1
Introduire 𝑣𝑝 et 𝑠𝑝 dans l’équation différentielle obtenue à la question précédente.
Corrigé

L’équation différentielle de la question précédente peut se réécrire

d2𝑣d𝑡2=−3𝑅𝐶d𝑣d𝑡−1(𝑅𝐶)2𝑣(𝑡)+1𝑅𝐶d𝑠d𝑡

soit, en remplaçant avec 𝑣𝑝 et 𝑠𝑝

d𝑣𝑝d𝑡=−3𝑅𝐶𝑣𝑝(𝑡)−1(𝑅𝐶)2𝑣(𝑡)+1𝑅𝐶𝑠𝑝(𝑡)

Les trois autres sont simplement des définitions de 𝑠𝑝 et 𝑣𝑝 et de la relation entre 𝑠 et 𝑣 vue à la question précédente.

Pour résoudre numériquement ces équations, la méthode d’Euler consiste à discrétiser le temps en intervalles de durée Δ𝑡 et à approximer les dérivées par des différences finies (relation de Tailor).

On note 𝑠𝑖=𝑠(𝑖×Δ) ; 𝑣𝑖=𝑣(𝑖×Δ𝑡) ; 𝑠𝑝,𝑖=𝑠𝑝(𝑖×Δ𝑡) et 𝑣𝑝,𝑖=𝑣𝑝(𝑖×Δ𝑡).

3/ Montrer que 𝑠𝑖, 𝑣𝑖, 𝑠𝑝,𝑖 et 𝑣𝑝,𝑖 vérifient les relations de récurrence suivantes :

{𝑠𝑝,𝑖=𝑠𝑖−𝑠𝑖−1Δ𝑡𝑣𝑝,𝑖=𝑣𝑝,𝑖−1+Δ𝑡(−3𝑅𝐶𝑣𝑝,𝑖−1−1(𝑅𝐶)2𝑣𝑖−1+1𝑅𝐶𝑠𝑝,𝑖)𝑣𝑖=𝑣𝑖−1+Δ𝑡𝑣𝑝,𝑖−1
Coup de pouce 1
La relation de Taylor stipule que 𝑠(𝑡+Δ𝑡)≈𝑠(𝑡)+Δ𝑡d𝑠d𝑡.
Coup de pouce 2
Transformer la relation de Taylor en relation de récurrence en utilisant la définition de 𝑠𝑖, 𝑣𝑖, 𝑠𝑝,𝑖 et 𝑣𝑝,𝑖.

4/ Compléter le code suivant permettant de simuler numériquement l’évolution des tensions dans l’oscillateur de Wien.

import numpy as np

R1 = 1000# Ohm
R2 = 2001# Ohm
C = 1E-6# F
R = 1000# Ohm

T = ...# s période présumée

Dt = T/100# s pas de temps
tmax = 100*T# s durée de la simulation

N = int(tmax//dt)# nombre de points de la simulation

t = np.linspace(0,tmax, N)# tableau des temps
v = np.zeros(N)# V tableau des tensions v
vp = np.zeros(N)# V/s dérivée de v
s = np.zeros(N)# V tableau des tensions s
sp = np.zeros(N)# V/s dérivée de s

v[0] = 0.1 # petite perturbation initiale

for i in range(1,N):# Calcul de s et v au cours du temps grâce à la méthode d'Euler
    s[i] = (1+R2/R1)*v[i-1]
    sp[i] = ...
    vp[i] = ...
    v[i] = ...
Coup de pouce 1
A quelle période oscille l’oscillateur de Wien lorsque la condition d’oscillation est satisfaite ?
Coup de pouce 2
Utiliser les relations de récurrence obtenues à la question précédente.
Corrigé
import numpy as np

R1 = 1000# Ohm
R2 = 2001# Ohm
C = 1E-6# F
R = 1000# Ohm

T = 2*np.pi*R*C# s période présumée

Dt = T/100# s pas de temps
tmax = 100*T# s durée de la simulation

N = int(tmax//dt)# nombre de points de la simulation

t = np.linspace(0,tmax, N)# tableau des temps
v = np.zeros(N)# V tableau des tensions v
vp = np.zeros(N)# V/s dérivée de v
s = np.zeros(N)# V tableau des tensions s
sp = np.zeros(N)# V/s dérivée de s

v[0] = 0.1 # petite perturbation initiale

for i in range(1,N):# Calcul de s et v au cours du temps grâce à la méthode d'Euler
    s[i] = (1+R2/R1)*v[i-1]
    sp[i] = (s[i] - s[i-1])/dt
    vp[i] = vp[i-1] + dt*(-3/(R*C)*vp[i-1] - 1/(R*C)**2*v[i-1] + 1/(R*C)*sp[i])
    v[i] = v[i-1] + dt*vp[i-1]

La saturation de l’amplificateur n’a pas encore été prise en compte. Une vérification doit être introduite entre les lignes 24 et 25 du code précédent pour s’assurer que la tension de sortie de l’amplificateur ne dépasse pas la tension de saturation 𝑉sat.

5/ Compléter les lignes à introduire entre les lignes 24 et 25 du code précédent pour prendre en compte la saturation de l’amplificateur.

if s[i] > Vsat :
    s[i] = ...
elif s[i] < -Vsat :
    s[i] = ...
Coup de pouce 1
La tension de sortie de l’amplificateur ne peut pas dépasser la tension de saturation 𝑉sat. Si c’est le cas dans la simulation, il faut la ramener à 𝑉sat.
Corrigé
if s[i] > Vsat :
    s[i] = Vsat
elif s[i] < -Vsat :
    s[i] = -Vsat

On souhaite maintenant visualiser les résultats de la simulation. Pour cela, on peut utiliser la bibliothèque matplotlib pour tracer les tensions 𝑠(𝑡) et 𝑣(𝑡) en fonction du temps.

6/ Compléter le code suivant pour tracer les tensions 𝑠(𝑡) et 𝑣(𝑡) en fonction du temps.

import matplotlib.pyplot as plt

plt.figure(1)
plt.clf()
plt.plot(..., label='s(t)')
plt.plot(..., label='v(t)')
plt.xlabel('Temps (s)')
plt.ylabel('Tension (V)')
plt.legend()
plt.grid()
plt.show()
Corrigé
import matplotlib.pyplot as plt

plt.figure(1)
plt.clf()
plt.plot(t, s, label='s(t)')
plt.plot(t, v, label='v(t)')
plt.xlabel('Temps (s)')
plt.ylabel('Tension (V)')
plt.legend()
plt.grid()
plt.show()

En théorie, on s’attend à ce que la tension 𝑣 soit “plus sinusoïdale” que la tension 𝑠. Pour vérifier cela, on peut effectuer une transformée de Fourier sur les signaux simulés et comparer les spectres obtenus.

Le code suivant permet de calculer et de tracer les spectres des signaux 𝑠(𝑡) et 𝑣(𝑡).

vTF = np.abs(np.fft.rfft(v)) # calcul du spectre de v
vTF = vTF/vTF.max() # normalisation du spectre pour pouvoir le comparer à celui de s
sTF = np.abs(np.fft.rfft(s)) # calcul du spectre de s
sTF = sTF/sTF.max() # normalisation
fréquences = np.fft.rfftfreq(N, dt) # calcul des fréquences associées aux spectres

plt.figure(2)
plt.clf()
plt.plot(fréquences, sTF, label="spectre de s")
plt.plot(fréquences, vTF, label="spectre de v")
plt.legend())
plt.xlabel("fréquence (Hz)")
plt.ylabel("spectre (sans unité)")
plt.show()

7/ Parmi les deux signaux, lequel a des harmoniques les plus grandes ? Est-ce conforme à ce que l’on attendait ? Quel est l’impact de 1+𝑅2𝑅1 sur le spectre ?

Corrigé

Le spectre de 𝑠 a des harmoniques plus grandes que celui de 𝑣. Cela est conforme à ce que l’on attendait, car la tension 𝑣 est filtrée par le filtre de Wien, ce qui réduit les harmoniques.

Plus 1+𝑅2𝑅1 est grand, plus les harmoniques de 𝑠 et 𝑣 sont importantes et plus les signaux s’éloignent de sinusoïdes.