Conclusion

La méthode retenue pour le mesurage[1] des grandeurs i et u a été celle consistant à utiliser un micro-contrôleur Arduino commandé par un programme en Python. Des mesures de tension à l'aide d'un multimètre numérique 2000 points n'ont pas montré de décalage significatif entre les mesures issues des deux méthodes de mesurage. En revanche, il convient de raisonner sur la valeur de la résistance étalon permettant d'accéder à la grandeur intensité du courant. Si la résistance étalon est trop faible par rapport à la résistance totale des dipôles en série, alors la mesure de la tension à ses bornes ne sera que quelques dizaines de fois la valeur du pas du CAN. L'erreur sur la mesure de i peut être importante. Un multimètre numérique dispose de plusieurs résistances étalons selon le calibre utilisé pour la mesure de l'intensité (20 mA, 200 mA, 2000 mA, 10 A...)

Le programme Python est tout à fait perfectible. Il ne réalise pas la validité des données saisies par l'opérateur, ce qui est une source de plantage. Les caractéristiques produites méritent d'être mieux légendées, nuage de points et modèle.

1
# Créé par Gilles Claudel, le 21/11/2018 en Python 3.4
2
from commandesPython import Arduino
3
import time
4
import os
5
import matplotlib.pyplot as plt
6
import numpy as np
7
import scipy.stats as st
8
9
def fichImage(ref, nb):
10
    os.makedirs("u=f(i)",exist_ok=True)
11
    image = "u=f(i)/caracteristique_R" + ref + "_n" + str(nb) + "_modelisee.png"
12
    plt.savefig(image, dpi=300)	#sauvegarde du fichier image de la caractéristique u = f(i)
13
    return(0)
14
	
15
def fichMes(ref, nb, i, u):
16
    os.makedirs("mesures",exist_ok=True)
17
    fichier = "mesures/fichier_R" + ref + "_n" + str(nb) + ".txt"
18
    mes_mesures = open(fichier, "w")	#création ou écrasement d'un fichier ouvert en écriture
19
    j = 0
20
    mes_mesures.write("i (A),u (V)\n") #entête du fichier de mesure
21
    
22
    while j < nb:
23
        mes_mesures.write(str(i[j]/1000)+","+str(u[j])+"\n")	#Le séparateur est la virgule pour Geogebra
24
        j = j + 1
25
    
26
    mes_mesures.close()	#fermeture du fichier texte
27
    return(0)
28
29
def incertitudeType_u (i, u, a, b, n):
30
    src = 0
31
    for k in range(n):
32
        src = src + (u[k]-(a*i[k]+b))**2    #résidu au carré
33
    sigma_u = np.sqrt(1/(n-2)*src)
34
    return sigma_u
35
36
def notation(valeur, erreur, cs):
37
    n = int(np.log10(valeur))
38
    a = round(valeur/10**n,cs)
39
    err = round(erreur/10**n,cs)
40
    sortie = "\\left("+str(a)+" \\pm"+str(err)+" \\right) \\times 10^{"+str(n)+"}"
41
    return sortie
42
	
43
k=0
44
u=[]
45
i=[]
46
R=[]
47
48
port = "COM3"			#à modifier si besoin
49
ard = Arduino(port)		#La classe Arduino permet de communiquer via le port série avec le micro-contrôleur
50
51
#On teste les saisies et on vérifie si ce sont bien des nombres
52
dipole = input("Valeur de référence de la résistance ?\n")
53
54
while True:
55
    try:
56
        r = float(input("Valeur de la résistance étalon pour la mesure de l'intensité ?\n"))
57
        break
58
    except ValueError:
59
        print("Entrez un nombre.")
60
61
while True:
62
    try:
63
        n = int(input("Nombre de mesures ?\n"))
64
        break
65
    except ValueError:
66
        print("Entrez un nombre entier.")
67
68
print("Faire varier l'intensité du courant dans le dipôle pendant environ 5 secondes")
69
70
time.sleep(0.5)
71
#Période d'échantillonnage
72
T_e = 5.0/n	#durée entre deux mesures telle que la durée totale soit de 5 s
73
74
while k < n:
75
    sensorU2 = ard.analogRead(0)	#La lecture d'une entrée analogique et sa conversion A/N : ce n'est pas instantané
76
    time.sleep(0.001)
77
    sensorUr = ard.analogRead(1)
78
    time.sleep(0.001)
79
    sensorGND = ard.analogRead(2)
80
    time.sleep(0.001)
81
82
    u.append(((sensorU2-sensorUr)/1023.0)*5.0)      #u en V : u = u_2 - u_r
83
    i.append(((sensorUr-sensorGND)/1.023)*5.0/r)    #i en mA : i = u_r / r
84
85
    k = k + 1
86
    time.sleep(T_e)
87
88
ard.close()		#Après n mesures, on libère le port de communication
89
90
#
91
# Travail de l'élève
92
# - représenter un nuage de points associé à la caractéristique du dipôle
93
# - modéliser la caractéristique de ce dipôle
94
#
95
96
# Création du fichier texte de mesures pour une 1re exploitation dans Geogebra
97
    
98
fichMes(dipole, n , i, u)
99
time.sleep(1)
100
101
# On vide les listes i et u
102
i = []
103
u = []
104
# On rouvre le fichier
105
file = "mesures/fichier_R" + dipole + "_n" + str(n) + ".txt"
106
i,u = np.loadtxt(file, delimiter=',', skiprows=1, unpack='true')
107
108
titre = "Caractéristique courant/tension d'un dipôle ohmique"
109
110
titreX = "intensité en mA"
111
titreY = "tension en V"
112
# arrondi au milliampère supérieur de la valeur maximale de i
113
i_max = 1000*np.ceil(10**np.ceil(-np.log10(np.max(i)))*np.max(i))*10**np.floor(np.log10(np.max(i)))
114
u_max = np.ceil(np.max(u))     #arrondi au volt supérieur de la valeur maximale de u
115
116
# Etude statistique
117
118
a, b, r_value, p_value, std_err = st.linregress(i, u)
119
120
i_mod = np.concatenate((i,[0.0, i_max]))
121
modele = np.concatenate((a*i+b,[b, a*i_max+b]))
122
123
soustitre = "u = "+ str(round(a,0)) + " i +" + str(round(b,2))
124
legende = r"$R="+notation(a, std_err, 2)+"\;\Omega$"
125
t = 0.6*i_max  #abscisse de la légende
126
127
# Nuage de points à partir des première et deuxième colonnes du fichier texte
128
# Tracé du modèle linéaire
129
# On convertit l'intensité en mA
130
131
plt.scatter(1000*i, u, marker='+')    # i en mA, car i est en A dans le fichier texte
132
133
yErrorValues = [incertitudeType_u(i, u, a, b, n) for m in range(n)]
134
plt.errorbar(1000*i, u, yerr = yErrorValues, fmt = 'none', capsize = 2, elinewidth = 1, ecolor = 'green', zorder = 1)
135
136
plt.plot(1000*i_mod, modele, c='r', label='modèle linéaire')
137
138
plt.suptitle(titre)
139
plt.title(soustitre)
140
plt.xlabel(titreX)
141
plt.ylabel(titreY)
142
plt.axis([0,i_max,0,u_max])
143
144
# On annote le modèle en précisant la pente et son incertitude-type
145
plt.annotate(legende,xy=(t, a*t/1000+b), xycoords='data',xytext=(-150, +50), textcoords='offset points', fontsize=14, arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
146
147
# Sauvegarde en image de la caractéristique
148
fichImage(dipole, n)
149
150
plt.show()
151
152
plt.close()

L'archive contient les trois programmes (deux en Python et un en C++), des exemples de caractéristiques et le fichier Geogebra.

Le choix du tableur de Geogebra nous a semblé pertinent. L'outil est libre ; il est performant au niveau de l'analyse statistique, adapté aux programmes de mathématiques de lycée et permet de simuler les comportements des dipôles. Des activités hors la classe, tutorées, utilisant un groupe Geogebra sont un moyen de poursuivre l'activité au-delà de la séance.

Pour revenir aux objectifs d'apprentissage, l'activité se veut différente de ce que les élèves de collège ont pu faire autour de la loi d'Ohm et met l'accent sur la mesure et les incertitudes associées avec une approche qualitative et grandement étayée par les outils numériques. Elle est réalisable sur une séance d'une heure et vingt-cinq minutes à la condition que les élèves ne découvrent pas le langage Python. Une capsule vidéo leur montrant, en amont, comment relier des composants sur la breadboard à partir d'un schéma est souhaitable.

Mesure et incertitudes, la loi d'Ohm en seconde

Représenter la caractéristique d'un dipôle et son modèle à l'aide d'un langage de programmation (Python).

La vidéo décrit l'utilisation du microcontrôleur, du programme Python et des outils d'analyse statistique : Geogebra.