Partage
  • Partager sur Facebook
  • Partager sur Twitter

Arduino, afficheur 2*7 segments

    15 août 2011 à 11:49:41

    Bonjour,

    je me suis récemment mis à arduino et après avoir "démonté" un appareil électronique pour récupérer un afficheur 2*7 segment à anodes communes, je l'ai branché avec un registre à décalage en adaptant ce tuto : ShiftOut. Malheureusement, du fait que les cathodes soient reliées deux à deux, je n'arrive à afficher des chiffres que sur un seul affichage, ou le même sur les deux (en reliant les anodes).

    Je possède un réseau de 7 transistors de puissance et 2 optocoupleurs s'ils peuvent être utiles, et je pourrai acheter demain après midi des composants s'ils peuvent être utiles.
    Si vous pouviez m'aider à trouver une solution je vous en serais redevable !

    Voici le cablage interne de l'afficheur.
    Image utilisateur

    Merci bien !!
    • Partager sur Facebook
    • Partager sur Twitter
      15 août 2011 à 16:37:13

      Ahhhh de l'électronique !

      Si je comprend bien, tu veux pouvoir t'amuser à afficher un nombre différent sur chacun des afficheurs...

      Sur celui que tu as récupéré, le constructeur emploie une technique dite de "multiplexage" pour éviter d'avoir 14 fils de donnée (7 par afficheur). A la place, il pilote 7 fils de données (le nombre à afficher, les connecteurs du bas sur ton schéma) et pilote ensuite l'affichage en alimentant ou non chacun des afficheurs.

      Par exemple, pour afficher un nombre sur celui de gauche, tu places les bons niveaux (actif à l'état bas) sur les pins de donnée, puis tu alimentes (au travers d'un transistor) la pin 10 (et pin 5 à la masse). Pouf, le nombre apparait à gauche.

      Ensuite, même combat à droite en alimentant la pin 5 et mettant la 10 à la masse.

      En faisant ca à une fréquence de plus de 50Hz, l'oeil ne verras pas le scintillement (phénomène de persistance rétinienne) et tu auras l'impression d'affiché des chiffres différents à droite et à gauche...

      Et voila !
      • Partager sur Facebook
      • Partager sur Twitter

      Retrouvez moi sur mon blog et ma chaine Youtube !

        15 août 2011 à 17:21:53

        Merci beaucoup :)

        Et donc j'ai juste à utiliser deux registres à décalage et à les alimenter successivement à une fréquence de 50Hz ?
        Comment je peux gérer la fréquence sans utiliser de délais, en clair pouvoir faire évoluer mon programme sans y penser ? Ou alors je dois me faire un hacheur avec un rapport à 0.5?
        • Partager sur Facebook
        • Partager sur Twitter
          15 août 2011 à 17:26:26

          Avec Arduino, tu peux utiliser des timers.
          Programme un timer à 50Hz et dans la fonction appelé par ce dernier tu met le code pour envoyer la valeur à l'afficheur et quel afficheur à utilisé.
          • Partager sur Facebook
          • Partager sur Twitter

          Retrouvez moi sur mon blog et ma chaine Youtube !

            15 août 2011 à 17:34:17

            Ce ne serait pas pas la fonction tone plutôt ? Je vois pour mettre les fréquences, mais comment les faire parfaitement alterner, en utilisant un délai de 2ms entre les deux ?
            • Partager sur Facebook
            • Partager sur Twitter
              15 août 2011 à 18:25:30

              Le truc c'est qu'avec la fonction "tone" tu vas juste pouvoir faire alterner la broche qui alimente les afficheurs (l'un avec un PNP et l'autre avec un NPN)

              Il y a donc deux solutions au problème.
              Soit tu cherches un peu sur le web pour créer une interruption sur un timer (car arduino ne propose pas de méthode simple pour ca)
              Mots clés: arduino, timer, interrupt

              Soit dans ta boucle loop, tu compares le temps courant et le temps auxquel à été executé la derniere fois ta fonction. Si cette différence est supérieur ou égal à 2 ms, tu executes ta fonction qui permet l'affichage

              Les deux sont biens. La première est plus rigoureuse mais plus difficile. La seconde, plus "bricolage" fonctionnent cependant très bien aussi et est souvent reprise (car on peut faire une infinité théorique de "timer" avec)
              • Partager sur Facebook
              • Partager sur Twitter

              Retrouvez moi sur mon blog et ma chaine Youtube !

                15 août 2011 à 20:42:27

                Pour le timer, ça a l'air assez simple avec MsTimer2, je vais de ce pas essayer !

                EDIT :

                Ca marche ! J'ai pour l'instant allumé un seul segment par afficheur. Seulement il faut alterner en même temps les cathodes et les anodes, ce qui me fait perdre 2 sorties de plus. J'avais pensé à utiliser mes optocoupleurs, pour les essayer mais j'ai peur que le délai fausse mon affichage (<1ms je crois)

                2ms ça fait pas 500Hz plutôt ? Enfin 250, puisque une période est un allumage et une extinction, donc 4ms. Je vais donc mettre 10ms ou un peu moins pour avoir réellement 50Hz

                donc là je pense que le délai des optocoupleurs sera négligeable. Je n'ai plus qu'à les essayer.

                C'est marrant, ecrire me permet de réfléchir, et du coup j'en ai encore à écrire.

                le datasheet de mos optocoupleurs
                • Partager sur Facebook
                • Partager sur Twitter
                  15 août 2011 à 22:21:07

                  Alors je crois que j'ai pas tout bien expliqué :)

                  Les transistors PNP et NPN ont un comportement antagonistes (pour le même signal de base, quand l'un passe, l'autre bloque et vice-versa)
                  Donc tu utilises une pin pour la "sélection de l'afficheur". En utilisant un PNP et un NPN pour passer le courant(broche 5 et 10 de l'afficheur).
                  Quand tu mettras un 1 sur cette broche, ca activera l'un et éteindra l'autre et quand tu mettras un 0 ca fera le contraire.

                  Ensuite, tu relies les broches de données à des broches numériques de ton arduino. Elles serviront à mettre le bon chiffre sur ton afficheur.

                  Pour faire un "affichage complet" tu passeras deux fois dans une fonction suivante (exemple):

                  void affichage(char chiffre)
                  {
                     static boolean choixafficheur = false; //static pour que ca soit pas effacé en sortie de fonction
                     //met a jour la pin de commande de l'afficheur
                     digitalWrite(cathode, choixafficheur);
                     pin = !pin; //pour alterner d'afficheur au prochain affichage
                     //met a jour le segment...en théorie a faire en fonction de "chiffre"
                     digitalWrite(pin_chiffre_1, HIGH); // ou LOW ...
                  }
                  
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Retrouvez moi sur mon blog et ma chaine Youtube !

                    15 août 2011 à 23:38:14

                    Yes !
                    Le code est brouillon, mais ça marche.


                    #include <MsTimer2.h>
                    
                    //Pin connected to latch pin (ST_CP) of 74HC595
                    const int latchPin = 8;
                    //Pin connected to clock pin (SH_CP) of 74HC595
                    const int clockPin = 12;
                    ////Pin connected to Data in (DS) of 74HC595
                    const int dataPin = 11;
                    
                    const int E1 = 3;
                    
                    const int E2 = 5;
                      byte bitsToSend1 = B11100111;
                      byte bitsToSend2 = B01001010;
                    
                    int E=0;
                    
                    void setup() {
                      
                      pinMode(latchPin, OUTPUT);
                      pinMode(dataPin, OUTPUT);  
                      pinMode(clockPin, OUTPUT);
                      pinMode(E1, OUTPUT);  
                      pinMode(E2, OUTPUT);
                      Serial.begin(9600);
                      Serial.println("reset");
                      digitalWrite(latchPin, LOW);
                      shiftOut(dataPin, clockPin, LSBFIRST, bitsToSend2);
                      digitalWrite(latchPin, HIGH);
                      digitalWrite(E1, HIGH);
                      digitalWrite(E2, HIGH);
                      MsTimer2::set(10, Invert);
                      MsTimer2::start();
                    }
                    
                    void Invert()
                    {
                      if (E==0)
                      {
                        digitalWrite(E1, HIGH);
                        digitalWrite(E2, LOW);
                        digitalWrite(latchPin, LOW);
                        shiftOut(dataPin, clockPin, LSBFIRST, bitsToSend2);
                        digitalWrite(latchPin, HIGH);
                      }
                      else
                      {
                        digitalWrite(E1, LOW);
                        digitalWrite(E2, HIGH);
                        digitalWrite(latchPin, LOW);
                        shiftOut(dataPin, clockPin, LSBFIRST, bitsToSend1);
                        digitalWrite(latchPin, HIGH);
                      }
                      E=1-E;
                    }
                    
                    void loop() {
                      if (Serial.available() > 0) {
                        // ASCII '0' through '9' characters are
                        // represented by the values 48 through 57.
                        // so if the user types a number from 0 through 9 in ASCII, 
                        // you can subtract 48 to get the actual value:
                        int bitToSet = Serial.read() - 48;
                    
                      // write to the shift register with the correct bit set high:
                        registerWrite(bitToSet);
                      }
                    }
                    
                    void registerWrite(int nombre) {
                          Serial.println(nombre);
                      switch (nombre) {
                        case 0:
                        bitsToSend1 = B10000010;
                        break;
                        case 1:
                        bitsToSend1 = B11100111;
                        break;
                        case 2:
                        bitsToSend1 = B01001010;
                        break;
                        case 3:
                        bitsToSend1 = B01000110;
                        break;
                        case 4:
                        bitsToSend1 = B00100111;
                        break;
                        case 5:
                        bitsToSend1 = B00010110;
                        break;
                        case 6:
                        bitsToSend1 = B00010010;
                        break;
                        case 7:
                        bitsToSend1 = B11000111;
                        break;
                        case 8:
                        bitsToSend1 = B00000010;
                        break;
                        case 9:
                        bitsToSend1 = B00000110;
                        break;
                        default:
                        Serial.println("nombre hors dommaine");
                        break;
                      }
                          Serial.println(bitsToSend1);
                      if (Serial.available() > 0) {
                        // ASCII '0' through '9' characters are
                        // represented by the values 48 through 57.
                        // so if the user types a number from 0 through 9 in ASCII, 
                        // you can subtract 48 to get the actual value:
                        int nombre1 = Serial.read() - 48;
                            Serial.println(nombre1);
                      switch (nombre1) {
                        case 0:
                        bitsToSend2 = B10000010;
                        break;
                        case 1:
                        bitsToSend2 = B11100111;
                        break;
                        case 2:
                        bitsToSend2 = B01001010;
                        break;
                        case 3:
                        bitsToSend2 = B01000110;
                        break;
                        case 4:
                        bitsToSend2 = B00100111;
                        break;
                        case 5:
                        bitsToSend2 = B00010110;
                        break;
                        case 6:
                        bitsToSend2 = B00010010;
                        break;
                        case 7:
                        bitsToSend2 = B11000111;
                        break;
                        case 8:
                        bitsToSend2 = B00000010;
                        break;
                        case 9:
                        bitsToSend2 = B00000110;
                        break;
                        default:
                        Serial.println("nombre hors dommaine");
                        break;
                      }
                      }
                      Serial.println(bitsToSend2);
                    }
                    


                    Merci pour al solution des transistors NPN et PNP.
                    Par contre je n'ai pas trop compris ton code...
                    • Partager sur Facebook
                    • Partager sur Twitter
                      16 août 2011 à 12:24:30

                      Bah t'inquiete pas pour mon code, il était vraiment brouillon ^^, si tu as trouvé une solution qui te convient et que tu comprends et gères c'est le principal :)

                      Amuse toi bien !
                      • Partager sur Facebook
                      • Partager sur Twitter

                      Retrouvez moi sur mon blog et ma chaine Youtube !

                        16 août 2011 à 12:55:45

                        Merci. Maintenant je galère sur les transistors... A part faire rebooter arduino ils font pas grand chose^^ mais ça je trouverai (surement une résistance que j'ai oublié)... un grand merci !

                        EDIT :
                        Et enfin ma première led grillée... j'arrive à faire marcher 1 transistor à la fois, mais pas deux...
                        • Partager sur Facebook
                        • Partager sur Twitter
                          16 août 2011 à 13:47:29

                          Pourtant ca ne devrais pas être trop compliqué (enfin je dis ca mais je suis très mauvais dès qu'il s'agit de les polariser...)

                          Tout ce que je peux te dire c'est qu'il ont un comportoment antagonistes (pour les NPN et PNP) en régime saturé/passant (donc pas en amplificateur...)

                          Avec les bonne résistances sur la base et sur le collecteur ca devrait passer normalement...

                          Tu devrais avoir tes réponses sur ce site, vers le milieu... (transistor en commutation)

                          • Partager sur Facebook
                          • Partager sur Twitter

                          Retrouvez moi sur mon blog et ma chaine Youtube !

                            16 août 2011 à 14:41:24

                            C'est bon, je crois avoir trouvé mon erreur pour les transistors. (pour la diode, c'est juste que la tension à "très légèrement" dépassé les 5V).

                            Merci pour le lien.

                            EDIT : en fait j'arrive pas à les faire fonctionner en même temps...
                            • Partager sur Facebook
                            • Partager sur Twitter
                              19 août 2011 à 18:06:52

                              Rebonjour.

                              J'ai branché un transistor PNP sur la pin 10 de l'afficheur, et relié la pin de controle du transistor à une résistance de 22kohm et à une diode, le tout relié à l'autre bout à la pin 5 de l'afficheur et à la pin 5 d'arduino (E2 dans mon code).



                              quand la pin 5 (E2) est à l'état haut, le chiffre de gauche s'affiche et quand il est à l'état bas, le chiffre de droite s'affiche.

                              Pour le chiffre de gauche qui s'affiche à droite, il faudrait n'afficher aucun chiffre pendant que le registre à décalage change le chiffre. (je sais, c'est très clair :) )

                              Voila mon code pour changer d'afficheur :
                              void Invert()
                              {
                                if (E==0)
                                {
                               
                                  digitalWrite(E2, LOW);
                                  digitalWrite(latchPin, LOW);
                                  shiftOut(dataPin, clockPin, LSBFIRST, bitsToSend2);
                                  digitalWrite(latchPin, HIGH);
                                }
                                else
                                {
                                  digitalWrite(E2, HIGH);
                                  digitalWrite(latchPin, LOW);
                                  shiftOut(dataPin, clockPin, LSBFIRST, bitsToSend1);
                                  digitalWrite(latchPin, HIGH);
                                }
                                E=1-E;
                              }
                              
                              • Partager sur Facebook
                              • Partager sur Twitter
                                19 août 2011 à 18:30:28

                                Euh... je t'avourais que j'ai pas bien compris ce que tu voulais dire... XD
                                Tu veux pouvoir éteindre les deux afficheurs en même temps ??
                                • Partager sur Facebook
                                • Partager sur Twitter

                                Retrouvez moi sur mon blog et ma chaine Youtube !

                                  19 août 2011 à 18:42:03

                                  Ben en fait c'est ma conclusion pour mon probleme, mais oui... mais je sais pas comment faire sans rajouter une sortie (que je viens justement d'enlever en ajoutant le transistor).
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    19 août 2011 à 18:54:41

                                    Euh... tu n'a pas le choix... tu devras rajouter une sortie (soit pour piloter les transistors indépendamment l'un de l'autre) soit pour piloter l'alimentation en amont
                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    Retrouvez moi sur mon blog et ma chaine Youtube !

                                      20 août 2011 à 11:10:20

                                      Ok, dans ce cas le transistor ne sert à rien...

                                      Merci beaucoup pour toutes tes réponses !
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        20 août 2011 à 17:23:08

                                        Normalement les transistors servent à amener la puissance pour tes leds car c'est pas censé être le boulot du micro...
                                        • Partager sur Facebook
                                        • Partager sur Twitter

                                        Retrouvez moi sur mon blog et ma chaine Youtube !

                                        Arduino, afficheur 2*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