Laboratoire 4 ============= Les notions abordées dans ce laboratoire sont les suivantes : * Mathématiques : - le reste de la division de nombres réels, - la foncion sinus. * Physique : - la tension et le courant, - la loi d'Ohm, - la relation entre la tension aux bornes d'un condensateur et le courant qui le "traverse", - le circuit RC, - la puissance. Programmes 6 : La loi d'Ohm -------------------------------- Nous allons à présent utiliser un oscilloscope pour étudier le comportement de quelques circuits électroniques. Le premier circuit que nous allons considérer est celui-ci : .. figure:: figures/circuit-r.png :scale: 100% :align: center :alt: Circuit R. Circuit R. Ce circuit est composé : - d'un générateur de tension sinusoïdale, d'amplitude 5 V et de fréquence 111 Hz. - d'une résistance :math:`R` de 2 :math:`\Omega` connectée aux bornes de ce générateur. - d'un ampèremètre ('A') mesurant le courant :math:`I` traversant la résistance. - d'un voltmètre ('V') mesurant la tension :math:`V` aux bornes de la résistance. L'idée consiste à utiliser l'oscilloscope pour observer trois signaux : - La tension :math:`V`. - Le courant :math:`I`. - La puissance :math:`P` dissipée dans la résistance. **Remarque :** Pour ce circuit, le quatrième signal ne sera pas utilisé; pour ne pas qu'il s'affiche, on lui attribuera une valeur constante qui sort de la fenêtre, par exemple 100. Procédure à suivre : 1. Recopier le programme de l'oscilloscope dans un nouveau programme ``prog-6.py``. Code de l'oscilloscope:: import math import pygame import sys # Fonctions def dessiner_pointilles_h(surface, couleur, y): n = dimensions_fenetre[0] // (longueur_pointille * 2) for i in range(n + 1): x1 = int((i - 0.25) * longueur_pointille * 2) x2 = x1 + longueur_pointille pygame.draw.line(surface, couleur, (x1, y), (x2, y)) return def dessiner_pointilles_v(surface, couleur, x): n = dimensions_fenetre[1] // (longueur_pointille * 2) for i in range(n + 1): y1 = (i - 0.25) * longueur_pointille * 2 y2 = y1 + longueur_pointille pygame.draw.line(surface, couleur, (x, y1), (x, y2)) return def afficher_grille(): yc = dimensions_fenetre[1] // 2 nh = yc // taille_grille for i in range(1, nh + 1): dessiner_pointilles_h(fenetre, GRIS, yc + i * taille_grille) dessiner_pointilles_h(fenetre, GRIS, yc - i * taille_grille) pygame.draw.line(fenetre, GRIS, (0, yc), (dimensions_fenetre[0], yc)) nv = dimensions_fenetre[0] // taille_grille for i in range(0, nv + 1): dessiner_pointilles_v(fenetre, GRIS, i * taille_grille) return def generer_signaux(delta_t): PERIODE_1 = 0.009 PERIODE_2 = 0.003 PERIODE_3 = 0.0015 PERIODE_4 = 0.0045 AMPL_1 = 10 AMPL_2 = 5 AMPL_3 = 3 AMPL_4 = 2 global signaux_initialises, a1, a2, a3, a4 if not signaux_initialises: a1 = 0 a2 = 0 a3 = 0 a4 = 0 signaux_initialises = True return (0, 0, 0, 0) a1 = math.fmod(a1 + delta_t * 2 * math.pi / PERIODE_1, 2 * math.pi) a2 = math.fmod(a2 + delta_t * 2 * math.pi / PERIODE_2, 2 * math.pi) a3 = math.fmod(a3 + delta_t * 2 * math.pi / PERIODE_3, 2 * math.pi) a4 = math.fmod(a4 + delta_t * 2 * math.pi / PERIODE_4, 2 * math.pi) return (AMPL_1 * math.cos(a1), AMPL_2 * math.cos(a2), AMPL_3 * math.cos(a3), AMPL_4 * math.cos(a4)) def acquisition(t): global acquisition_initialisee, t_signaux_prec if acquisition_initialisee: dt = t - t_signaux_prec if dt <= 0: print("erreur de timing") sys.exit() while dt > t_echantillons: generer_signaux(t_echantillons) dt -= t_echantillons s = generer_signaux(dt) else: s = (0, 0, 0, 0) acquisition_initialisee = True t_signaux_prec = t return s def afficher_signal(x, v, couleur, gain): y = dimensions_fenetre[1] // 2 - v * gain pygame.draw.line(fenetre, couleur, (x, y - 5), (x, y + 5)) return def afficher_trame(temps_maintenant): signaux_prec = acquisition(temps_maintenant) for x in range(dimensions_fenetre[0]): temps_maintenant += t_echantillons signaux = acquisition(temps_maintenant) if (signaux[0] >= seuil_trigger and signaux_prec[0] < seuil_trigger): break signaux_prec = signaux for x in range(dimensions_fenetre[0]): temps_maintenant += t_echantillons signaux = acquisition(temps_maintenant) for i in range(4): afficher_signal(x, signaux[i], couleur_signaux[i], gain_signaux[i]) return def afficher_trigger(): y = dimensions_fenetre[1] // 2 - seuil_trigger * gain_signaux[0] pygame.draw.line(fenetre, ROUGE, (0, y), (20, y), 5) return # Constantes BLEUCLAIR = (127, 191, 255) CYAN = (0, 255, 255) GRIS = (127, 127, 127) JAUNE = (255, 255, 0) MAGENTA = (255, 0, 255) ROUGE = (255, 0, 0) VERT = (0, 255, 0) # Paramètres dimensions_fenetre = (800, 600) # en pixels images_par_seconde = 25 taille_grille = 100 longueur_pointille = 10 t_trame = 0.010 t_echantillons = t_trame / dimensions_fenetre[0] seuil_trigger = 5 seuil_trigger_delta = 0.2 couleur_signaux = [ JAUNE, CYAN, MAGENTA, VERT ] gain_signaux = [ 20, 20, 20, 20 ] # Initialisation pygame.init() fenetre = pygame.display.set_mode(dimensions_fenetre) pygame.display.set_caption("Programme 4") horloge = pygame.time.Clock() couleur_fond = BLEUCLAIR pygame.key.set_repeat(10, 10) acquisition_initialisee = False signaux_initialises = False # Dessin while True: for evenement in pygame.event.get(): if evenement.type == pygame.QUIT: pygame.quit() sys.exit() elif evenement.type == pygame.KEYDOWN: if evenement.key == pygame.K_UP: seuil_trigger += seuil_trigger_delta elif evenement.key == pygame.K_DOWN: seuil_trigger -= seuil_trigger_delta temps_maintenant = pygame.time.get_ticks() / 1000 fenetre.fill(couleur_fond) afficher_trame(temps_maintenant) afficher_trigger() afficher_grille() pygame.display.flip() horloge.tick(images_par_seconde) 2. Modifier la fonction ``generer_signaux()`` : - Le premier signal, correspondant à la tension :math:`V`, doit être un signal périodique similaire à ceux du programme 4, d'amplitude 5 V et de fréquence 111 Hz. - Le deuxième signal, représentant le courant :math:`I`, peut se calculer à partir de :math:`V` grâce à la loi d'Ohm pour la résistance: .. math:: V = R \times I. - Le troisième signal, égal à la puissance dans la résistance, vaut .. math:: P = V \times I. - Comme discuté précédemment, le quatrième signal prend la valeur constante 100 de façon à ne pas être visible dans la fenêtre. 3. Essayer votre programme. Le résultat correspond-t-il à ce que vous attendiez? 4. Lorsque le programme fonctionne, le déposer sur la platforme de soumission, avec le suffixe ``prog-6.py``. Pour la suite de ce programme, nous allons simuler une variante du circuit précédent : .. figure:: figures/circuit-r-square.png :scale: 100% :align: center :alt: Circuit R avec signal carré. Circuit R avec signal carré. La seule différence est que le générateur produit maintenant un signal *carré* d'amplitude 5 V et de fréquence 222 Hz. Cela signifie que ce signal est égal à 5 V pendant la moitié de sa période, et à 0 V pendant l'autre moitié. Les modifications à apporter à votre code pour remplacer le signal sinusoïdal par ce signal carré devraient être minimales. (En particulier, le calcul des valeurs de :math:`I` et de :math:`P` devraient rester inchangés.) Le programme fournit-il le résultat attendu? Si oui, déposez-le sur la platforme de soumission, avec le suffixe ``prog-6-square.py``. Programmes 7 : Circuit RC ------------------------------ Dans cette dernière étape, nous étudierons un *circuit RC*, faisant intervenir une résistance et un condensateur. Son schéma est le suivant : .. figure:: figures/circuit-rc-square.png :scale: 100% :align: center :alt: Circuit RC. Circuit RC. Nous nous intéressons à quatre signaux : - La tension :math:`V_1` produite par le générateur, qui prend comme pour le programme 6 la forme d'un signal carré de fréquence 222 Hz. - La tension :math:`V_2` aux bornes du condensateur. - Le courant :math:`I` traversant la résistance et le condensateur (mesuré par l'ampèremètre 'A'). - La puissance :math:`P` échangée avec le condensateur. Les modifications à apporter au programme 6 sont les suivantes (effectuez-les dans un nouveau programme ``prog-7.py``). Dans la fonction ``generer_signaux()`` : - La tension :math:`V_1` est générée de la même façon que la tension :math:`V` dans le programme 6 version ``square``. - La tension :math:`V_2` dépend du niveau de charge du condensateur. Le plus simple consiste à représenter cette tension par une nouvelle variable globale ``tension_condensateur`` qui sera gérée par la fonction ``generer_signaux()``. Initialement, on peut considérer que cette tension est nulle (c'est-à-dire, que le condensateur est déchargé au début de la simulation). - A partir de :math:`V_1` et de :math:`V_2`, le courant :math:`I` peut se calculer en appliquant la loi d'Ohm aux bornes de la résistance: .. math:: I = \frac{V_1 - V_2}{R}. - La valeur du courant :math:`I` permet de mettre à jour la tension du condensateur, celui-ci se chargeant si :math:`I` est positif et se déchargeant s'il est négatif; Pendant le pas de temps :math:`\textit{dt}` de la simulation, la tension :math:`V_2` (mémorisée dans ``tension_condensateur``) doit évoluer selon la loi : .. math:: V_2 \,\leftarrow\, V_2 + \frac{I\textit{dt}}{C}. - La puissance échangée avec le condensateur est donnée par le produit .. math:: P = V_2 \times I. **Note importante :** Pour que les signaux 3 et 4 soient visibles, vous devez modifier le gain qui leur est appliqué dans le programme. Pour les valeurs proposées des composants, un gain de 20000 pour ces deux signaux produit un bon résultat. Après avoir implémenté ces modifications dans votre programme, qu'observez-vous? N'hésitez pas à expérimenter en modifiant la valeur de R et de C. Les signaux obtenus correspondent-ils à ce que prévoit la théorie? Une fois que votre programme est au point, déposez-le dans le répertoire des laboratoires, avec le suffixe ``prog-7.py``. Il reste à présent à simuler le même circuit, mais avec un générateur sinusoïdal : .. figure:: figures/circuit-rc-sin.png :scale: 100% :align: center :alt: Circuit RC avec signal sinusoïdal. Circuit RC avec signal sinusoïdal. Les modifications à apporter au programme sont simples. Cette fois, avant de les effectuer et de tester l'application, essayez de dessiner sur une feuille de papier la forme des quatre signaux qui devraient être obtenus. Comparez ensuite vos prédictions avec le résultat de l'expérience. Déposez enfin votre programme dans le répertoire centralisé, avec le suffixe ``prog-7-sin.py``.