9. ANNEXES▲
9-1. Arduino RGB▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
/* Broches */
const int LED_R = 8;
const int LED_G = 9;
const int LED_B = 10;
void setup() { 
    // Initialise les broches 
    pinMode(LED_R, OUTPUT); 
    pinMode(LED_G, OUTPUT);
    pinMode (LED_B, OUTPUT);
}
void loop() {
    // 1 seconde par couleur
    digitalWrite(LED_R, HIGH);
    delay(1000);
    digitalWrite (LED_R, LOW);
    digitalWrite (LED_G, HIGH);
    delay(1000);
    digitalWrite (LED_G, LOW);
    digitalWrite (LED_B, HIGH);
    delay(1000);
    digitalWrite (LED_B, LOW);
}
9-2. Arduino JCMB▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
/* Broches */ 
const int LED_R = 8; 
const int LED_G = 9; 
const int LED_B = 10; 
void setup() { 
    // Initialise les broches 
    pinMode(LED_R, OUTPUT); 
    pinMode(LED_G, OUTPUT);
    pinMode (LED_B, OUTPUT);
}
void loop() {
    digitalWrite (LED_R, HIGH);
    digitalWrite (LED_G, HIGH);
    delay(1000);
    digitalWrite (LED_R, LOW);
    digitalWrite (LED_B, HIGH);
    delay(1000);
    digitalWrite (LED_G, LOW);
    digitalWrite (LED_R, HIGH);
    delay(1000);
    digitalWrite (LED_G, HIGH);
    delay(1000);
    digitalWrite (LED_R, LOW);
    digitalWrite (LED_G, LOW);
    digitalWrite (LED_B, LOW);
}
9-3. Arduino intensité d'un canal▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
/* Broches */
const int LED_R = 8;
const int LED_G = 9;
const int LED_B = 10;
void setup() {
    // Initialise les broches
    pinMode(LED_R, OUTPUT);
    pinMode(LED_G, OUTPUT);
    pinMode(LED_B, OUTPUT);
}
void loop() {
    analogWrite (LED_G, 0);
    delay(1000);
    analogWrite (LED_G, 75);
    delay(1000);
    analogWrite (LED_G, 125);
    delay(1000);
    analogWrite (LED_G, 250);
    delay(1000);
}
9-4. La photorésistance▲
Le code Arduino
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
const int broche = A0;
void setup() {
    Serial.begin(19200);
}
void loop() {
    int valeur = analogRead (broche);
    Serial.print(valeur);
    Serial.print("\t");
    Serial.println(millis());
}

On ne conserve que les valeurs exploitables. On rappelle qu'il est possible de n'utiliser qu'une partie des valeurs d'une liste, soit L une liste, alors on écrit : L[debut, fin]. Dans notre exemple, on peut essayer de démarrer à partir de la valeur d'index 50 en gardant toutes les valeurs suivantes, ce qui donne : temps[50:]. À vous d'ajuster en fonction de ce que vous obtenez.
2.
3.
4.
5.
6.
7.
8.
# attention les deux listes doivent contenir le même nombre de valeurs.
plt.plot(temps[50:], mesure[50:])
plt.title("Fréquence d'un stroboscope")
plt.ylabel('Intensité')
plt.xlabel('Temps (ms)')
plt.grid()
plt.show()
9-4-1. Le bouton poussoir▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
// État en cours de l'automate
int etat;
// État à mémoriser
int oldEtat;
//Les états possibles de l'automate
const int WAIT = 2;
const int START = 1;
const int STOP = 0;
// Les broches utilisées
//capteur
const int broche = A0;
//bouton-poussoir
const int BP = 3;
void setup() {
    //initialisation des variables
    oldEtat = LOW;
    etat = WAIT;
    //config E/S
    pinMode(BP, INPUT);
    //liaison série
    Serial.begin(19200);
}
void loop() {
    //Lecture du bouton
    int etatBP = digi talRead (BP);
    //gestion des états
    if (oldEtat == LOW && etatBP == HIGH) {
        if (etat == WAIT)
        {
            etat = START;
        }
        else if (etat == STOP)
        {
            etat = START;
        }
        else if (etat == START)
        {
            etat = STOP;
        }
    }
    //Traitement des états
    if (etat == START) {
        int valeur = analogRead (broche);
        Serial.print(valeur);
        Serial.print("\t");
        Serial.println(millis());
    }
    else if (etat == STOP)
        Serial.println("-1\t -1");
    oldEtat = etatBP;
    delay(10);
}
9-5. Le projet : vitesse du son▲
9-5-1. Le code Arduino▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
// Déclaration des variables globales : broches
int trigg = 8;
int echo = 9;
void setup() {
    pinMode(trigg, OUTPUT);      // Configuration des broches
    digitalWrite(trigg, LOW);    // La broche TRIGGER doit être à LOW au repos
    pinMode(echo, INPUT);        // La broche ECHO en entrée
    Serial.begin(9600);          // Démarrage de la liaison série
}
void loop() {
    digitalWrite(trigg, HIGH);       // Lance une mesure de distance en envoyant
    delayMicroseconds(10);           // Une impulsion HIGH de 10 microsecondes
    digitalWrite(trigg, LOW);        // Fin d'émission
    int temps = pulseIn(echo, HIGH); // Mesure temps émission-réception
    Serial.print(temps);
    Serial.print("\t");              // on ajoute une tabulation et la
    Serial.println("-1");            // la valeur -1
    delay(500);
}
Dans cet exemple, seule la valeur temps nous intéresse. Mais pour uniformiser le code, nous ajoutons une tabulation et la valeur −1. Cela permet de réutiliser les codes Python précédents. En effet, côté Python on attend toujours deux informations (deux grandeurs physiques). C'est un choix de programmation que nous avons fait dès le départ, mais qui est cohérent avec les besoins que nous avons en physique-chimie qui se traduit souvent par l'étude d'une grandeur en fonction du temps. Il suffira d'ignorer la lecture de la valeur −1 côté Python. En informatique, il est courant d'utiliser la valeur −1 pour indiquer soit une erreur soit une valeur à ignorer.
9-5-2. Le code Python▲
Penser à écrire une fonction pour calculer le temps moyen sur un nombre entier n de valeurs renvoyées par le capteur ultrason.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
def temps_moyen(n, serial_port) :
    """
    Cette fonction calcule une moyenne des temps ultrasons
    reçus sur n valeurs
    n           -> <int>    : nombre de valeurs à lire
    serial_port -> <serial> : port série
    """
    i = 0
    t_somme = 0
    serial_port.flushInput()
    while i < n:
        val = serial_port.readline().split()
        try:
            t = float(val[0])    # lecture temps ultrason
            t_somme += t         # la somme des temps ultrasons
            i = i + 1            # ajoute 1 à la variable comptant les mesures
        except :
            pass
    return t_somme/n
2.
3.
# les imports
import serial
import matplotlib.pyplot as pl t
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
# ouverture du port série et synchronisation des données entre Arduino et Python.
serial_port = serial.Serial(port = "/dev/ttyACM0", baudrate = 9600)
temps = []      # une liste pour les mesures de temps
distances = []  # une liste pour les mesures de distance
dist = 0        # juste pour entrer dans la boucle
nb_t = 10       # le nombre de mesures temps
while dist != −1:
    dist = float(input("Entrez votre mesure : "))
    if dist != −1:
        distances.append(dist)
        tm = temps_moyen(nb_t, serial_port)
        temps.append(tm)
# fermeture du port série
serial_port.close()
9-5-3. Comment faire les mesures ?▲
- Téléverser le programme Arduino dans la mémoire de la carte.
- Ouvrir un moniteur série et vérifier que les mesures de temps s'affichent. Faire varier la distance entre l'objet et le capteur HC-SR04 pour observer que les valeurs temps augmentent si la distance augmente.
- Valider les cellules contenant le code Python concernant cet exercice.
- Placer correctement votre capteur HC-SR04 à une distance déterminée de votre objet.
- 
              Normalement, vous devez avoir la possibilité de saisir cette distance dans une boite de dialogue qui s'est ouverte sur le Notebook. 
- Valider avec la touche Enter, modifier la distance capteur-objet, entrer la valeur, etc.
L'affichage du graphique : distances en fonction du temps, je vous laisse ajouter les commentaires : title, xlabel, ylabel
2.
3.
4.
plt.figure(figsize =(12, 6))
plt.plot (mesures, distances, 'ro')
plt.grid()
plt.show()
9-6. La chute libre▲
9-6-1. Le code Arduino▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
// Déclaration des variables globales : broches
int trigg = 8;
int echo = 9;
void setup() {
    pinMode(trigg, OUTPUT);     // Configuration des broches
    digitalWrite(trigg, LOW);   // La broche TRIGGER doit être à LOW au repos
    pinMode(echo, INPUT);       // La broche ECHO en entrée
    Serial.begin(19200);        // Démarrage de la liaison série
}
void loop() {
    digitalWrite(trigg, HIGH);  // Lance une mesure de distance en envoyant
    delayMicroseconds(10);      // Une impulsion HIGH de 10 microsecondes
    digitalWrite(trigg, LOW);   // Fin d'émission
    int temps_echo = pulseIn(echo, HIGH); // Mesure temps émission-réception
    Serial.print(temps_echo);
    Serial.print("\t");
    Serial.println(millis());
    delay(1);
}
9-6-2. Le code Python▲
Les mesures ont été faites avec un paquet de mouchoirs en papier accroché à une ficelle d'environ 80 cm. J'ai lancé le code Python puis j'ai compté jusqu'à deux avant de lâcher le paquet bien à la verticale du capteur ultrason.
2.
3.
4.
# les imports
import serial
import time
import matplotlib.pyplot as plt
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
# ouverture du port série
serial_port = serial.Serial(port = "/dev/ttyACM1", baudrate = 19200)
serial_port.setDTR(False)
time.sleep(0.1)
serial_port.setDTR(True)
serial_port.flushInput()
# les mesures
mesure_dist = []
temps = []
duree = 3000                             # durée d'acquisition
end = False
while end == False or temps[−1] − temps[0] <= duree :
    val = serial_port.readline().split() # lecture des données
    try:
        d = float(val[0]) / 58           # distance en cm
        t = float(val[1])                # temps écoulé en ms
        if d > 1 and d < 100:            # filtrage des valeurs aberrantes
            mesure_dist.append(d)        # entre 1 cm et 1 m
            temps.append(t)
            end = True
    except:
        pass
# fermeture du port série
serial_port.close()
2.
3.
4.
5.
6.
plt.plot(temps, mesure_dist, ".")
plt.title("CHUTE LIBRE D'UN PAQUET DE MOUCHOIRS")
plt.ylabel('Distance (cm)')
plt.xlabel('Temps (ms)')
plt.grid()
plt.show()
2.
3.
4.
5.
6.
plt.plot(temps[100:200], mesure_dist[100:200], ".")
plt.title("CHUTE LIBRE D'UN PAQUET DE MOUCHOIRS")
plt.ylabel('Distance (cm)')
plt.xlabel('Temps (ms)')
plt.grid()
plt.show()
9-7. Le saut à l'élastique▲
Avec un capteur ultrason, il également possible d'étudier les différentes phases d'un saut à l'élastique.
Les codes Arduino et Python pour obtenir ces résultats sont exactement les mêmes que pour la chute libre. Il peut donc être intéressant de créer une fonction Python que les élèves pourraient utiliser à partir d'un module.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
# ouverture du port série
serial_port = serial.Serial(port = "/dev/ttyACM0", baudrate = 19200)
serial_port.setDTR(False)
time.sleep(0.1)
serial_port.setDTR(True)
serial_port.flushInput()
temps, mesure_dist = distance_ultrason(5000, serial_port)
# fermeture du port série
serial_port.close()
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
def distance_ultrason(duree, serial_port, inf = 1, sup = 100):
    """
    Renvoie respectivement une liste temps (dates d'acquisition)
    et une liste distance en (cm) mesurée par le capteur ultrason
    durant une durée donnée et dans un intervalle de distance
    fixée par défaut entre 1 cm et 1 m
    duree       -> <float>  : durée de l'acquisition en (ms)
    serial_port -> <serial> : port série ouvert à la communication
    inf         -> <float>  : distance minimum d'acquisition en (cm)
    sup         -> <float>  : distance maximum d'acquisition en (cm)
    """
    mesure = []
    temps = []
    end = False
    while end == False or temps[−1] − temps [0] <= duree:
        val = serial_port.readline().split() # lecture des données
        try:
            d = float(val[1]) / 58           # distance en cm
            t = float(val[0])                # temps écoulé en ms
            if d > inf and d < sup:          # filtrage des valeurs aberrantes
                mesure.append(d)
                temps.append(t)
                end = True
        except:
            pass
    return temps, mesure
10. Note de la rédaction▲
Ce document ressource (licence CC BY-NC-SA) a été donné en formation académique (Académie de Bordeaux) afin de découvrir la physique-chimie « computationnelle », Python et Arduino pour une utilisation au lycée.
Nous remercions les membres de Developpez pour le travail de mise en forme et de relecture du document, en particulier : Winjerome, f-leb et escartefigue.











