[ Arduino 206] [TP] Parking

Ça y est, une page se tourne avec l’acquisition de nombreuses connaissances de base. C’est donc l’occasion idéale pour faire un (gros 😈 ) TP qui utilisera l’ensemble de vos connaissances durement acquises. J’aime utiliser les situations de la vie réelle, je vais donc en prendre une pour ce sujet. Je vous propose de réaliser la gestion d’un parking souterrain… RDV aux consignes pour les détails.

[adsense]

Consigne

Après tant de connaissances chacune séparée dans son coin, nous allons pouvoir mettre en œuvre tout ce petit monde dans un TP traitant sur un sujet de la vie courante : les parkings !

Histoire

Le maire de zCity à décidé de rentabiliser le parking communal d’une capacité de 99 places (pas une de plus ni de moins). En effet, chaque jour des centaines de zTouristes viennent se promener en voiture et ont besoin de la garer quelque part. Le parking, n’étant pour le moment pas rentable, servira à financer l’entretien de la ville. Pour cela, il faut rajouter au parking existant un afficheur permettant de savoir le nombre de places disponibles en temps réel (le système de paiement du parking ne sera pas traité). Il dispose aussi dans la ville des lumières vertes et rouges signalant un parking complet ou non. Enfin, l’entrée du parking est équipée de deux barrières (une pour l’entrée et l’autre pour la sortie). Chaque entrée de voiture ou sortie génère un signal pour la gestion du nombre de places. Le maire vous a choisi pour vos compétences, votre esprit de créativité et il sait que vous aimez les défis. Vous acceptez évidemment en lui promettant de réussir dans les plus brefs délais !

Matériel

Pour mener à bien ce TP voici la liste des courses conseillée :

  • Une carte Arduino (évidemment)
  • 2 LEDs avec leur résistance de limitations de courant (habituellement 330 Ohms) -> Elles symbolisent les témoins lumineux disposés dans la ville
  • 2 boutons (avec 2 résistances de 10 kOhms et 2 condensateurs de 10 nF) -> Ce sont les « capteurs » d’entrée et de sortie.
  • 2 afficheurs 7 segments -> pour afficher le nombre de places disponibles
  • 1 décodeur 4 bits vers 7 segments
  • 7 résistances de 330 Ohms (pour les 7 segments)
  • Une breadboard pour assembler le tout
  • Un paquet de fils
  • Votre cerveau et quelques doigts…

Voici une vidéo pour vous montrer le résultat attendu par le maire :

Bon courage !

Correction !

J’espère que tout s’est bien passé pour vous et que le maire sera content de votre travail. Voilà maintenant une correction (parmi tant d’autres, comme souvent en programmation et en électronique). Nous commencerons par voir le schéma électronique, puis ensuite nous rentrerons dans le code.

Montage

Le montage électronique est la base de ce qui va nous servir pour réaliser le système. Une fois qu’il est terminé on pourra l’utiliser grâce aux entrées/sorties de la carte Arduino et lui faire faire pleins de choses. Mais ça, vous le savez déjà. Alors ici pas de grand discours, il « suffit » de reprendre les différents blocs vus un par un dans les chapitres précédents et de faire le montage de façon simple.

Schéma

Je vous montre le schéma que j’ai réalisé, il n’est pas absolu et peut différer selon ce que vous avez fait, mais il reprend essentiellement tous les « blocs » (ou mini montages électroniques) que l’on a vus dans les précédents chapitres, en les assemblant de façon logique et ordonnée :

Secret: Réponse SelectionnerAfficher

Procédure de montage

Voici l’ordre que j’ai suivi pour réaliser le montage :

  • Débrancher la carte Arduino !
  • Mettre les boutons
    • Mettre les résistances de pull-up
    • Puis les condensateurs de filtrage
    • Et tirez des fils de signaux jusqu’à la carte Arduino
    • Enfin, vérifiez la position des alimentations (+5V et masse)
  • Mettre les LEDs rouge et verte avec leur résistance de limitation de courant et un fil vers Arduino
  • Mettre les décodeurs
    • Relier les fils ABCD à Arduino
    • Mettre au +5V ou à la masse les signaux de commandes du décodeur
    • Mettre les résistances de limitations de courant des 7 segments
    • Enfin, vérifier la position des alimentations (+5V et masse)
  • Puis mettre les afficheurs -> les relier entre le décodeur et leurs segments) -> les connecter au +5V
  • Amener du +5V et la masse sur la breadboard

Ce étant terminé, la maquette est fin prête à être utilisée ! Évidemment, cela fait un montage (un peu) plus complet que les précédents !

Programme

Nous allons maintenant voir une solution de programme pour le problème de départ. La vôtre sera peut-être (voire surement) différente, et ce n’est pas grave, un problème n’exige pas une solution unique. Je n’ai peut-être même pas la meilleure solution ! (mais ça m’étonnerait 😛 :ninja: )

Les variables utiles et déclarations

Tout d’abord, nous allons voir les variables globales que nous allons utiliser ainsi que les déclarations utiles à faire. Pour ma part, j’utilise six variables globales. Vous reconnaîtrez la plupart d’entre elles car elles viennent des chapitres précédents.

  • Deux pour stocker l’état des boutons un coup sur l’autre et une pour le stocker de manière courante
  • Un char stockant le nombre de places disponibles dans le parking
  • Un booléen désignant l’afficheur utilisé en dernier
  • Un long stockant l’information de temps pour le rafraichissement de l’affichage

Voici ces différentes variables commentées.

Secret: Réponse SelectionnerAfficher

L’initialisation de la fonction setup()

Je ne vais pas faire un long baratin sur cette partie car je pense que vous serez en mesure de tout comprendre très facilement car il n’y a vraiment rien d’original par rapport à tout ce que l’on a fait avant (réglages des entrées/sorties et de leurs niveaux).

Secret: Réponse SelectionnerAfficher

La boucle principale (loop)

Ici se trouve la partie la plus compliquée du TP. En effet, elle doit s’occuper de gérer d’une part une boucle de rafraichissement de l’allumage des afficheurs 7 segments et d’autre part gérer les évènements. Rappelons-nous de l’organigramme vu dans la dernière partie sur les 7 segments :

Dans notre application, la gestion d’évènements sera « une voiture rentre-t/sort-elle du parking ? » qui sera symbolisée par un appui sur un bouton. Ensuite, il faudra aussi prendre en compte l’affichage de la disponibilité sur les LEDs selon si le parking est complet ou non… Voici une manière de coder tout cela :

Secret: Réponse SelectionnerAfficher
Dans les lignes 4 à 11, on retrouve la gestion du rafraichissement des 7 segments. Ensuite, on s’occupe de réceptionner les évènements en faisant un test par bouton pour savoir si son état a changé et s’il est à l’état bas. Enfin, on va borner le nombre de places et faire l’affichage sur les LED en conséquence. Vous voyez, ce n’était pas si difficile en fait ! Si, un peu quand même, non ? :mrgreen: Il ne reste maintenant plus qu’à faire les fonctions d’affichages.

Les fonctions d’affichages

Là encore, je ne vais pas faire de grand discours puisque ces fonctions sont exactement les mêmes que celles réalisées dans la partie concernant l’affichage sur plusieurs afficheurs. Si elles ne vous semblent pas claires, je vous conseille de revenir sur le chapitre concernant les 7 segments.

Secret: Réponse SelectionnerAfficher

Et le code au complet

Si vous voulez tester l’ensemble de l’application sans faire d’erreurs de copier/coller, voici le code complet (qui doit fonctionner si on considère que vous avez branché chaque composant au même endroit que sur le schéma fourni au départ !)

Conclusion

Bon, si vous ne comprenez pas tout du premier coup, c’est un petit peu normal, c’est en effet difficile de reprendre un programme que l’on a pas fait soi-même et ce pour diverses raisons. Le principal est que vous ayez cherché une solution par vous-même et que vous soyez arrivé à réaliser l’objectif final. Si vous n’avez pas réussi mais que vous pensiez y être presque, alors je vous invite à chercher profondément le pourquoi du comment votre programme ne fonctionne pas ou pas entièrement, cela vous aidera à trouver vos erreurs et à ne plus en refaire !

Il est pas magnifique ce parking ? J’espère que vous avez apprécié sa réalisation. Nous allons maintenant continuer à apprendre de nouvelles choses, toujours plus sympas les unes que les autres. Un conseil, gardez votre travail quelques part au chaud, vous pourriez l’améliorer avec vos connaissances futures !

Laisser un commentaire

  1. Ré bonjour,
    Bon je n’ai pas réussi le TP… Mais je n’étais pas si loin … Quelques variables mal définis. Notamment les « mem » des « états des boutons » … Mais j’ai compris tout ton code. En revanche, je ne comprends pas dans le montage… Pourquoi tu ne branches pas les « ABCD » comme dans le montage précédent ? En effet, tu branches les broches 1, 2, y et 7 du micro contrôleur sur les broche de l’arduino ?
    Duplau

    • C’est ce qu’on appelle une magnifique boulette !! Cette partie du tuto (les 7 segments) a subit une grosse révision pendant sa vie, qui a inclus notamment un changement de référence pour le décodeur… et du coup un changement des broches… J’aurais juré avoir fait le changement du schéma aussi ! Il va falloir que je me penche la dessus !
      EDIT : Effectivement, j’ai bien le schéma à jour sur mon ordinateur mais va savoir pourquoi j’ai pas repercuté ca sur le TP… je fais ca de suite !!

  2. Bonjour,
    Après avoir copier le code du corrigé et adapté les numéros de broches à mon montage, mon afficheur ne clignote pas assez vite pour avoir le phénomène de persistance rétinienne. J’ai beau cherché et vérifier mes branchements je ne voit pas d’où ça vient. Sur le précédent TP avec l’afficheur et les transistors cela marchait parfaitement.
    Cordialement

    • Salut ! Es-tu sur de ne pas avoir une fonction bloquante qui viendrait perturber le bon déroulement du programme en faisant une petite pause a un endroit non désiré ? L’idéal serait de voir le code que tu charges 🙂
      Pour discuter de tout ça et debugguer l’ensemble, je te propose d’ouvrir un sujet sur un forum dédié (comme dans la section “Programmation” du site Zeste De Savoir par exemple). Ce sera plus pratique pour échanger/debugguer que cette zone de commentaire

    • je te conseille de réinitialiser ton décodeur après chaque chiffre ! c’est à dire tu met un zéro après chaque chiffre! car apparent sa s’incrémente d’ou le problème

  3. const int bit_A = 2;
    const int bit_B = 3;
    const int bit_C = 4;
    const int bit_D = 5;
    int aff1 = 6;
    int aff2 = 7;

    void setup() {
    // put your setup code here, to run once:
    pinMode( bit_A, OUTPUT) ;
    pinMode( bit_B, OUTPUT) ;
    pinMode( bit_C, OUTPUT) ;
    pinMode( bit_D, OUTPUT) ;
    pinMode( aff1, OUTPUT) ;
    pinMode( aff2, OUTPUT) ;
    //Les broches sont toutes mises à l’état bas
    digitalWrite( bit_A, LOW) ;
    digitalWrite( bit_B, LOW) ;
    digitalWrite( bit_C, LOW) ;
    digitalWrite( bit_D, LOW) ;
    digitalWrite( aff1, LOW) ;
    digitalWrite( aff2, LOW) ;
    }

    void loop() {
    // put your main code here, to run repeatedly:
    int i = 0;
    int j = 0;

    while ( i < 10)
    {
    j = 0;
    while ( j < 10)
    {
    long temps;
    temps = millis() ;
    while ( (millis() – temps) = 8)
    {
    digitalWrite(bit_D, HIGH) ;
    chiffre = chiffre – 8;
    }
    if (chiffre >= 4)
    {
    digitalWrite(bit_C, HIGH) ;
    chiffre = chiffre – 4;
    }
    if (chiffre >= 2)
    {
    digitalWrite(bit_B, HIGH) ;
    chiffre = chiffre – 2;
    }
    if (chiffre >= 1)
    {
    digitalWrite(bit_A, HIGH) ;
    chiffre = chiffre – 1;
    }

    }

    dis moi ce que tu pense de ce code !!!!

    • Bonjour,

      Bonjour, explication, merci, au revoir.

      C’est pas parce que l’on sur internet que la politesse disparaît. Pas de politesse, pas de réponse.

  4. Bonjour , je trouve super le tp ! C’est justement ce dont j’ai besoin pour mon PPE en terminale S où l’on travaille sur un parking et je m’occupe de la partie gestion du parking , j’aurai quelques questions , si c’est possible d’avoir un mail afin d’échanger ?

    • Hello !

      Je ne fais pas d’aide par email/voie privée. Cependant je serais ravi de t’aider sur les forums de Zeste de Savoir (rubrique « Système et Matériel ») !

      • Super 🙂 pourais-tu m’envoyé un lien alors stp , désoler je m’y connais pas trop sur ce site et forum x_x »

  5. De plus j’aimerai comprendre pourquoi quand on dit  » const int bit_A,B,C,D etc » on s’arrete à la D alors que pour un afficheur à cette segment les led vont jusqu’a G ?

  6. Salut, alors déjà chapeau pour ce tuto, c’est vraiment sympa d’aider les autres comme ça et surtout gratuitement.
    Malgré le fait que ton tuto explique bien les choses, je suis pas sûr d’avoir tout compris, j’ai fait ce tp de mon coté et j’aimerais que tu me dise ce que tu en pense, que faut t’il faut amélioré, est-ce qu’il marche ( oui car je n’ai pas(encore) de carte arduino donc tout ça c’est de la théorie pour moi)… voila merci d’avance.

    • Ok il manque un bout du code je sais pas pourquoi, et vu que je peut pas éditer mon commentaire, je vais le reposter:

      const int DecA = 2; // Décodeur bit 1
      const int DecB = 3; //...
      const int DecC = 4;
      const int DecD = 5;
      const int ledv = 11; // Led Verte
      const int ledr = 12; // Led Rouge
      const int bouton_entre = 9;
      const int bouton_sortie = 8;
      const int alim_unite = 7; // Transistor de l'afficheur des unite
      const int alim_dizaine = 6; // Transistor de l'afficheur des dizaines
      long temps;
      unsigned char i = 50; //place dispo du parking
      int etat_entre = HIGH; //pour stocker l'état du bouton d'entrée
      int etat_sortie = HIGH; // pareille, mais pour la sortie
      
      void setup() {
        pinMode(DecA, OUTPUT);
        pinMode(DecB, OUTPUT);
        pinMode(DecC, OUTPUT);
        pinMode(DecD, OUTPUT);
        pinMode(ledv, OUTPUT);
        pinMode(ledr, OUTPUT);
        pinMode(bouton_entre, INPUT);
        pinMode(bouton_sortie, INPUT);
        pinMode(alim_unite, OUTPUT);
        pinMode(alim_dizaine, OUTPUT);
        
        digitalWrite(DecA, LOW);
        digitalWrite(DecB, LOW);
        digitalWrite(DecC, LOW);
        digitalWrite(DecD, LOW);
        digitalWrite(ledv, LOW);
        digitalWrite(ledr, HIGH);
        digitalWrite(alim_unite, LOW);
        digitalWrite(alim_dizaine, LOW);
      
        temps = millis();
        
      }
      
      void loop() {
        if(temps - millis() > 10){
          digitalWrite(alim_unite, HIGH);
          digitalWrite(alim_dizaine, LOW);
          afficher_nombre(i);
        }
        else{
          digitalWrite(alim_unite, LOW);
          digitalWrite(alim_dizaine, HIGH);
          afficher_nombre(i);
        }
        etat_entre = digitalRead(bouton_entre);
        if(etat_entre == LOW);{
          i++;
          }
        etat_sortie = digitalRead(bouton_sortie);
        if(bouton_sortie == LOW);{
          i--;
          }
        if(i > 100);{
          i = 100;
          }
        if(i  9){
          dizaine = nombre/10;
          afficher(dizaine);
          }
        unite = nombre - dizaine*10;
        afficher(unite);
        }
      
      void afficher(char chiffre){
        digitalWrite(DecA, LOW);
        digitalWrite(DecB, LOW);
        digitalWrite(DecC, LOW);
        digitalWrite(DecD, LOW);
      
        if(chiffre >= 8){
          digitalWrite(DecD, HIGH);
          chiffre = chiffre - 8;
          }
        if(chiffre >= 4){
          digitalWrite(DecC, HIGH);
          chiffre = chiffre - 4;
          }
        if(chiffre >= 2){
          digitalWrite(DecB, HIGH);
          chiffre = chiffre - 2;
          }
        if(chiffre >= 1){
          digitalWrite(DecA, HIGH);
          chiffre = chiffre - 1;
          }
        
        }
      
      Ok la j'ai tout vérifié avant de commenter, normalement c'est bon.
      • Il y a quelques incoherences dans les noms de fonctions (afficher et afficher_nombre par exemple). Aussi il va falloir faire une detection de front, car si le vehicule reste devant le capteur tu vas avoir une belle incrementation en peu de temps 😉 Enfin, ta fonction d’affichage ne prend pas en parametre le nom de l’afficheur donc tu afficheras toujours sur le meme affichage 😉

        Je te conseille cependant vivement d’essayer de faire le montage en vrai, j’ai surement raté des choses en relisant le code. Il existe aussi des simulateurs en ligne comme 123dcircuits

        • Merci pour tes conseils. Je me suis décidé a en acheter une finalement et tu avais raison 😉

  7. Bonjour, après une longue analyse de ton code, j’ai une petite incompréhension…
    Ton Code ci-dessous avec 2 commentaires

    //Les broches sont toutes mises à l’état bas (sauf led rouge éteinte)
    digitalWrite(bit_A, LOW);
    digitalWrite(bit_B, LOW);
    digitalWrite(bit_C, LOW);
    digitalWrite(bit_D, LOW);
    digitalWrite(alim_dizaine, LOW);
    digitalWrite(alim_unite, LOW);
    digitalWrite(led_rouge, HIGH); <– Si LED rouge éteinte c'est LOW qu'il faut
    digitalWrite(led_verte, LOW); //vert par défaut <– Si vert par défaut c'est HIGHT qu'il faut
    temps = millis(); //enregistre "l'heure"

    Je n'ai peut-être pas tout compris.
    En tout cas, BRAVO pour ton dévouement a tenter de faire comprendre a des ignares comme moi.
    Merci

  8. Bonjour,

    Bravo pour ce blog, c’est vraiment sympa d’aider les autres comme ça et surtout gratuitement.

    Sur ton programme lié au parking tu aurais pas inverser sur tes variables globales ( btn_entree, btn_sortie) l’incrémentation et la décrémentation de la variable « place_dispo » pour l’afficheur.
    Car quand une voiture rentre dans le parking on se trouve avec une place disponible en moins et quand une voiture sort du parking on se trouve avec une place en plus dans le parking.

    Merci d’avance pour votre réponse et bravo encore pour ce blog ainsi que merci car c’est d’une grand aide pour ceux qui débute sur les arduino.

  9. Bonjour,

    Je trouve cette page excellente ! J’apprécie beaucoup ce genre de TP. Simple mais efficace. Je me demandais aussi s’il etait possible d’y ajouter un bouton « reset » qui réinitialiserai le nombre de places à 0 ?

    Merci d’avance et bonne continuation !