Compte à rebours avec Arduino uno - Page 2
Répondre à la discussion
Page 2 sur 2 PremièrePremière 2
Affichage des résultats 31 à 34 sur 34

Compte à rebours avec Arduino uno



  1. #31
    Yvan_Delaserge

    Re : Compte à rebours avec Arduino uno


    ------

    Bonjour à tous,

    Je viens de réaliser un affichage multiplexé avec mon Arduino. J'ai réalisé le montage avec un IC décodeur 7 segments et trois transistors commandés par l'Arduino pour le multiplexage Je suis parti de la doc d'Eskimon page 169 et j'ai adapté son programme. J'ai rencontré quelques difficultés, mais finalement, ça marche.

    Pour mémoire, voici le logiciel d'Eskimon: Il sert à gérer le nombre de voitures d'un parking. Je n'ai repris que les parties qui servent à réaliser un affichage multiplexé à 3 chiffres. Et j'y ai ajouté un simple compteur de 0 à 999.

    Code:
    //les broches du décodeur 7 segments
    const int bit_A = 2;
    const int bit_B = 3;
    const int bit_C = 4;
    const int bit_D = 5;
    //les broches des transistors pour l'afficheur des dizaines et celui des unités
    const int alim_dizaine = 6;
    const int alim_unite = 7;
    //les broches des boutons
    const int btn_entree = 8;
    const int btn_sortie = 9;
    //les leds de signalements
    const int led_rouge = 12;
    const int led_verte = 11;
    //les mémoires d'état des boutons
    int mem_entree = HIGH;
    int mem_sortie = HIGH;
    int etat = HIGH; //variable stockant l'état courant d'un bouton
    char place_dispo = 10; //contenu des places dispos
    bool afficheur = false;
    long temps;
    void setup()
    {
    //Les broches sont toutes des sorties (sauf les boutons)
    pinMode(bit_A, OUTPUT);
    pinMode(bit_B, OUTPUT);
    pinMode(bit_C, OUTPUT);
    pinMode(bit_D, OUTPUT);
    pinMode(alim_dizaine, OUTPUT);
    pinMode(alim_unite, OUTPUT);
    pinMode(btn_entree, INPUT);
    pinMode(btn_sortie, INPUT);
    pinMode(led_rouge, OUTPUT);
    pinMode(led_verte, OUTPUT);
    //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);
    digitalWrite(led_verte, LOW); //vert par défaut
    temps = millis(); //enregistre "l'heure"
    }
    
    void loop()
    {
    //si ca fait plus de 10 ms qu'on affiche, on change de 7 segments
    if((millis() temps)
    > 10)
    {
    //on inverse la valeur de "afficheur" pour changer d'afficheur (unité ou dizaine)
    afficheur = !afficheur;
    //on affiche
    afficher_nombre(place_dispo, afficheur);
    temps = millis(); //on met à jour le temps
    }
    //on test maintenant si les boutons ont subi un appui (ou pas)
    //d'abord le bouton plus puis le moins
    etat = digitalRead(btn_entree);
    if((etat != mem_entree) && (etat == LOW))
    place_dispo += 1;
    mem_entree = etat; //on enregistre l'état du bouton pour le tour suivant
    //et maintenant pareil pour le bouton qui décrémente
    etat = digitalRead(btn_sortie);
    if((etat != mem_sortie) && (etat == LOW))
    place_dispo =
    1;
    mem_sortie = etat; //on enregistre l'état du bouton pour le tour suivant
    //on applique des limites au nombre pour ne pas dépasser 99 ou 0
    if(place_dispo > 99)
    place_dispo = 99;
    if(place_dispo < 0)
    place_dispo = 0;
    //on met à jour l'état des leds
    //on commence par les éteindre
    digitalWrite(led_verte, HIGH);
    digitalWrite(led_rouge, HIGH);
    if(place_dispo == 0) //s'il n'y a plus de place
    digitalWrite(led_rouge, LOW);
    else
    digitalWrite(led_verte, LOW);
    }
    //fonction permettant d'afficher un nombre
    void afficher_nombre(char nombre, bool afficheur)
    {
    long temps;
    char unite = 0, dizaine = 0;
    if(nombre > 9)
    dizaine = nombre / 10; //on récupère les dizaines
    unite = nombre (
    dizaine*10); //on récupère les unités
    if(afficheur)
    {
    //on affiche les dizaines
    digitalWrite(alim_unite, LOW);
    digitalWrite(alim_dizaine, HIGH);
    afficher(dizaine);
    }
    else
    {
    //on affiche les unités
    digitalWrite(alim_dizaine, LOW);
    digitalWrite(alim_unite, HIGH);
    afficher(unite);
    }
    }
    
    //fonction écrivant sur un seul afficheur
    void afficher(char chiffre)
    {
    //on commence par écrire 0, donc tout à l'état bas
    digitalWrite(bit_A, LOW);
    digitalWrite(bit_B, LOW);
    digitalWrite(bit_C, LOW);
    digitalWrite(bit_D, LOW);
    if(chiffre >= 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;
    }
    }
    Eskimon (qui vient du C) utilise des variables de type char, c'est-à dire qu'il s'agit d'un octet. Il le fait de préférence à int, qui en utilise deux.

    Or, si on se plonge dans la doc Arduino, on voit que:

    INT are your primary data-type for number storage.

    alors que:

    CHAR is a data type that takes up 1 byte of memory that stores a character value.

    Je me suis dit que si mon Arduino essayait d'envoyer des caractères ASCII aux afficheurs 7 segments, cela pourrait poser problème, mais à la réflexion, non puisque le contenu de l'octet reste le même. Cependant, si l'on utilise print pour voir ce que l'Arduino envoie aux afficheurs, on voit bel et bien des caractères ASCII, pas des chiffres.

    N'étant pas en manque de place mémoire, j'ai remplacé les CHAR par des INT.

    Le second problème que j'ai rencontré a été que les afficheurs ne s'allumaient pas séquentiellement, avec le code que voici:
    Code:
    void afficher_nombre(int nombre, int afficheur)
    {
    int centaine = nombre / 100;  //on récupère les centaines
    int dizaine = (nombre / 10) - (centaine * 10); //on recupere les dizaines
    int unite = nombre - (centaine * 100) - (dizaine*10); //on recupere les unités
    
    if(afficheur= 1)
    {
    digitalWrite(alim_unite, HIGH);
    digitalWrite(alim_dizaine, LOW);
    digitalWrite(alim_centaine, LOW);
    afficher(unite);
    }
    
    else if(afficheur= 2)
    {
    digitalWrite(alim_unite, LOW);
    digitalWrite(alim_dizaine, HIGH);
    digitalWrite(alim_centaine, LOW);
    afficher(dizaine);
    }
    
    else if(afficheur= 3)
    {
    digitalWrite(alim_unite, LOW);
    digitalWrite(alim_dizaine, LOW);
    digitalWrite(alim_centaine, HIGH);
    afficher(centaine);
    }
    Seul l'afficheur des centaines s'allumait. Je n'ai toujours pas compris pourquoi! Si quelqu'un arrive à me l'expliquer, je l'en remercie d'avance!

    J'ai résolu le problème en utilisant la fonction suivante:

    Code:
    //fonction permettant d'afficher un nombre
    void afficher_nombre(int nombre, int afficheur)
    {
    int centaine = nombre / 100;  //on récupère les centaines
    int dizaine = (nombre / 10) - (centaine * 10); //on recupere les dizaines
    int unite = nombre - (centaine * 100) - (dizaine*10); //on recupere les unités
    
    switch (afficheur) {
        case 1:
          digitalWrite(alim_unite, HIGH);
          digitalWrite(alim_dizaine, LOW);
          digitalWrite(alim_centaine, LOW);
          afficher(unite);
          break;
        case 2:
          digitalWrite(alim_unite, LOW);
          digitalWrite(alim_dizaine, HIGH);
          digitalWrite(alim_centaine, LOW);
          afficher(dizaine);
          break;
        case 3:
          digitalWrite(alim_unite, LOW);
          digitalWrite(alim_dizaine, LOW);
          digitalWrite(alim_centaine, HIGH);
          afficher(centaine);
          break;
          }
    }
    La seconde difficulté que j'ai rencontrée était un manque de contraste de l'affichage, c'est-à-dire que les segments non utilisés des afficheurs ne s'éteignaient pas complètement.
    La situation s'est améliorée en introduisant une pause de 5 millisecondes entre les allumages des afficheurs.

    Dans le programme d'Eskimon, on a la boucle principale (loop) qui teste à chaque passage si 10 millisecondes se sont écoulées depuis le dernier changement d'afficheur.

    Code:
    void loop()
    {
    
      //si ca fait plus de 5 ms qu'on affiche, on change de 7 segments
    if ((millis() - temps) >5)
    {
    //on update la valeur de "afficheur" 
    afficheur = afficheur+1;
    if (afficheur >3) {afficheur = 1;}
    temps = millis();
    //on update la valeur de "compteur"
    compteur=compteur+1;
    }
    
    if(compteur>9999){compteur = 0;}
    int comptaff= compteur/10;
    
    //on affiche
    afficher_nombre(comptaff, afficheur);
    }
    J'ai modifié le délai de 10 à 5 msec. Et j'ai introduit un délai de 5 msec après l'envoi du mot BCD au décodeur 7 segments.

    Code:
    //fonction écrivant sur un seul afficheur
    void afficher(int chiffre)
    {
    //on commence par écrire 0, donc tout à l'état bas
    digitalWrite(bit_A, LOW);
    digitalWrite(bit_B, LOW);
    digitalWrite(bit_C, LOW);
    digitalWrite(bit_D, LOW);
    if(chiffre >= 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;
    }
    delay (5);
    }
    Et comme ça, ça ne fonctionne pas trop mal. Y aurait-il moyen de faire mieux?

    Merci d'avance,

    Yvan

    -----
    Un civet, un plat de côtes et puis, glissez-moi une petite paupiette avec.( Lino Ventura)

  2. #32
    mag1

    Re : Compte à rebours avec Arduino uno

    Bonjour,

    Pas encore eu le temps de me pencher sur le clone arduino.

    Mais pour un compte à rebours, j'ai l'alternative picaxe toute prête:
    http://electromag1.wifeo.com/minuter...eur-tm1637.php

    On trouve des afficheurs TM1637 entre 2 et 3 euros sur eBay, voir la vidéo sur l'autre page

    MM
    Si il y a des erreurs ci dessus, c'est que je n'ai pas eu le temps de les corriger...

  3. #33
    Yvan_Delaserge

    Re : Compte à rebours avec Arduino uno

    Les afficheurs sont effectivement bon marché, tout comme les décodeurs.
    J'ai utilisé des afficheurs triples à cathode commune à $2,86 les 5 pièces
    et des décodeurs HEF 4511B à $ 2,50 les 10 pièces.

    Pour le contraste des afficheurs, la clé du succès est d'observer un délai juste après avoir envoyé le mot BCD au décodeur.
    Même une milliseconde améliore déjà les choses.
    Apparemment, le problème venait du décodeur (?). Il a besoin d'une certaine stabilité sur ses entrées BCD (?). C'est intéressant. Je vais regarder ce que ça donne à l'oscillo.
    J'ai fini par supprimer complètement le délai de multiplexage de la boucle principale. Le délai de 5 millisecondes entre chaque changement d'afficheur est observé après l'envoi du mot BCD au décodeur.
    Un civet, un plat de côtes et puis, glissez-moi une petite paupiette avec.( Lino Ventura)

  4. #34
    invite6170f95c

    Re : Compte à rebours avec Arduino uno

    WOUAHHHH!!!.
    Merci pour Cette réponse avec tous le code et tout!!!! MERCI!!!!
    Mais c'est quel code le résultat final?
    Et vu que je n'ai qu'un 4 digits, il faut simplement ne pas brancher le digit non utilisé ?

Page 2 sur 2 PremièrePremière 2

Discussions similaires

  1. création d'un compte à rebours !
    Par invite946dfcf4 dans le forum Électronique
    Réponses: 2
    Dernier message: 19/05/2012, 11h40
  2. fabriquer un compte à rebours
    Par invite51ced213 dans le forum Électronique
    Réponses: 6
    Dernier message: 12/12/2007, 18h05
  3. Compte à rebours
    Par invitebda49094 dans le forum Logiciel - Software - Open Source
    Réponses: 0
    Dernier message: 06/06/2006, 10h12
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...