Travail Collaboratif : Analog Filter#

Acquis d’Apprentissage Visés#

  • AAv1 (Étude de circuits électronique d’ordre 2) : A l’issue du 4e semestre d’électronique, l’étudiant sera capable de déterminer sous forme analytique ou numérique les paramètres caractéristiques d’un circuit du 2nd ordre en fonction de la valeur de ses composants en déterminant au préalable sa fonction de transfert. Les paramètres caractéristiques comprennent:

    • le type de filtre;

    • le coefficient d’amplification;

    • la fréquence propre;

    • le coefficient d’amortissement.

  • AAv4 (Design) : A l’issue du 4e semestre d’électronique, l’étudiant sera capable de proposer un circuit respectant un cahier des charges. Le cahier des charges sera spécifié sous la forme soit par de plusieurs paramètres caractéristiques d’une cellule d’ordre 2 (type, coefficient d’amplification, fréquence propre, coefficient d’amortissement) ou soit par un gabarit fréquentiel. L’étudiant sera en mesure de vérifier la conformité de sa proposition avec le cahier des charges en utilisant un logiciel de simulation (Python/Numpy/Scipy et LTspice).

Description du travail#

Objectifs#

Dans ce travail, nous souhaitons développer des fonctions Python pour analyser des circuits d’ordre 2. Pour chaque filtre d’ordre 2, nous souhaitons traiter les problèmes suivants :

  1. Calcul de la fonction de transfert, puis écriture sous forme normalisée,

  2. Implémentation d’une fonction lti permettant d’obtenir la fonction de transfert en Python à partir des composants,

  3. Implémentation d’une fonction get_params permettant d’obtenir les paramètres de la fonction de transfert,

  4. Implémentation d’une fonction get_components permettant d’obtenir les composants du filtre à partir des paramètres.

  5. Validation sur LTSpice

Fonctions de transfert normalisées#

  • Passe-bas (LP)

\[H(p)=\frac{T_0}{\frac{1}{\omega_0^2}p^2+\frac{2m}{\omega_0}p+1}​\]
  • Passe-bande (BP)

\[H(p)=\frac{\frac{2mT_m}{\omega_0}p}{\frac{1}{\omega_0^2}p^2+\frac{2m}{\omega_0}p+1}​\]
  • Passe-haut (HP)

\[H(p)=\frac{\frac{T_{\infty}}{\omega_0^2}p^2}{\frac{1}{\omega_0^2}p^2+\frac{2m}{\omega_0}p+1}​\]

Exemple#

Dans cet exemple, nous allons considérer l’analyse complète du circuit suivant :

Filter

RLC_BP3 Filter#

Fonction de transfert#

En utilisant le pont diviseur de tension, nous obtenons

\[V_s(p) = \frac{Z_{eq}}{R_2+Z_{eq}}V_e(p) \Rightarrow \frac{V_s(p)}{V_e(p)} = \frac{1}{1+\frac{R_2}{Z_{eq}}}\]

\[\frac{1}{Z_{eq}} = \frac{1}{Z_L}+\frac{1}{Z_{R_1}}+\frac{1}{Z_c}=\frac{1}{Lp}+\frac{1}{R_1}+Cp\]

Il en vient que :

\[H(p)= \frac{\frac{L}{R_2}p}{1+L(\frac{R_1+R_2}{R_1R_2})p+LCp^2}\]

Implémentation#

Fonction lti_RLC_BP3#

Pour implémenter la fonction de transfert, nous pouvons utiliser la fonction lti du module scipy.

import numpy as np
from scipy.signal import lti


def lti_rlc_bp3(L, C, R1, R2):
    """
    Create the transfer function for the RLC_BP3 filter.

    Parameters
    ----------
    L : float
    C : float
    R1 : float
    R2 : float

    Returns
    -------
    system : an instance of the LTI class
    """

    num = [L/R2,0]
    den = [L*C, L*(R1+R2)/(R1*R2), 1]
    return lti(num, den)

Fonction get_params#

En identifiant la fonction de transfert avec la fonction de transfert normalisée d’un passe-bande, nous obtenons :

\[H(p)=\frac{\frac{2mT_m}{\omega_0}p}{\frac{1}{\omega_0^2}p^2+\frac{2m}{\omega_0}p+1}​\]

avec

\[\begin{split}w_0 &= \frac{1}{\sqrt{LC}}\\ m &= \frac{1}{2}\left(\frac{R_1+R_2}{R_1R_2}\right)\sqrt{\frac{L}{C}}\\ T_{m} &= \frac {R_1} {R_1 + R_2}\end{split}\]
def get_params(L, C, R1, R2):
    """
    Compute the maximum gain, the angular frequency and the damping factor of the RLC_BP3 filter.

    Parameters
    ----------
    L : float
    C : float
    R1 : float
    R2 : float

    Returns
    -------
    Type: string
    Tm : float
    w0 : float
    m : float
    """

    Tm = R1 / (R1+R2)
    w0 = 1/ np.sqrt(L*C)
    m = 0.5*((R1+R2)/(R1*R2))*np.sqrt(L/C)
    return "BP", Tm, w0, m

Fonction get_components#

Comme nous avons 3 équations et 4 composants, nous devons fixer un composant. En fixant la bobine L, nous obtenons alors les équations suivantes :

\[\begin{split}C &=\frac{1}{L \omega_0^2}\\ R_2 &=\frac{1}{2 m T_{m}}\sqrt{\frac{L}{C}}\\ R_1 &= \frac{R_2 T_{m}}{1 - T_{m}}\\\end{split}\]
def get_components(Tm, w0, m, L):
    """
    Returns the circuit components from the filter parameters.

    Parameters
    ----------
    Tm : float
    w0 : float
    m : float
    L : float

    Returns
    -------
    C : float
    R1 : float
    R2 : float
    """

    C = 1 / (L*(w0**2))
    R2 = (1/(2*m*Tm))*np.sqrt(L/C)
    R1 = (R2*Tm) / (1-Tm)
    return C, R1, R2

Approche Objet#

Au lieu de définir des fonctions, il est d’adopter une approche objet afin de gagner en organisation, clarté et modularité. Il est également possible d’implémenter des tests unitaires pour vérifier le bon comportement de notre classe.

Classe RLC_BP3_Filter#

Pour implémenter notre classe, nous allons créer le fichier filter_RLC.py contenant le code suivant.

 1import numpy as np 
 2from scipy.signal import lti
 3
 4
 5class RLC_BP3_Filter():
 6
 7    def __init__(self, R1, R2, C, L):
 8        """
 9        Constructor
10        """
11        self.R1 = R1 
12        self.R2 = R2 
13        self.C = C 
14        self.L = L
15
16    def lti(self):
17        """
18        Create the transfer function for the filter.
19
20        Returns
21        -------
22        system : an instance of the LTI class 
23        """
24        num = [self.L/self.R2,0]
25        den = [self.L*self.C, self.L*(self.R1+self.R2)/(self.R1*self.R2), 1]
26        return lti(num, den)    
27
28    def get_params(self):
29        """
30        Compute the maximum gain, the angular frequency and the damping factor of the filter.
31        
32        Returns
33        -------
34        Tm : float 
35        w0 : float 
36        m : float
37        """
38        Tm = self.R1 / (self.R1+self.R2)
39        w0 = 1/ np.sqrt(self.L*self.C)
40        m = 0.5*((self.R1+self.R2)/(self.R1*self.R2))*np.sqrt(self.L/self.C)
41        return "BP", Tm, w0, m
42    
43    def set_components(self, Tm, w0, m):
44        """
45        Set the circuit components C, R1 et R2 from the filter parameters and the attribute L
46
47        Parameters
48        ----------
49        Tm : float 
50        w0 : float 
51        m : float
52        """
53
54        C = 1 / (self.L*(w0**2)) 
55        R2 = (1/(2*m*Tm))*np.sqrt(self.L/C)
56        R1 = (R2*Tm) / (1-Tm)
57        self.R2 = R2 
58        self.R1 = R1
59        self.C = C

Test unitaire#

Pour valider le bon fonctionnement de la classe, il est possible de réaliser un test unitaire. Un test unitaire est une méthode de test de logiciel où des unités individuelles (ou composants) d’un logiciel sont testées séparément pour s’assurer qu’elles fonctionnent correctement. L’objectif est d’isoler chaque partie du programme et de vérifier qu’elle fonctionne comme prévu.

En python, les tests unitaires peuvent être réalisés facilement avec le framework unitests. Dans notre cas, nous allons créer le fichier test_filter_RLC.py contenant le code suivant.

 1import unittest
 2from filter_RLC import RLC_BP3_Filter
 3
 4class TestRLC_BP3_Filter(unittest.TestCase):
 5
 6    def setUp(self):
 7        self.L = 10**-3
 8        self.Tm_ref, self.w0_ref, self.m_ref = 0.5, 10*3, 0.2
 9        self.my_filter = RLC_BP3_Filter(10**3, 10**3, 10**-9, self.L)
10
11    def test_set_and_get_params(self):
12        self.my_filter.set_components(self.Tm_ref, self.w0_ref, self.m_ref)
13        _, Tm, w0, m = self.my_filter.get_params()
14
15        self.assertAlmostEqual(Tm, self.Tm_ref, places=20)
16        self.assertAlmostEqual(w0, self.w0_ref, places=20)
17        self.assertAlmostEqual(m, self.m_ref, places=20)
18
19
20if __name__ == "__main__":
21    unittest.main()

Pour tester le bon fonctionnement de la classe RLC_BP3_Filter, il suffit ensuite de lancer le script python suivant

python test_filter_RLC.py

Liste des circuits#

Note

Chaque étudiant devra choisir un filtre passif et un filtre actif.

Circuits RC/RC#

RC RC LP

RC/RC LP Filter#

RC RC BP

RC/RC BP Filter#

RC RC HP

RC/RC HP Filter#

Circuits RLC#

RLC LP

RLC LP Filter#

RLC BP1

RLC BP1 Filter#

RLC BP2

RLC BP2 Filter#

RLC HP

RLC HP Filter#

Circuits Sallen Key#

SK LP

SK LP Filter#

SK HP

SK HP Filter#

Circuits Rauch#

MFB LP

MFB LP Filter#

MFB BP

MFB BP Filter#

MFB BP2

MFB BP2 Filter#

MFB HP

MFB HP Filter#