Partage
  • Partager sur Facebook
  • Partager sur Twitter

74HC595 - Perte de luminositée des leds

Question sur l'utilisation de condensateurs

Sujet résolu
    22 octobre 2013 à 23:40:46

    ha attends j'ai dit une bêtise, tu peux pas le faire ça le pont diviseur de tension, "il débite du courant du coup ça marche pas"...

    l'idée serait d'avoir un 5V bien propre et même un peu plus, c'est pas très gênant, le tout étant de pas griller les shift registers (74 HC 595? j'ai plus ta référence...) et surtout bien stable. le truc c'est que ce genre de choses nécessitent un peu de matériel... à tout hasard t'aurais pas un régulateur de tension 7805 et 2 gros condos qui trainent sous la main? (sinon ne t'embête pas à acheter, c'est pas très cher, mais le résultat est pas garanti alors... on cherchera d'autres pistes avant)

    quel genre de matériel as-tu chez toi? je veux dire par là matériel de mesure électrique (voltmetre, oscilloscope, analyseur de trames, etc?

    -
    Edité par remace 23 octobre 2013 à 0:45:17

    • Partager sur Facebook
    • Partager sur Twitter

    oui. non. enfin je regarde et je te dis.

      23 octobre 2013 à 11:51:59

      Oui ce sont des 74HC595, pour le 7805 et 2 gros condo je doit pouvoir trouver ça, 1000uF ça te parait assez gros? Niveau matériel j'ai un voltmètre de disponible, le reste je n'ai pas :(

      J'ai aussi fait le test de brancher un interrupteur sur l'alim générale, quelle sois via arduino ou pile. Et lorsque que je coupe cette alim, les leds sont quand même allumées très très faiblement, donc apparemment le courant de sorties des pins traverse le circuit de manière à éclairé les leds, peut être que celà pose problèmes aussi? Car ça ne devrais pas être le cas non? Il doit y avoir un moyen de supprimer ce courant ?

      -
      Edité par CactusTribe 23 octobre 2013 à 12:23:34

      • Partager sur Facebook
      • Partager sur Twitter
        23 octobre 2013 à 14:56:59

        oui pour moi ça vient aussi du circuit, ton code est on ne peut plus propre et simple. et donc tu dis que tu as mis un interrupteur sur le bloc piles, c'est ça?

        (les condensateurs, plus petits tu as? un seul condensateur de 10µF sur la sortie du régulateur suffirait, comme en entrée c'est des piles.)

        pour l'instant ton bloc piles alimente quoi exactement? 

        avant de regarder les montages d'alim (parce qu'on en est même pas sûrs que ça vient de là), ce qu'il faudrait déterminer c'est d'où vient le problème: des transistors, t'en as combien? 1 par couche + 1 par colonne? seulement 1 par couche? encore moins?

        en tout cas, il faudrait mesurer les tensions des couches "qui produisent beaucoup de fantomes" par rapport à la valeur qu'elles sont censées avoir: pour ça essaye de n'allumer qu'une diode ou deux (enfin selon ton programme, qui fait quand même le balayage, le but étant de chercher d'où viennent les fantômes, il vaudrait mieux qu'il y en ait), pareil pour les colonnes, la tension entre les colonnes et le 4.5V (ou 0, je me rappelle plus du sens de ton montage, le but étant que si ça marche bien, il y ait 0V sur le voltmetre).

        • Partager sur Facebook
        • Partager sur Twitter

        oui. non. enfin je regarde et je te dis.

          23 octobre 2013 à 18:01:58

          Alors entre temps j'ai réussis à supprimer l'effet fantomes en reliant les masses des shift registers à l'arduino, avant elles étaient reliées au - de la pile.

          Je récapitule les différents branchements du montage :


          Vcc + MR des 595                      ------>  + Pile

          OE + GND des 595                    ------>   GND Arduino

          Sorties 595 colonnes (8+8)      ------>  Anodes LEDs

          Collecteurs des 4 transistors    ------>  Cathodes LEDs

          Bases des 4 transistors            ------>  Sorties 595 étages (4)

          Emeteurs des 4 transistors      ------>  - Pile

          Mesures :

          V colonnes ON = 0.47

          V colonnes OFF = -0.75

          V étages ON = -0.83

          V étanges OFF = -1.0

          Toute ses mesures effectuées quand le programme des 2leds fonctionne.

          Je n'ai plus les effets de fantomes donc, mais du coup le fait de passé en alimentation séparé ne permet pas (à ce stade) d'augmenté la luminosité des leds lors d'un affichage important de pixels.

          • Partager sur Facebook
          • Partager sur Twitter
            23 octobre 2013 à 19:06:27

            ha mais t'avais pas relié les masses arduino et pile ensemble? désolé de pas l'avoir mieux dit avant, alors:euh:

            CactusTribe a écrit:

            Alors entre temps j'ai réussis à supprimer l'effet fantomes en reliant les masses des shift registers à l'arduino, avant elles étaient reliées au - de la pile.

            mais... plus de fantomes, plus de problèmes?:D

            bon plus sérieusement, je vais aller voir mieux comment fonctionnent les 74HC595 et je te dis mieux dès que j'ai fini. maintenant, pour moi c'est plus qu'un problème de programme. (ton truc d'écrire les leds une par une dans les registres là ça me parait pas OP comme truc)

            -
            Edité par remace 23 octobre 2013 à 19:09:18

            • Partager sur Facebook
            • Partager sur Twitter

            oui. non. enfin je regarde et je te dis.

              23 octobre 2013 à 19:15:44

              Justement si j'avais relié les masses arduino et pile, et je viens de les séparé ce qui as permis d'enlever les fantomes !

              Le problème de base était la luminosité des LEDs, l’hypothèse était que l'usb n'alimentais pas suffisamment, maintenant avec la pile on peut voir que ça ne change rien au problème x)

              Si jamais tu connais l'ULN2803 (réseau de transistor) j'en ai à disposition si sa peut être plus opti ?

              C'est vrais que le code est pas forcément opti, mais je n'ai pas trouvé une autre façon de faire, je suis débutant tout de même haha, j'ai pas tout les reflexes et tout n'est pas très claire dans ma tête :lol:

              -
              Edité par CactusTribe 23 octobre 2013 à 19:17:58

              • Partager sur Facebook
              • Partager sur Twitter
                23 octobre 2013 à 19:41:46

                bon. alors si tu as la masse de l'arduino sur les 74HC... il faudrait que tu leur donne aussi l'alimentation de l'arduino. sinon c'est pas beau^^ 

                en fait, j'ai l'impression que quand tu "allume beaucoup de diodes", ton programme est assez lent pour que la luminosité soit moins bonne... essaye de rajouter DelayMicroseconds(10) dans ta fonction affichage pixel, n'importe ou, et lance un programme qui est censé afficher beaucoup de led et qui utilise cette fonction.

                • Partager sur Facebook
                • Partager sur Twitter

                oui. non. enfin je regarde et je te dis.

                  23 octobre 2013 à 20:27:19

                  déjà, j'ai une idée: écrivons le programme pour être tout le temps dans le pire des cas: créer un tableau de booléens à 3 dimensions, ajouter l'état de la led à commander comme parametre de ta fonction affichage pixel, et balayer TOUTES les leds en permanence. 

                  donc pour résumer: en variable globale ou accessible via une référence ou un pointeur (je sais pas ce qui existe sur arduino pour passer un tableau sans en faire une copie en mémoire), un tableau:

                  cube [4][4][4] de booléens.

                  ta fonction affichage s'écrit maintenant comme ça: 

                  void affichagePixel(int x, int y, int z, boolean etat)
                  {
                      clearRegisters(); //on commence par mettre tout le monde à 0
                      setRegisterPin(16 + z, etat); //le choix de la couche
                      setRegisterPin(x+y*4, etat); //la led à allumer
                      writeRegisters();  //met à jour les registres à décalages
                   
                  }

                  et ton main c'est

                  for (x=0; x<4,x++)
                       {
                       for(y=0;y<4,y++)
                            {
                            for(z=0;z<4;z++)
                            {
                                 affichagePixel(x,y,z,cube[x][y][z];
                            }
                       }
                  }

                  comme ça on travaille "dans le pire des cas" tout le temps, et la luminosité ne dépend pas du nombre de led allumées.

                  -
                  Edité par remace 23 octobre 2013 à 20:30:47

                  • Partager sur Facebook
                  • Partager sur Twitter

                  oui. non. enfin je regarde et je te dis.

                    24 octobre 2013 à 1:37:49

                    Salut,

                    J'arrive après la bataille, dommage, je pense que j'aurais pu faire gagner un peu de temps.

                    Pour l'affichage, néanmoins je conseillerais plutôt le code suivant

                    int z=0;
                    void loop ()
                    {
                        setRegisterPin(16 + z, HIGH); //le choix de la couche
                        for(x=0;x<4,x++)
                        {
                            for(y=0;y<4;y++)
                            {
                                setRegisterPin(x+y*4, cube[x][y][z]); //allumer les leds qui doivent l'être à ce niveau
                            }
                        }
                        writeRegisters(); //met à jour les registres à décalages
                        setRegisterPin(16 + z, LOW); // on dé-sélectionne la couche
                        z=(z+1)%4
                        sleep(1); //attendre 1 ms pour que les gens voient les LEDs allumées. Image 250Hz \o/
                    }

                    Il n'y a plus qu'à ajouter du code pour changer les LEDs qu'on veut voir allumées (le code qui vient modifier le tableau cube)

                    L'avantage de ce code, c'est qu'il divise par 16 l'impression de clignotement (et il multiplie par 16 le rapport cyclique d'allumage des LEDs, donc on a l'impression que les LEDs brillent plus)

                    -
                    Edité par Natalya 24 octobre 2013 à 1:41:55

                    • Partager sur Facebook
                    • Partager sur Twitter
                    64kB de mémoire, c'est tout ce dont j'ai besoin
                      24 octobre 2013 à 13:18:39

                      Remace : Merci pour ton bout de code, j'ai essayer de le mettre en place sans  succès j'avais une erreur : to few argument in fonction void affichePixel. J'avais bien créer le tableau boolean cube[4][4][4];pourtant

                      J'ai par contre réussis à plus ou moins faire marché celui de Natalaya malgré encore quelques soucis, c'est à dire que je n'arrive pas à afficher la led (0,0,1) par ex, le code affiche tout les x et y du niveau z = 1, le tout - une led (x=3;y=3). Cependant coté luminosité rien à redire, c'est exactement la bonne intensité visible sans aucun problèmes de scintillement ! :D

                      La photo qui met en évidence le résultat :

                       Main :

                      void loop()
                      {  
                       affichagePixel(0,0,1);
                      }

                      AffichagePixel :

                      void affichagePixel(int x, int y, int z)
                      {
                        
                          int cube[4][4][4];
                        
                          setRegisterPin(16 + z, HIGH); //le choix de la couche
                          for(x=0;x<4;x++)
                          {
                              for(y=0;y<4;y++)
                              {
                                  setRegisterPin(x+y*4, cube[x][y][z]); //allumer les leds qui doivent l'être à ce niveau
                              }
                          }
                          writeRegisters(); //met à jour les registres à décalages
                          setRegisterPin(16 + z, LOW); // on dé-sélectionne la couche
                          z=(z+1)%4;
                          delay(1); //attendre 1 ms pour que les gens voient les LEDs allumées. Image 250Hz \o/
                      }


                      Cas particulier : au 3ème étage la led inactive à l'étage 2 (3;3) elle se met à clignoté de façon périodique x)



                      -
                      Edité par CactusTribe 24 octobre 2013 à 13:42:37

                      • Partager sur Facebook
                      • Partager sur Twitter
                        24 octobre 2013 à 13:28:58

                        natalya: en fait c'est un peu le genre de choses que je voulais arriver au final à lui faire faire, mais j'ai pas l'intuition de le faire en une fois^^ donc tu n'est pas du tout en retard. par contre, je vois un truc là dans ton programme, quand tu allume une led, tu ne l'éteins pas au "tour d'après", si?

                        et de ce que je vois, tu allume une couche à chaque fois non? donc pour un "petit cube" ça marche, mais pour cube plus un grand ça peut faire des consommations nettement plus grandes aussi (genre sur un 8x8x8 ça peut faire 64 LEDS à la fois, soit 1.2A)?

                        CactusTribe: regarde si ta led est pas grillée? (mets une autre led en parallèle de celle-ci, pas besoin de souder, juste mets la en contact avec les mêmes points (enroule les pattes autour des fils, en plus c'est une led du bord, te fais pas chier) et vois

                        -
                        Edité par remace 24 octobre 2013 à 13:45:04

                        • Partager sur Facebook
                        • Partager sur Twitter

                        oui. non. enfin je regarde et je te dis.

                          24 octobre 2013 à 13:55:46

                          Non non elle n'est pas grillé, car en modifiant la forme affiché, elle est encore fonctionnelle, c'est un soucis de codes je pense non?

                          • Partager sur Facebook
                          • Partager sur Twitter
                            24 octobre 2013 à 13:59:23

                            toutes les leds (3,3,z) s'allument normalement, sauf celle-ci?

                            pour vérifier que c'est bien un probleme de code, essaye d'éditer ton programme pour donner à chaque tour de boucle les indices et valeur de led dans ton IDE

                            -
                            Edité par remace 24 octobre 2013 à 14:08:02

                            • Partager sur Facebook
                            • Partager sur Twitter

                            oui. non. enfin je regarde et je te dis.

                              24 octobre 2013 à 14:26:10

                              Alors j'ai fait ça comme boucle :

                              animationFullLed :

                              void animationFullLed(int nbCycles)
                              {
                                  for(int i = nbCycles; i>0 ; i--)
                                {
                                      for(int z=0; z<4; z++)
                                      {
                                         for(int y=0; y<4; y++)
                                          {
                                          for(int x=0; x<4; x++)
                                            {
                                                affichagePixel(x,y,z); 
                                                
                                            }
                                          }
                              
                                      }
                              
                                } 
                              }

                              Main :

                              void loop()
                              {   
                                 animationFullLed(1);   
                              }

                              Résultat vidéo : http://www.youtube.com/watch?v=guhE9JYiOV4

                              On peut voir le clignotement périodique des leds


                              • Partager sur Facebook
                              • Partager sur Twitter
                                24 octobre 2013 à 14:43:04

                                pour vérifier le programme de natalya, tu peux rajouter une ligne qui écrit dans ta console PC avec l'écriture des registres dans les boucles for. ça doit ressembler à ça, mais je suis pas sûr.

                                serial.write("x :" + x + "y: " + y + "z: "+ z +"\t"+ etat + "\n");

                                qui te permet de vérifier si le code de natalya écrit bien les bonnes choses dans les registres (j'ai quand même aucun doute là dessus, mais si tu veux vérifier tu peux^^).

                                ta fonction affichagePixel est très longue en durée, ça peut expliquer les clignottements périodiques. (sauf la colonne x=3 et y=3)

                                -
                                Edité par remace 24 octobre 2013 à 14:50:34

                                • Partager sur Facebook
                                • Partager sur Twitter

                                oui. non. enfin je regarde et je te dis.

                                  24 octobre 2013 à 15:05:39

                                  remace a écrit:

                                  par contre, je vois un truc là dans ton programme, quand tu allume une led, tu ne l'éteins pas au "tour d'après", si?

                                  Physiquement, le système ne peux allumer qu'un étage à la fois (sauf si tu affiches la même chose sur plusieurs étages). Je désélectionne bien mon étage en fin d'itération, et à chaque itération de loop je réécris toutes les valeurs de l'étage à afficher.

                                  Par contre, j'ai oublié de déclarer x et y.

                                  Mon code ressemblerait plutôt à ça :

                                  int cube[4][4][4];
                                  int z=0;
                                  int loopCount=0;
                                  
                                  void loop()
                                  {
                                      int x, y;
                                      
                                      //On passe dans loop toutes les ms. Toutes les 1000 fois, donc toutes les secondes
                                      //On va appler une fonction qui change le motif affiché.
                                      if(loopCount==0)
                                          updateCube();
                                      loopCount= (loopCount+1)%1000;
                                      
                                      // A partir de là, c'est le code qui allume régulièrement les LEDs
                                      setRegisterPin(16 + z, HIGH); //le choix de la couche
                                      
                                      for(x=0;x<4;x++)
                                      {   
                                          for(y=0;y<4;y++)
                                          {   
                                              //allumer les leds qui doivent l'être à ce niveau
                                              setRegisterPin(x+y*4, cube[x][y][z]);
                                          }
                                      }
                                      
                                      writeRegisters(); //met à jour les registres à décalages
                                      setRegisterPin(16 + z, LOW); // on dé-sélectionne la couche
                                      
                                      z=(z+1)%4; //On passe à la couche suivante pour le prochain passage dans loop
                                      delay(1); //attendre 1 ms pour que les gens voient les LEDs allumées. Image 250Hz \o/
                                  }
                                  
                                  
                                  int currentLed = 0;
                                  void updateCube()
                                  {
                                      //Pour tester le cube, on va allumer les LED une par une et changer de LED toutes
                                      // les secondes
                                      
                                      //D'abord on efface tout le cube (c'est plus simple que d'éteindre les LEDs qu'on
                                      //a allumées avant.)
                                      clearCube(); 
                                      
                                      // On marque la LED qui nous intéresse pour être allumée
                                      cube[currentLed%4][(currentLed/4)%4][currentLed/16] = HIGH;
                                      
                                      // on passe à la prochaine LED pour quand cette fonction sera à nouveau appelée
                                      // c'est à dire à peu près 1s plus tard
                                      currentLed = (currentLed + 1)%64;
                                  }
                                  
                                  void clearCube()
                                  {   
                                      int i,j,k;
                                      for(i=0; i<4; i++)
                                          for(j=0; j<4; j++)
                                              for(k=0; k<4; k++)
                                                  cube[i][j][k]=LOW;
                                  }
                                  

                                  Du coup, Cactus, j'attends tes questions sur le code ci-dessus. Si tu n'as pas de question, je t'en poserai, ça te permettra de voir tout se qui se cache dans ce code.

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  64kB de mémoire, c'est tout ce dont j'ai besoin
                                    24 octobre 2013 à 15:16:46

                                    remace a écrit:

                                    pour vérifier que c'est bien un probleme de code, essaye d'éditer ton programme pour donner à chaque tour de boucle les indices et valeur de led dans ton IDE

                                    Son code est faux : les 0 en x et y qu'il passe en argument à affichagePixel sont écrasés dans la fonction et donc ignoré, seul le z est utilisé, et explique pourquoi l'étage 1 s'allume. Ensuite le cube physique s'allume en fonction des valeurs contenues dans la variable cube, qui ne sont pas initialisée. On aurait pu avoir un motif très différent avec le même code.

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    64kB de mémoire, c'est tout ce dont j'ai besoin
                                      24 octobre 2013 à 15:55:37

                                      oui non mais du coup ce que je voulais dire c'est que tu (par volonté s'entend) n'allume pas diode par diode, mais étage par étage, du coup ça fait consommer 16*plus de courant (320mA) dans son cas actuel, mais ça fait aussi 64 x plus (1.2A) dans le cas d'un 8x8x8 comme il exprime l'idée d'en faire un au début du topic.
                                      • Partager sur Facebook
                                      • Partager sur Twitter

                                      oui. non. enfin je regarde et je te dis.

                                        25 octobre 2013 à 0:19:12

                                        Bonjour,

                                        Bon pour moi fausse alerte, j'avais juste monté la LED à l'envers, du coup elles étaient à 1 pratiquement tout le temps... (trollolol...)

                                        Donc j'ai toujours mon problème :/

                                        Mon bout de code pour tester :

                                        const int pause = 10;
                                        unsigned int cpt = 0;
                                        
                                        void setup() {
                                          
                                          pinMode(9, OUTPUT);
                                          pinMode(10, OUTPUT);
                                          pinMode(11, OUTPUT);
                                          
                                        }
                                        
                                        void loop() {
                                         
                                            switch(cpt){
                                              case 0 :  analogWrite(9, 0);
                                                        analogWrite(10, 255);
                                                        analogWrite(11, 255);break;
                                                        
                                              case 1 :  analogWrite(9, 255);
                                                        analogWrite(10, 0);
                                                        analogWrite(11, 255);break;
                                                        
                                              case 2 :  analogWrite(9, 255);
                                                        analogWrite(10, 255);
                                                        analogWrite(11, 0);break;
                                                        
                                              default:  analogWrite(9, 255);
                                                        analogWrite(10, 255);
                                                        analogWrite(11, 255);
                                            }
                                          
                                            delayMicroseconds(pause); 
                                        
                                            if (++cpt >= 600){
                                              cpt = 0;
                                            }
                                        
                                        }

                                        200 LEDs RGB donc 600 LEDs. Je simule le multiplexage sur une seule LED RGB (à anode commune). Je perçois un léger clignotement (ce qui ne devrait pas).

                                        Le schéma elec est on ne peut plus simple, le +Vcc va sur l'anode, chaque cathode de LED va sur une résistance de 220 ohm qui va sur une sortie pwm.

                                        J'ai testé en diminuant le max du compteur, en jouant sur le delay, la luminosité est faiblarde. (plein pot ça éclaire du feu de dieu).

                                        Si quelqu'un a une idée ?

                                        Merci.

                                        PS : Je me rends compte que j’empiète sur le post d'un autre.

                                        -
                                        Edité par Julien Grall 25 octobre 2013 à 0:27:49

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          25 octobre 2013 à 2:07:56

                                          Je m'y perd. Tu peux ouvrir ton propre sujet pour qu'on ne mélange pas les deux problèmes ?

                                          Merci

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          64kB de mémoire, c'est tout ce dont j'ai besoin
                                            25 octobre 2013 à 16:13:19

                                            Natalya : J'ai tester ton code, il fonctionne , il affiche toutes les leds une par une convenablement !

                                            J'ai essayer de le décortiquer et de le comprendre mais quelques truc m’échappent encore, je n'arrive pas à visualisé clairement et précisément l'enchainement des actions.

                                            Déjà % c'est bien le modulo du C ? Il permet de donner le reste de la division c'est ça?

                                            Donc en appliquant cette opération j'ai essayer de remplacer les termes à certains endroit pour comprendre les résultats :

                                            loopCount= (loopCount+1)%1000; --> 1= (1+1) %1000 = 0

                                            cube [1%4] [(1/4)%4] [1/16] = cube [0] [0] [0.065] ? (Ce résultat me parait bien étrange)

                                            Si tu pouvais m'éclairer un peu la dessus :)

                                            Car du coup j'ai essayer ensuite de tester différentes valeurs dans les boucles x et y, pour pouvoir ensuite recrée la fameuse fonction affichagePixel(x,y,x) qui me permettrais de créer plus facilement les animations. Mais sans succès.

                                            Autre problème : Si je fais loopCount= (loopCount+1)%1; pour rafraichir plus rapidement et afficher donc la totalité des led, ça ne marche pas, on perçois seulement une diagonal du cube qui en plus scintille de façon très visible.

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              25 octobre 2013 à 16:52:31

                                              oui, % c'est modulo, soit le reste de la division euclidienne ENTIERE d'un entier par un entier:

                                              int dividende - (int résultat  * int diviseur) = int reste //qu'on appelle ici modulo

                                              ça permet de pas faire des tonnes de boucles pour rien. (la syntaxe, c'est a%b= reste de la division entière de a par b) 

                                              du coup dans ta compréhension du modulo il y a un problème: déjà, (1+1)%1000, ça fait 2%1000, ça fait 2, pas 0, ni 1 (j'aime pas quand on écrit 2 = sur la même ligne, ça ôte tout le sens de la ligne). 

                                              ensuite, sur le même principe, cube[1%4][1/4%4][1/16] donne cube[0][0][0]: les divisions (barre de fraction) sur un int donnent la partie entière du résultat, et le modulo donne le reste. donc pour prendre l'exemple concret de la 2e coordonnée, 1/4%4 ça fait pareil que 0%4, ça fait 0.

                                              du coup pour ta dernière question, (loopcount+1)%1 ça donne: reste de la division entière de loopcount+1 par 1. or quand tu divise un nombre par 1, le reste c'est 0. du coup ça fait update ton cube à chaque tour de la fonction loop, au lieu de faire 1000 tour entre chaque update.

                                              sinon... là ça marche, avec le code de natalya, pourquoi chercher à le modifier? tout ce que tu as à faire, c'est de changer les valeurs dans le tableau cube quand il y a besoin, le programme fait TOUT le reste.

                                              -
                                              Edité par remace 25 octobre 2013 à 17:02:42

                                              • Partager sur Facebook
                                              • Partager sur Twitter

                                              oui. non. enfin je regarde et je te dis.

                                                25 octobre 2013 à 17:15:16

                                                Merci pour tes précisions !

                                                Je ne vois pas comment et où tu peut changer les valeurs du tableau?

                                                Car exemple simple si je veux allumer tout le cube visuellement je doit faire tourner le code de Natalya assez vite pour l'illusion, sauf que j'ai jouer sur le modulo %1000 pour la vitesse, ou j'ai aussi jouer sur delay, également delayMicrosec et au final ça ne marche pas, scintillement visible.

                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  25 octobre 2013 à 17:37:03

                                                  pour sélectionner une led à afficher, ça se passe dans updateCube(); 

                                                  il y a 3 phases: la phase ou il vide le cube (ou le remplit de 0), la phase où il sélectionne les leds à allumer SUR TOUT LE CUBE, et la phase de sélection de l'image suivante

                                                  Natalya a écrit:

                                                  int currentLed = 0;
                                                  void updateCube()
                                                  {
                                                      //partie "vidange" du cube
                                                      clearCube(); 
                                                      
                                                      /* sélection des leds à allumer
                                                         ici il choisit une seule led 
                                                         en fonction de la valeur de currentLed*/
                                                      cube[currentLed%4][(currentLed/4)%4][currentLed/16] = HIGH;
                                                      
                                                      /*sélection de la prochaine frame 
                                                        qui dans ce cas précis passe par l'incrémentation de currentLed,
                                                        modulo 64, le nombre de leds du cube*/
                                                      currentLed = (currentLed + 1)%64;
                                                  }

                                                  -
                                                  Edité par remace 26 octobre 2013 à 0:08:06

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter

                                                  oui. non. enfin je regarde et je te dis.

                                                    25 octobre 2013 à 21:43:33

                                                    Je vais modifier un tout petit peu mon code, comme suit :

                                                    int cube[4][4][4];
                                                    int z=0;
                                                    int loopCount=0;
                                                    
                                                    void refreshLights()
                                                    {
                                                        int x, y;
                                                        
                                                        // A partir de là, c'est le code qui allume régulièrement les LEDs
                                                        setRegisterPin(16 + z, HIGH); //le choix de la couche
                                                        
                                                        for(x=0;x<4;x++)
                                                        {   
                                                            for(y=0;y<4;y++)
                                                            {   
                                                                //allumer les leds qui doivent l'être à ce niveau
                                                                setRegisterPin(x+y*4, cube[x][y][z]);
                                                            }
                                                        }
                                                        
                                                        writeRegisters(); //met à jour les registres à décalages
                                                        setRegisterPin(16 + z, LOW); // on dé-sélectionne la couche
                                                        
                                                        z=(z+1)%4; //On passe à la couche suivante pour le prochain passage dans loop
                                                    }
                                                    
                                                    
                                                    int currentLed = 0;
                                                    void updateCube()
                                                    {
                                                        //Pour tester le cube, on va allumer les LED une par une et changer de LED toutes
                                                        // les secondes
                                                        
                                                        //D'abord on efface tout le cube (c'est plus simple que d'éteindre les LEDs qu'on
                                                        //a allumées avant.)
                                                        clearCube(); 
                                                        
                                                        // On marque la LED qui nous intéresse pour être allumée
                                                        cube[currentLed%4][(currentLed/4)%4][currentLed/16] = HIGH;
                                                        
                                                        // on passe à la prochaine LED pour quand cette fonction sera à nouveau appelée
                                                        // c'est à dire à peu près 1s plus tard
                                                        currentLed = (currentLed + 1)%64;
                                                    }
                                                    
                                                    void clearCube()
                                                    {   
                                                        int i,j,k;
                                                        for(i=0; i<4; i++)
                                                            for(j=0; j<4; j++)
                                                                for(k=0; k<4; k++)
                                                                    cube[i][j][k]=LOW;
                                                    }
                                                    
                                                    void loop()
                                                    {
                                                        //On passe dans loop toutes les ms. Toutes les 1000 fois, donc toutes les secondes
                                                        //On va appler une fonction qui change le motif affiché.
                                                        if(loopCount==0)
                                                            updateCube();
                                                        loopCount= (loopCount+1)%1000;
                                                    
                                                        refreshLights();    
                                                        delay(1); //attendre 1 ms pour que les gens voient les LEDs allumées. Image 250Hz \o/
                                                    }
                                                    

                                                    Voilà, comme ça, j'ai le moins de choses possibles dans loop. Comment fonctionne ce code ? l'idée de ce code, c'est que le microcontrôleur est très rapide, et donc que le temps d'exécution des instructions est négligeable.

                                                    Du coup, dans loop, j'ai du code qui ne prend pas de temps, et un delay(1). Ma boucle va donc être appelée toutes les 1ms. Ca va me servir de base de temps. Une fois que j'ai choisi cette base de temps, je vais éviter de la changer, parce que ça a de l'influence sur toutes ce que je fais dans loop. Pourquoi ai-je choisi 1ms ? Il me faut un temps assez long pour pouvoir considérer que le reste du code s'exécute instantanément, et assez court pour que je puisse agir aussi souvent que je le veux. En plus, si c'est rond, c'est mieux : si j'avais choisi 7ms, je n'aurais pu agir que toutes les 7ms, ou toutes les 14, ou 21, ... C'est pas pratique.

                                                    Bon, du coup, qu'est ce que je fais dans loop ?

                                                    • On travaille sur un cube lumineux, le but c'est donc d'allumer le cube. On sait qu'on ne peut allumer qu'un étage à la fois, et qu'il faut changer d'étage assez souvent pour que l'œil humain ait l'impression que tous les étages sont allumés en continu. On peut le faire toutes les ms. On va le faire à chaque passage dans loop, c'est ce que fais ma fonction refreshLights ci-dessus.

                                                    • On voudrait bien changer le motif affiché par le cube. Par contre, ça, on ne va pas le faire aussi souvent, parce que sinon l'œil n'aura pas le temps de le voir. J'ai choisi de changer toutes les secondes, donc toutes les 1000 ms (toutes les 1000 loop). C'est à ça que sert le 1000 dans

                                                      loopCount= (loopCount+1)%1000;
                                                      Il faut lire ce code comme loopCount va maintenant valoir la valeur qu'il avait +1, et si ça fait 1000, à la place, loopCount repasse à 0. La ligne juste au dessus n'est executée que si loopCount vaut 0, donc une fois sur 1000, donc une fois toutes les 1000 ms.
                                                      Si tu veux changer ton cube plus ou moins souvent, c'est ce 1000 qu'il va falloir changer : c'est le nombre de passage dans la boucle où on ne change rien.
                                                      Et pour ma mise à jour du cube, j'efface tout mon cube (en fait j'efface le tableau dans la mémoire, mais c'est ce tableau qui sert à choisir quelles LED on allume dans refreshLights), et j'y écris mon nouveau dessin. Bon, la ligne du milieu est vraiment bizarre. J'y reviens en dernier. Je voulais éclairer les LED une par une, il me fallait donc une variable qui compte de 0 à 63 (il y a 64 LED), en augmentant de 1 à chaque passage dans la fonction. C'est ce que je fais avec currentLed = (currentLed + 1)%64;.

                                                    Il reste la dernière ligne

                                                    cube[currentLed%4][(currentLed/4)%4][currentLed/16] = HIGH;
                                                    C'est pas facile à voir avec un cube de 4x4x4. Imaginons que le cube fasse 10x10x10. Ca fait 1000 LED. En comptant de 0 à 999, je compte le nombre de LED. Pour savoir de quelle LED je parle, je vais utiliser le code suivant :
                                                    • le premier chiffre sera le z
                                                    • le second chiffre sera le y
                                                    • le troisième chiffre sera le x
                                                      Par exemple, pour la LED 537, on a x=7, y=3, z=5. Comment je récupère mes chiffres ? On est en division entière, donc le premier c'est facile
                                                      537/100=5 donc z=(numéro de la LED)/100
                                                      Le % permet de récupérer le reste de la division entière.
                                                      537/10=53, donc 537%10=7, donc x=(numéro de la LED)%10
                                                      Pour le y, on mélange les deux. On commence par virer le 7
                                                      537/10=53
                                                      et ensuite on garde le 3
                                                      53%10=3, donc y=(numéro de la LED/10)%10.
                                                      En remettant ça dans les indices du tableau, ça donne
                                                      cube[currentLed%10][(currentLed/10)%10][currentLed/100] = HIGH;

                                                      Après, comme notre cube ne fait pas 10 de côté mais 4, il suffit de remplacer 10 par 4. 100 c'est 10x10, donc on le remplace par 4x4=16

                                                    -
                                                    Edité par Natalya 25 octobre 2013 à 21:45:21

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                    64kB de mémoire, c'est tout ce dont j'ai besoin
                                                      28 octobre 2013 à 11:36:31

                                                      Merci beaucoup pour tes explications ! Même si celà reste encore un peu flou forcément par le manque d'expérience et le fait que je suis pas l'auteur du code, j'ai pas répondus tout de suite car j'ai préféré prendre un peu le temps d'étudier jours après jours faire quelques test, laisser murir le truc on va dire.

                                                      J'ai donc réussis en modifiant un peu de façon empirique le code pour obtenir un rafraichissement non visible en allumant tout un étage d'un coup successivement de façon à obtenir un cube entier. 

                                                      Cependant quand il s'agit de mettre en place par exemple de animations différentes qui s'enchaine à la suites avec un délais d'animation changeable comme dans mon code du début avec un nombre de cycles intégré à la fonction et ben je bloque total.

                                                      Voici le code actuel, qui décrit le cube entier dont je parle au début :

                                                      int currentLed = 0;
                                                      void updateCube()
                                                      {
                                                          //partie "vidange" du cube
                                                          clearCube();
                                                           
                                                          /* sélection des leds à allumer
                                                             ici il choisit une seule led
                                                             en fonction de la valeur de currentLed*/
                                                      
                                                                 for(int y=0; y<4; y++)
                                                                  {
                                                                  for(int x=0; x<4; x++)
                                                                    {
                                                                        cube[x][y][currentLed/8] = HIGH;
                                                                        
                                                                    }
                                                                  }
                                                              
                                                         
                                                           
                                                          /*sélection de la prochaine frame
                                                            qui dans ce cas précis passe par l'incrémentation de currentLed,
                                                            modulo 64, le nombre de leds du cube*/
                                                          currentLed = (currentLed + 1)%32;
                                                      }
                                                       
                                                      void clearCube()
                                                      {  
                                                          int i,j,k;
                                                          for(i=0; i<4; i++)
                                                              for(j=0; j<4; j++)
                                                                  for(k=0; k<4; k++)
                                                                      cube[i][j][k]=LOW;
                                                      }
                                                       
                                                      void loop()
                                                      {   
                                                       
                                                          //On passe dans loop toutes les ms. Toutes les 1000 fois, donc toutes les secondes
                                                          //On va appler une fonction qui change le motif affiché.
                                                          if(loopCount==0)
                                                              updateCube();
                                                          loopCount= (loopCount+1)%1;
                                                       
                                                          refreshLights();   
                                                          delayMicroseconds(1); //attendre 1 ms pour que les gens voient les LEDs allumées. Image 250Hz \o/
                                                          
                                                         
                                                      
                                                      }



                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        28 octobre 2013 à 13:10:40

                                                        bon ben on va reprendre: currentLed c'est un sélecteur d'image, donc ce que tu peux faire c'est changer son modulo par ton nombre d'images (cube entiers). on va prendre comme exemple le fait d'afficher 1 plan horizontal à la fois en boucle, avec un intervalle de 0.5s pour qu'on ait le temps de voir mais que ça soit pas trop lent. 

                                                        natalya t'a expliqué qu'un tour de boucle loop() dure "grossomodo 1ms" (tout est négligeable devant la temporisation pour fixer l'affichage) donc elle a rajouté une variable pour mettre à jour l'affichage moins souvent, en enlevant le scintillement dû au temps de mise à jour du cube. pour que ça soit visible par l'oeil, etc... il faut 500ms pour faire la temporisation qu'on veut, donc loopcount va être incrémenté "modulo 500":

                                                        loopCount= (loopCount+1)%500;

                                                        ensuite, il nous faut une fonction qui allume un plan:

                                                        void plan_horizontal(int etage){
                                                            int i,j=0;
                                                            for(i=0, i<4,i++){
                                                                for(j=0,j<4,j++){
                                                                    cube[i][j][etage] = HIGH;
                                                                }
                                                            }
                                                        }

                                                        maintenant, on compte combien on a d'images différentes à afficher. 4 plans horizontaux sur le cube, donc 4 images. donc on incrémente currentLed modulo 4 à la fin de la fonction updateCube:

                                                        currentLed = (currentLed + 1)%4;

                                                        du coup on obtient ça:

                                                        int cube[4][4][4];
                                                        int z=0;
                                                        int loopCount=0;
                                                         
                                                        void refreshLights()
                                                        {
                                                            int x, y;
                                                             
                                                            // A partir de là, c'est le code qui allume régulièrement les LEDs
                                                            setRegisterPin(16 + z, HIGH); //le choix de la couche
                                                             
                                                            for(x=0;x<4;x++)
                                                            {  
                                                                for(y=0;y<4;y++)
                                                                {  
                                                                    //allumer les leds qui doivent l'être à ce niveau
                                                                    setRegisterPin(x+y*4, cube[x][y][z]);
                                                                }
                                                            }
                                                             
                                                            writeRegisters(); //met à jour les registres à décalages
                                                            setRegisterPin(16 + z, LOW); // on dé-sélectionne la couche
                                                             
                                                            z=(z+1)%4; //On passe à la couche suivante pour le prochain passage dans loop
                                                        }
                                                         
                                                         
                                                        int currentFrame = 0;
                                                        void updateCube()
                                                        {
                                                            //Pour tester le cube, on va allumer les LED une par une et changer de LED toutes
                                                            // les secondes
                                                             
                                                            //D'abord on efface tout le cube (c'est plus simple que d'éteindre les LEDs qu'on
                                                            //a allumées avant.)
                                                            clearCube();
                                                             
                                                            // On marque les leds qui nous intéresse pour être allumées dans l'image en cours.
                                                            plan_horizontal(currentFrame);
                                                             
                                                            // on passe au prochain plan pour quand cette fonction sera à nouveau appelée
                                                            // c'est à dire à peu près 1s plus tard. on pourrait le faire en début de fonction
                                                            currentFrame = (currentFrame + 1)%4;
                                                        }
                                                         
                                                        void clearCube()
                                                        {  
                                                            int i,j,k;
                                                            for(i=0; i<4; i++)
                                                                for(j=0; j<4; j++)
                                                                    for(k=0; k<4; k++)
                                                                        cube[i][j][k]=LOW;
                                                        }
                                                         
                                                        void loop()
                                                        {
                                                            //On passe dans loop toutes les ms. Toutes les 500 fois, donc toutes les 500 millisecondes
                                                            //On va appeler une fonction qui change le motif affiché.
                                                            if(loopCount==0)
                                                                updateCube();
                                                            loopCount= (loopCount+1)%500; //%500 pour donner 500ms entre 2 changement d'image
                                                         
                                                            refreshLights();   
                                                            delay(1); //attendre 1 ms pour que les gens voient les LEDs allumées. Image 250Hz \o/
                                                        }
                                                        
                                                        void plan_horizontal(int etage){
                                                            int i,j=0;
                                                            for(i=0, i<4,i++){
                                                                for(j=0,j<4,j++){
                                                                    cube[i][j][etage] = HIGH;
                                                        } } }

                                                        -
                                                        Edité par remace 28 octobre 2013 à 13:27:45

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter

                                                        oui. non. enfin je regarde et je te dis.

                                                          28 octobre 2013 à 13:29:02

                                                          bon ben on va prendre un exemple simple, et le décomposer pour que tu comprenne comment te servir de ce que t'a donné Natalya. on va prendre comme exemple le fait d'afficher 1 plan horizontal à la fois en boucle, avec un intervalle de 0.5s pour qu'on ait le temps de voir mais que ça soit pas trop lent. 

                                                          natalya t'a expliqué qu'un tour de boucle loop() dure "grossomodo 1ms" (tout est négligeable devant la temporisation pour fixer l'affichage) donc elle a rajouté une variable pour mettre à jour l'affichage moins souvent, (dans son exemple à elle, une fois toutes les secondes) ce qui a pour unique but d'enlever le scintillement dû au temps de mise à jour du cube.

                                                          pour notre exemple, il faut 500ms pour faire la temporisation qu'on veut, donc loopcount va être incrémenté "modulo 500":

                                                          loopCount= (loopCount+1)%500;

                                                          ensuite, il nous faut une fonction qui allume un plan horizontal (bon je te fais pas l'affront de t'expliquer comment elle marche...):

                                                          void plan_horizontal(int etage){
                                                              int i,j=0;
                                                              for(i=0, i<4,i++){
                                                                  for(j=0,j<4,j++){
                                                                      cube[i][j][etage] = HIGH;
                                                                  }
                                                              }
                                                          }

                                                          maintenant, on compte combien on a d'images différentes à afficher. 4 plans horizontaux sur le cube, donc 4 images: les images 0,1,2, et 3.

                                                          pourquoi incrémenter "au modulo"? quand currentFrame vaut 4, le modulo vaut 0, pour 5 c'est 1, pour 6 c'est 2, pour 7 c'est 3, etc, juqu'à la valeur maximale pour un int.

                                                          pour avoir une boucle 0,1,2,3 sur les images sans avoir à faire des tests sur la valeur de currentFrame, on incrémente currentFrame modulo 4 à la fin de la fonction updateCube:

                                                          currentLed = (currentLed + 1)%4;

                                                          -
                                                          Edité par remace 28 octobre 2013 à 13:40:53

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter

                                                          oui. non. enfin je regarde et je te dis.

                                                            28 octobre 2013 à 13:42:20

                                                            du coup on obtient ça:

                                                            int cube[4][4][4];
                                                            int z=0;
                                                            int loopCount=0;
                                                             
                                                            void refreshLights()
                                                            {
                                                                int x, y;
                                                                 
                                                                // A partir de là, c'est le code qui allume régulièrement les LEDs
                                                                setRegisterPin(16 + z, HIGH); //le choix de la couche
                                                                 
                                                                for(x=0;x<4;x++)
                                                                {  
                                                                    for(y=0;y<4;y++)
                                                                    {  
                                                                        //allumer les leds qui doivent l'être à ce niveau
                                                                        setRegisterPin(x+y*4, cube[x][y][z]);
                                                                    }
                                                                }
                                                                 
                                                                writeRegisters(); //met à jour les registres à décalages
                                                                setRegisterPin(16 + z, LOW); // on dé-sélectionne la couche
                                                                 
                                                                z=(z+1)%4; //On passe à la couche suivante pour le prochain passage dans loop
                                                            }
                                                             
                                                             
                                                            int currentFrame = 0;
                                                            void updateCube()
                                                            {
                                                                //Pour tester le cube, on va allumer les LED une par une et changer de LED toutes
                                                                // les secondes
                                                                 
                                                                //D'abord on efface tout le cube (c'est plus simple que d'éteindre les LEDs qu'on
                                                                //a allumées avant.)
                                                                clearCube();
                                                                 
                                                                // On marque les leds qui nous intéresse pour être allumées dans l'image en cours.
                                                                plan_horizontal(currentFrame);
                                                                 
                                                                // on passe au prochain plan pour quand cette fonction sera à nouveau appelée
                                                                // c'est à dire à peu près 1s plus tard. on pourrait le faire en début de fonction.
                                                                currentFrame = (currentFrame + 1)%4;
                                                            }
                                                             
                                                            void clearCube()
                                                            {  
                                                                int i,j,k;
                                                                for(i=0; i<4; i++)
                                                                    for(j=0; j<4; j++)
                                                                        for(k=0; k<4; k++)
                                                                            cube[i][j][k]=LOW;
                                                            }
                                                             
                                                            void loop()
                                                            {
                                                                //On passe dans loop toutes les ms. Toutes les 500 fois, donc toutes les 500 millisecondes
                                                                //On va appeler une fonction qui change le motif affiché.
                                                                if(loopCount==0)
                                                                    updateCube();
                                                                loopCount= (loopCount+1)%500; //%500 pour donner 500ms entre 2 changement d'image
                                                             
                                                                refreshLights();   
                                                                delay(1); //attendre 1 ms pour que les gens voient les LEDs allumées. Image 250Hz \o/
                                                            }
                                                            
                                                            void plan_horizontal(int etage){
                                                                int i,j=0;
                                                                for(i=0, i<4,i++){
                                                                    for(j=0,j<4,j++){
                                                                        cube[i][j][etage] = HIGH;
                                                                    }
                                                                }
                                                            }

                                                            EDIT: apparemment il y a une limite pour la taille des réponses (ce qui parait logique) du coup j'ai été obligé de faire un double-post

                                                            -
                                                            Edité par remace 28 octobre 2013 à 13:47:14

                                                            • Partager sur Facebook
                                                            • Partager sur Twitter

                                                            oui. non. enfin je regarde et je te dis.

                                                            74HC595 - Perte de luminositée des leds

                                                            × 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