Simulation d'un feu de chantier pour la circulation automobile

FondamentalMatériel nécessaire

Pour cette activité, nous utiliserons

  • 2 cartes micro:bit avec cables croco ou shield pour connecter des composants extérieurs (ici des LED)

  • 4 LEDs (2 rouges et 2 oranges)

  • 2 résistances de protection de 220Ohms

  • une plaquette de prototypage (breadboard) ou bien un modèle de feu imprimé en 3D.

FondamentalMéthode alternative sans matériel supplémentaire

Si vous ne disposez que des cartes sans possibilités de raccorder des LED sur les broches d'entrée/sortie, pas de problèmes : vous pourrez réaliser cette activité en utilisant la matrice LED de la carte pour afficher l'état des feux en remplacement des LED rouges et orange.

Je donnerai pour chaque étape de l'activité les codes correspondants aux deux situations : avec et sans feux LEDs.

Version 0

Consigne

Créer une simulation de feu dans laquelle

  • un feu comporte 2 LEDs (orange et rouge) connectées sur les broches 0 et 1 de la carte. En l'absence de LEDs, afficher le feu sous forme d'un carré de 4 pixels en haut à droite pour rouge et en bas à droite pour orange (une valeur de pixels égale à 4 simulera une couleur différente).

  • le feu change toutes les 10 secondes

  • un compte à rebours s'affiche sur l'écran

SimulationUtilisation du simulateur en ligne

Cette version 0 peut être réalisée sur le simulateur en ligne en utilisant les broches 5 et 6 pour simuler les 2 LED du feu ou bien en utilisant uniquement la matrice de LED.

MéthodeLe montage en cas d'utilisation des LEDs

Pour cette activité, nous utiliserons

  • 2 LEDs (une rouge et une orange)

  • une résistance de protection de 220Ohms

  • une plaquette de prototypage (breadboard) ou bien un modèle de feu imprimé en 3D.

ComplémentIndication pour la version avec LED

On pourra utiliser les fonctions ci-dessous permettant de simuler un feu rouge, un feu orange et l'affichage du temps restant

1
def afficheRouge():
2
    pin1.write_digital(1)
3
    pin0.write_digital(0)
4
5
def afficheOrange():
6
    pin1.write_digital(0)
7
    pin0.write_digital(1)
8
9
def afficheAttente(attente):
10
    display.show(str(attente))

ComplémentIndication pour la version sans LED

On pourra utiliser les fonctions ci-dessous permettant de simuler un feu rouge, un feu orange et l'affichage du temps restant

1
def afficheRouge():
2
    for x in range(3,5):
3
        for y in range(2):
4
            display.set_pixel(x,y,9)
5
    for x in range(3,5):
6
        for y in range(3,5):
7
            display.set_pixel(x,y,0)
8
9
def afficheOrange():
10
    for x in range(3,5):
11
        for y in range(2):
12
            display.set_pixel(x,y,0)
13
    for x in range(3,5):
14
        for y in range(3,5):
15
            display.set_pixel(x,y,4)
16
17
def afficheAttente(attente):
18
    for x in range(2):
19
        for y in range(5):
20
            display.set_pixel(x,y, 0 if 5*x+y >= attente else 9)

Corrigé

Voici le corrigé pour la version avec LEDs et sans LEDs.

Version 1 : Passage à 2 feux

Il y a deux façons d'aborder la suite de cette activité selon le niveau des élèves et la progression Python dans l'année :

  • on demande aux élèves de construire le projet eux même

  • on fournit un code opérationnel et on pose des questions aux élèves pour les faire réfléchir en mode débranché

Dans la suite de l'activité, je me placerai dans le second scénario : le code version 1 est fourni aux élèves et une démonstration leur est faite du dispositif fonctionnel d'un bout à l'autre de la salle de classe. Il est alors possible de mener la suite de cette activité en mode partiellement débranché en demandant aux élèves de répondre aux questions sur feuille puis passer à la phase de réalisation si vous avez accès à une salle info avec le matériel adéquat.

Objectif de l'activité

Dans cette partie, nous allons étudier un système de 2 feux connectés dans lequel

  • les feux sont en opposition !

  • Les 2 feux affichent le même compte à rebours

Consigne

Nous allons travailler sur les programmes suivants : étudiez la version avec LED ou sans LED selon votre configuration (la version sans LED fonctionne sur la carte seule en utilisant l'affichage de la matrice LED pour simuler les feux) puis répondez sur feuille aux questions suivantes :

  • Les programmes sur les 2 cartes sont-ils identiques ? Pourquoi ?

  • Identifiez le programme maître et le programme esclave.

  • Décrire le protocole de communication entre les cartes

  • Est-on certain de la robustesse du système ?

    • les feux peuvent-ils être tous les deux au rouge ? Est-ce gênant ?

    • les feux peuvent-ils être tous les deux au vert ? Est-ce gênant ?

    • quelles sont les conséquences du plantage d'un des feux ?

SimulationUtilisation du simulateur en ligne

Ces deux programmes peuvent être simulés dans le simulateur en ligne, mais l'un après l'autre indépendamment.

Pour voir les messages envoyés par le programme maître, réglez les paramètres de l'onglet radio comme indiqué sur la capture d'écran ci-contre.

Sur le programme esclave, vous pourrez utiliser le champ Message pour simuler l'envoi d'une commande par le maître (essayez d'envoyer 3 ou VERT et observez le comportement de la carte).

MéthodeEléments de réponse

Les deux feux peuvent être au rouge simultanément le temps que l'esclave reçoive une consigne du maître mais ce n'est pas gênant. Il n'est pas possible cependant du fait des valeurs d'initialisation de la variable feuRouge que les deux feux se retrouvent orange en même temps ce qui est plutôt rassurant.

Pour le moment le protocole de communication est simple : Il va toujours du maître vers l'esclave et utilise les mots suivants :

  • VERT : demande à l'esclave de passer à l'orange

  • ROUGE : demande à l'esclave de passer au rouge

  • 1 à 9 : Valeur du compte à rebours

Il y a tout de même une faille si un feu est défaillant alors que l'autre laisse passer les voitures. Une absence de feu peut laisser croire aux usager que la voie est libre et ils vont rencontrer des véhicules venant en face. Le dispositif n'est donc pas très robuste.

ComplémentVersion 1 bis : identique à la version 1 mais le feu orange clignote !

Cette déclinaison de la version 1 n'est pas si simple à mettre en œuvre car elle requiert d'éviter d'avoir recours à la fonction sleep() qui bloque l'exécution du programme. Il faut donc envisager la gestion du temps autrement. A réserver aux élèves les plus expérimentés !

La méthode utilise une variable clignotant qui mémorise toutes les secondes la valeur de l'horloge donnée par ticks_ms(). Ensuite, le clignotement est réalisé dans la fonction afficheOrange() par le code suivant ou on utilise le temps écoulé depuis la dernière mémorisation de la valeur clignotant pour déterminer la luminosité du pixel. Le maximum de luminosité est donné à l'instant clignotant + 500ms.

1
# orange clignotant
2
    couleur = max(0,4 - abs(ticks_ms()-clignotant - 500)//100)
3
    for x in range(3,5):
4
        for y in range(3,5):
5
            display.set_pixel(x,y,couleur)

Voir le code complet en version LED et sans LED.

Version 2 : Le véhicule prioritaire

Consigne

Un véhicule prioritaire arrive à un feu ce qui doit le faire basculer au vert immédiatement.

  • Imaginer par quel(s) moyen(s) on peut interagir avec la carte pour simuler cette situation ? décrire l'interaction homme-machine.

  • la manière de prendre en compte l'arrivée du véhicule prioritaire est-elle identique selon le feu qui reçoit le signal ?

  • situation A : le véhicule prioritaire arrive au feu maître. Modifier le programme maître afin qu'un appui sur le bouton A passe le feu maître à l'orange et l'autre feu au rouge.

  • situation B : le véhicule prioritaire arrive à l'autre feu. Que faut-il modifier pour prendre en compte cette situation ?

  • Décrire les modifications apportées au protocole de communication

Remarque

Dans ce scénario, les élèves n'ont pas à écrire plus de 4 lignes de python pour les deux dernières questions, ce qui est tout à fait abordable pour un élève de seconde en SNT, même si au final, le projet global est assez ambitieux.

Éléments de réponse

Il y a plusieurs moyens d'interagir avec la carte pour signaler la présence d'un véhicule prioritaire. Le plus simple est d'utiliser le bouton A de la carte, mais on peut imaginer d'autres scénarios :

  • utiliser l'accéléromètre pour détecter une secousse

  • communication radio avec une autre carte microbit

  • souffler sur la carte qui détectera une élévation soudaine de la température

  • approcher un aiment qui sera détecter par le magnétomètre

Pour la prise en charge de l'arrivée du véhicule prioritaire, les deux feux n'ont pas le même rôle : l'un envoie des ordres (maître) et le second obéi (esclave). Il n'y a pas pour le moment de communication de l'esclave vers le maître. Il faudra ajouter cette fonctionnalité pour permettre à un véhicule prioritaire de déclencher le feu esclave.

Concernant le protocole de communication, il n'y a pas de changements pour la situation A : en effet le maître contrôle le feu esclave et il peut choisir de le passer au rouge quand bon lui semble.

Par contre, lorsque le véhicule prioritaire arrive au feu esclave il est nécessaire de modifier le protocole de communication afin de permettre à l'esclave de faire un signalement au maître. On utilise ici le message PRIO que l'esclave envoie au maître pour lui demander le passage.

MéthodeCorrigé situation A : un appui sur le bouton A passe le feu maître à l'orange et l'autre feu au rouge.

Ici seul le code maître doit être actualisé. L'esclave n'est pas concerné par l'arrivée du véhicule prioritaire au feu maître car de toute manières, c'est le feu maître qui commande l'autre feu. Le code maître est modifié en ajoutant ces lignes au début de la boucle principale :

1
 # Arrivee du vehicule prioritaire au feu maitre
2
    if button_a.was_pressed():
3
        feuRouge = False
4
        attente = DUREE
5
        radio.send("ROUGE")

Voir le code complet en version LED et sans LED.

MéthodeCorrigé situation B : le véhicule prioritaire arrive au feu esclave.

Ici, nous devons ajuster les deux codes afin d'établir une communication dans le sens esclave vers maître.

Code pour le feu maître. 5 lignes ont été ajoutées pour écouter les communications en provenance de l'esclave.

1
# Traitement des messages en provenance de l'esclave
2
    incoming = radio.receive()
3
    # Arrivee du vehicule priopritaire au feu esclave
4
    if incoming == "PRIO" :
5
        feuRouge = True
6
        attente = DUREE
7
        radio.send("VERT")

Code pour le feu esclave. Deux lignes ont été ajoutées pour envoyer le signal PRIO au maître. Il enverra alors l'ordre à l'esclave de passer au vert.

1
 # Arrivee vehicule prioritaire
2
    if button_a.was_pressed():
3
        radio.send("PRIO")

Voir le code complet en version LED et sans LED.

Version 3 : Améliorer la robustesse du dispositif

Consigne

  • Quel scénario proposeriez-vous afin de renforcer la robustesse (tolérance aux pannes) du dispositif et renforcer la sécurité ?

  • Proposez une modification des programmes en ce sens

MéthodeCorrigé scénario A

Afin de renforcer la fiabilité du dispositif, une communication régulière peut être établie du maître vers l'esclave. Si l'esclave ne reçoit pas de nouvelles du maître, il passe au rouge et affiche une figure triste. Pour ce faire, dans le code du feu maître, 4 lignes ont été ajoutées :

1
# Robustesse du dispositif :
2
    # Le maitre envoie l'etat du feu a l'esclave
3
    # toutes les secondes
4
    if feuRouge :
5
        radio.send("VERT")
6
    else:
7
        radio.send("ROUGE")

Pour le feu esclave, voici les lignes impactées. On utilise ici la fonction ticks_ms() afin de savoir combien de millisecondes se sont écoulées depuis la dernière transmission du feu maître. Si ce temps dépasse 2 secondes, l'esclave se met en sécurité.

1
# Traitement des messages du maitre
2
    incoming = radio.receive()
3
    if incoming:
4
        if incoming == "VERT" :
5
            feuRouge = False
6
            lastTransm = ticks_ms()  # message recu
7
        elif incoming == "ROUGE" :
8
            feuRouge = True
9
            lastTransm = ticks_ms()  # message recu
10
        elif len(incoming) ==1:
11
            afficheAttente(int(incoming))
12
13
    # Mise en securite si le maitre plante
14
    if ticks_ms() - lastTransm > 2000 :
15
        # Plus de deux secondes sans nouvelles du maitre
16
        feuRouge = True
17
        display.show(Image.SAD)

Voir le code complet en version LED et sans LED.

MéthodeCorrigé scénario B

Pour améliorer encore la fiabilité du dispositif, une communication régulière (envoi du message ALIVE) est établie de l'esclave vers le maître. Si le maître ne reçoit pas de nouvelles de son esclave, il passe au rouge et affiche une figure triste.

Voici les impacts sur le code maître de cette dernière modification :

On commence par ajouter une variable qui mémorise l'instant de la dernière transmission de l'esclave

1
lastTransm = ticks_ms() # derniere transmission de l'esclave

Ensuite, dans la boucle principale, on met le maître en sécurité (feu rouge et image triste) si l'esclave n'a pas donné signe de vie depuis plus de 2 secondes.

1
    # Mise en securite si l'esclave plante
2
    if ticks_ms() - lastTransm > 2000:
3
        # Plus de deux secondes sans nouvelles de l'esclave
4
        feuRouge = True
5
        display.show(Image.SAD)

Pour le feu esclave, on ajoute ue nouvelle variable qui mémorise le dernier envoi du message ALIVE :

1
lastAlive = ticks_ms()  # derniere transmission ALIVE de l'esclave

Ensuite, on envoie le message ALIVE toutes les deux secondes dans la boucle principale :

1
    # L'esclave envoie un message au maitre toutes les secondes
2
    if ticks_ms() - lastAlive > 1000:
3
        radio.send("ALIVE")
4
        lastAlive = ticks_ms()

Voir le code complet en version LED et sans LED.

Version finale

L'usage de la fonction sleep() n'est vraiment pas recommandable sur le feu maître car pendant qu'il est en sommeil il n'est pas à l'écoute des événements extérieurs et ne peut donc pas réagir en temps réel. La version proposée ci-dessous banni le sleep() au profit de la fonction ticks_ms() déjà rencontré. Il y a une meilleure réactivité du dispositif mais au prix d'un code légèrement plus compliqué, ce qui peut rebuter des élèves débutants en programmation.

Voir le code complet en version LED et sans LED.

Pour aller plus loin

Quelques idées afin de prolonger ce projet pour ceux qui le souhaitent

  • Ajouter un délai de sécurité durant lequel les 2 feux sont rouges pour laisser le temps aux véhicules engagés de libérer la voie

  • Réaliser la télécommande du chef de chantier qui

    • affiche quel feu est passant

    • permet de commander les 2 feux avec les boutons A et B

  • Ajouter un 3ème feu. Quelles modifications cela implique t-il ? Proposer un protocole de communication gérant une configuration à 3 (voire plus) feux.