Partage
  • Partager sur Facebook
  • Partager sur Twitter

Plusieurs afficheur 7 segments

Problème code

    19 janvier 2013 à 19:58:14

    Bon, j'ai encore des problèmes avec mon arduino! Quoi que sa me permet d'apprendre beaucoup!

    J'ai par contre besoin de votre aide pour bien faire fonctionner mon circuit! Voila, je veux faire un compteur avec 2 afficheur 7 segments, un décodeur et 2 transistor..

    J'ai réussi a faire fonctionner un afficheur et faire un compte a rebours de 9.. Maintenant je veux le réaliser à 99! J'ai testé mon circuit avec un autre programme.. Donc je suis certain que sa ne vient pas du circuit!

    Voici le problème! Lorsque je lance mon programme, mon afficheur des unites affiche, 0...1...3...7... et plus rien! Donc le compte ne se fait vraiment pas bien! Je n'arrive pas à voir le problème, pouvez-vous m'aider? M

    erci d'avance

    Ps: Voila le code!

    const int bit_A = 2;
    const int bit_B = 3;
    const int bit_C = 4;
    const int bit_D = 5;
    
    const int alim_dizaine = 6;
    const int alim_unite = 7;
    
    void setup()
    {
      pinMode(bit_A, OUTPUT);
      pinMode(bit_B, OUTPUT);
      pinMode(bit_C, OUTPUT);
      pinMode(bit_D, OUTPUT);
      pinMode(alim_dizaine, OUTPUT);
      pinMode(alim_unite, OUTPUT);
      
      digitalWrite(bit_A, LOW);
      digitalWrite(bit_B, LOW);
      digitalWrite(bit_C, LOW);
      digitalWrite(bit_D, LOW);
      digitalWrite(alim_dizaine, LOW);
      digitalWrite(alim_unite, LOW);
    }
    
    void loop()
    { 
      for(char i=0; i<10; i++)
      {
        affichage_nombre(i);
      }
    }
    
    void affichage_nombre(char nombre)
    {
      long temps;
      char dizaine = 0, unite = 0;
    
        unite = nombre - (dizaine*10);
      
      temps = millis();
      while((millis()-temps) < 1000)
      {
        digitalWrite(alim_unite, HIGH);
        digitalWrite(alim_dizaine, LOW);
        affichage(unite);
      }
    }
    void affichage(char chiffre)
    {
      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;
      }
    }
    • Partager sur Facebook
    • Partager sur Twitter
      19 janvier 2013 à 21:45:13

      Je voit 3 problèmes dans ton code :

      -Le for ne va que jusqu'à 10

      -Dizaine est toujours égal à 0

      -Jamais alim_dizaine n'est sur HIGH

      • Partager sur Facebook
      • Partager sur Twitter
      2b||!2b   sqrt(4b²)
        19 janvier 2013 à 21:49:59

        Oui.. Je suis au courrant.. J'étais en train de faire fonctionner les unites en premier pour après m'attaquer au dizaine car sa ne fonctionnait pas!

        Mais même avec les 3 problèmes.. Sa n'expliquerait toujours pas pourquoi il affiche, 0...1...3...7... Plus rien!

        • Partager sur Facebook
        • Partager sur Twitter
          19 janvier 2013 à 22:29:08

          Ah, d'accord.

          Essaye quelque chose de simple :

          void loop()
          { 
            digitalWrite(alim_unite, HIGH);
            digitalWrite(alim_dizaine, LOW);
            for(char i=0; i<10; i++)
            {
              affichage(i);
              delay(500);
            }
          }
          • Partager sur Facebook
          • Partager sur Twitter
          2b||!2b   sqrt(4b²)
            19 janvier 2013 à 23:55:34

            C'est normal que ça t'affiche 1,3,7 puis rien. Je vois un problème dans ta fonction "affichage" : 

            • Tu mets tes sorties à 1 logique mais après tu ne les remets jamais à 0. Ça explique pourquoi ça fait 1,3,7 puis rien. Si tu n'effaces pas, ça donne : 0001 (1) puis 0011 (3) puis 0111 (7) et au final 1111 (sur un décodeur ça t'affiche pas un chiffre, normal...).

            L'idéal, pour ne pas s'encombrer avec des lignes de code superflues, ce serait tout simplement de "mapper" ton chiffre sur les sorties de ton microcontroleur, mais ça demande de connaître les opérations bits à bits et la manipulation des registres d'entrées/sorties.

            Exemple : 

            Imaginons que l'on branche les 4 entrées du décodeur sur 4 sorties du microcontroleur, disons tout à droite sur PORTB (c'est à dire sur les sorties 8, 9, 10, 11). Il suffirait d'écrire :

            PORTB = (PORTB & 0xF0) | chiffre;

            dans ta fonction affichage. C'est tout. Essaye, ça marche très bien ! Il faut juste faire les bons branchements.

            Si tu ne vois pas ce que je veux dire, je suis prêt à t'expliquer en détail ;)

            Voilà un exemple concret où la connaissance de notions un peu plus avancées sur les microcontroleurs permet de faire des choses plus simplement et plus rapidement.



            • Partager sur Facebook
            • Partager sur Twitter
              20 janvier 2013 à 6:49:42

              Wow!! Tu as mis le doigt sur le problème!! Je te remerci mille fois!

              Pour ce qui est du mappage, je n'y connais absolument rien! Je vais faire des recherches de mon côté, mais si tu repasses par ici que sa te dit de dirriger mes recherches un peu, je serais un homme comblé ;)

              J'ai enfin un compteur jusqu'à 99! :D

              • Partager sur Facebook
              • Partager sur Twitter
                20 janvier 2013 à 11:18:45

                Dans ta fonction affichage, il suffit de remettre à LOW les segments avant de faire un nouvel affichage :

                void affichage(char chiffre)
                {
                  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; } }



                • Partager sur Facebook
                • Partager sur Twitter

                Retrouvez moi sur mon blog et ma chaine Youtube !

                  20 janvier 2013 à 11:40:19

                  Voilà un lien pour les entrées/sorties. Et sinon tu peux aussi rechercher les opérateurs bits à bits en C/C++ et un peu d'algèbre booléenne si ça te chante. Si tu comprends bien toutes ces notions là, normalement tu comprendra la ligne de code que j'ai donné dans le message précédant. Mais après si tu veux que je t'explique directement, y a pas de soucis ;)
                  • Partager sur Facebook
                  • Partager sur Twitter
                    20 janvier 2013 à 11:44:06

                    Eskimon a écrit:

                    Dans ta fonction affichage, il suffit de remettre à LOW les segments avant de faire un nouvel affichage :

                    void affichage(char chiffre)
                    {
                      digitalWrite(bit_A, HIGH);
                      digitalWrite(bit_B, HIGH);
                      digitalWrite(bit_C, HIGH);
                      digitalWrite(bit_D, HIGH);
                    
                      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;
                      }
                    }

                    Petite erreur ;) Tu les as mis HIGH et pas LOW...



                    • Partager sur Facebook
                    • Partager sur Twitter
                      20 janvier 2013 à 14:28:00

                      Exact, erreur de précipitation ^^ c'est édité/corrigé
                      • Partager sur Facebook
                      • Partager sur Twitter

                      Retrouvez moi sur mon blog et ma chaine Youtube !

                        20 janvier 2013 à 17:00:15

                        Je vois que tu utilises tes digital IO pour alimenter tes 7-segments (40mA c'est suffisant après tout :)), j'espère juste que t'as pensés à mettre des résistances suffisantes ;).
                        Tu peux aussi jouer avec le PWM pour réguler l'alimentation moyenne.

                        Pour tes chiffres, mieux vaut utiliser la division par 10 et le modulo 10 que le signe - ;).

                        • Partager sur Facebook
                        • Partager sur Twitter
                          20 janvier 2013 à 19:13:28

                          Les I/O utilisés ne servent pas en alimentation, juste pour transmettre l'information au décodeur et aux transistors de choix de l'afficheur (ces derniers feront alors passer la puissance).

                          • Partager sur Facebook
                          • Partager sur Twitter

                          Retrouvez moi sur mon blog et ma chaine Youtube !

                            22 janvier 2013 à 1:48:31

                            J'ai une autre question concernant les afficheurs 7 segments..

                            Voici mon code.. Tout fonctionne, j'affiche le chiffre 6 comme voulu.

                            const int bit_A = 2;
                            const int bit_B = 3;
                            const int bit_C = 4;
                            const int bit_D = 5;
                            
                            void setup()
                            {
                              pinMode(bit_A, OUTPUT);
                              pinMode(bit_B, OUTPUT);
                              pinMode(bit_C, OUTPUT);
                              pinMode(bit_D, OUTPUT);
                            }
                            
                            void loop()
                            {
                              char i=6;
                              affichage(i);
                              delay(1);
                            }
                            
                            void affichage(char chiffre)
                            {
                              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;
                              }
                            }
                            Par contre, quand j'enleve le delay(1); , il m'affiche 8...! Bizarre.. J'essaie de comprendre pourquoi, mais je n'y arrive pas!
                            void loop()
                            {
                              char i=6;
                              affichage(i);
                            }

                            PS: En fesant d'autre test, j'ai remarquer que ce n'est pas tout a fait le chiffre 8 qui s'affiche.. En fait, le chiffre 6 était affiché, mais seulement LÉGÈREMENT plus éclairé que le reste.. Donc sans le delay, le problème est que le courrant continue d'aller dans les autres segments.. Pourquoi? :p

                            • Partager sur Facebook
                            • Partager sur Twitter
                              22 janvier 2013 à 10:58:52

                              Le problème vient tout simplement du fait que la fonction digitalWrite() ne modifie l'état que d'une seule sortie à la fois.

                              Avec l'exemple du 6 affiché, tu as les bits B et C qui sont à 1. Quand les bits sont remis à 0 dans ta fonction, pendant un court instant tu n'as que le bit C encore un 1. N'est-ce pas ? Cet instant est très court, mais suffisant pour te faire afficher brièvement un 4 sur l'afficheur. Et comme tu enlèves le delay(), les instructions sont exécutées à la suite en permanence et sans arrêt. Ce qui te donne l'impression de voir un 8 et pas un 6, parce que tu as en permanence un 6 et un 4 qui alternent sur l'afficheur. Mais quand tu mets le delay(), le temps pendant lequel l'afficheur affiche 4 est trop court par rapport au temps pendant lequel l'afficheur affiche 6. C'est pour ça que là, tu ne vois qu'un 6.

                              Donc, pour éviter ce problème, il faudrait soit laisser un délai après être passé dans la fonction affichage, soit tu change l'état de toutes les sorties en même temps. Et donc pour ça tu es obligé de passer par la manipulation d'un registre d'E/S. La ligne de code que j'ai donné auparavant répond exactement à ton problème (si tu veux te dispenser d'un delay()). Cette solution est la plus pratique, la plus simple, la moins contraignante (pas de delay() imposé) et la moins coûteuse en opérations (1 ligne de code).

                              D'ailleurs si tu veux la tester, il faudra au préalable brancher l'entrée A sur la sortie 8, B sur 9, C sur 10, D sur 11 (si tu es sur la UNO).

                              • Partager sur Facebook
                              • Partager sur Twitter
                                24 janvier 2013 à 10:07:57

                                L'erreur se trouve dans le parametre de la fonction afficher(char nombre) et dans les boucles (char i):donc il faut remplacer char par int
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  24 janvier 2013 à 10:19:17

                                  Pourquoi tu ne pourrais pas mettre un char dans un for ?
                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  Retrouvez moi sur mon blog et ma chaine Youtube !

                                    24 janvier 2013 à 11:15:14

                                    Mehdi Elgaïdi a écrit:

                                    L'erreur se trouve dans le parametre de la fonction afficher(char nombre) et dans les boucles (char i):donc il faut remplacer char par int


                                    Même chose qu'Eskimon : qu'est-ce qui t'empêche d'utiliser un char ?

                                    Et puis non, ce n'est clairement pas ça la cause.

                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    Plusieurs afficheur 7 segments

                                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                    • Editeur
                                    • Markdown