Partage
  • Partager sur Facebook
  • Partager sur Twitter

Arduino incompréhension....

    15 mars 2014 à 22:17:43

    Bonsoir,

    j'ai créé un petit script/montage permettant de lire 8 bits, de convertir l'octet en binaire et d'afficher le nombre sur 3 afficheurs 7 seg multiplexés.
    voici le code :

    void setup()
    {
     
      pinMode(12,INPUT);
      pinMode(1,OUTPUT);
      pinMode(2,OUTPUT);
      pinMode(3,OUTPUT);
      pinMode(4,OUTPUT);
      pinMode(5,OUTPUT);
      pinMode(6,OUTPUT);
      pinMode(7,OUTPUT);
      pinMode(8,OUTPUT);
      pinMode(9,OUTPUT);
      pinMode(10,OUTPUT);
      int i=0;
      
      
    }
    int val[8];
    int cur;
    int comb[3][10][10] =
    {{{0,1,1,1,1,1,1,1,0,0},{0,0,0,1,0,0,1,1,0,0},{1,0,1,1,1,1,0,1,0,0},{1,0,1,1,0,1,1,1,0,0},{1,1,0,1,0,0,1,1,0,0},
    {1,1,1,0,0,1,1,1,0,0},{1,1,1,0,1,1,1,1,0,0},{0,0,1,1,0,0,1,1,0,0},{1,1,1,1,1,1,1,1,0,0},{1,1,1,1,0,1,1,1,0,0}},
    {{0,1,1,1,1,1,1,0,1,0},{0,0,0,1,0,0,1,0,1,0},{1,0,1,1,1,1,0,0,1,0},{1,0,1,1,0,1,1,0,1,0},{1,1,0,1,0,0,1,0,1,0},
    {1,1,1,0,0,1,1,0,1,0},{1,1,1,0,1,1,1,0,1,0},{0,0,1,1,0,0,1,0,1,0},{1,1,1,1,1,1,1,0,1,0},{1,1,1,1,0,1,1,0,1,0}},
    {{0,1,1,1,1,1,1,0,0,1},{0,0,0,1,0,0,1,0,0,1},{1,0,1,1,1,1,0,0,0,1},{1,0,1,1,0,1,1,0,0,1},{1,1,0,1,0,0,1,0,0,1},
    {1,1,1,0,0,1,1,0,0,1},{1,1,1,0,1,1,1,0,0,1},{0,0,1,1,0,0,1,0,0,1},{1,1,1,1,1,1,1,0,0,1},{1,1,1,1,0,1,1,0,0,1}}};
    
    void aff(int d)
    {
        int c = (d%10);
        int b = ((d/10)%10);
        int a = ((d/100)%10);
        for(int i=1;i<=10;i++)
        {
          digitalWrite(i,comb[0][a][i-1]);
        }
        delay(10);
        for(int i=1;i<=10;i++)
        {
          digitalWrite(i,comb[1][b][i-1]);
        }
        delay(10);
        for(int i=1;i<=10;i++)
        {
          digitalWrite(i,comb[2][c][i-1]);
        }
        delay(10);
        for(int i=1;i<=10;i++)
        {
          digitalWrite(i,0);
        }
        
    }
    void loop()
    {
      int num=0;
      for(int j=0;j<=7;j++)
      {
        cur=digitalRead(12);
        num=num+cur*pow(2,j);
        delay(20);
      }
    
    
      for(int f=0;f<=70;f++)
      {aff(num);
      }
    }

     Tout marche très bien, sauf que lorsque tous les bits sont à 1, cela m'affiche 249 et pas 255 !
    Apparemment le probleme vient de la boucle

      for(int j=0;j<=7;j++)

      {

        cur=digitalRead(12);

        num=num+cur*pow(2,j);

        delay(20);

      } 
    Qui devrait nous donner si le pin 12 est toujours haut, 0+2^0+2^1+2^2+2^3+2^4+2^5+2^6+2^7 = 255
    or ce n'est pas le cas, pouvez vous m'indiquer mon erreur ? merci ! 

    • Partager sur Facebook
    • Partager sur Twitter
      15 mars 2014 à 22:29:06

      J'ai trouvé le probleme, aussi étrange soit-il, il s'agit de la fonction pow...

      J'ai recodé ca de manière assez moche pour le test, mais ca marche int puiss(int v)

      {

        int p=1;

        for(int u=1;u<=v;u++)

        {

          p=2*p;

        }

        return p;

      }

      Si vous avez des explications j'écoute !

      • Partager sur Facebook
      • Partager sur Twitter
        16 mars 2014 à 10:01:48

        La fonction pow travaille sur des float ...

        En plus d'etre excessivement lent, le résultat n'est pas très précis.

        Bref, ce n'est absolument pas adapté à ton besoin.

        Pour faire une puissance de 2, utilise le décalage binaire, c'est 1000 fois plus rapide et d'une précision absolue.

        pow(2, x) revient à écrire ( 1 << x )

        =====

        Ensuite, je voudrais te faire remarquer que ton code n'est pas du tout optimisé !

        Surtout en ce qui concerne la RAM.

        En effet, un int, c'est 2 octets donc ton tableau en bouffe 3*10*10 = 300 !

        Pourquoi mettre tes 10 combinaisons de 1/0 à part alors que tu peux les regrouper en un seul short (2 ocets).

        Dans ce cas, ton tableau n'occuperait que 3*10 = 30 octets (10 fois moins).

        =====

        La fonction digitalwrite est aussi SUPER lente ! (pas optimisée du tout)

        Et tu dois la faire 10 fois pour afficher le bon digit...

        Je t'encourage vivement à lire ce lien : http://arduino.cc/en/Reference/PortManipulation#.UyVj64WwSik

        Comme tu peux le voir, en utilisant PORTB, PORTC, PORTD, tu peux affecter 8 pins en même temps en une seule instruction !

        =====

        L'idée serait de combiner les 2 propositions du haut en une seule : tu t'arranges pour que tes tableaux contiennent directement les valeurs à écrire et tout devient ultra rapide sans consommer de RAM.

        =====

        Exemple :

        /*
            RAPPEL :
            port D : D digital pins 0 to 7
            port B : digital pin 8 to 13
        */
        
        // Data pour le port B
        unisgned char portDataB[3][10] = { ... };
        
        // Data pour le port D
        unisgned char portDataD[3][10] = { ... };
        
        // Mask pour le port B
        unsigned char portMaskB = 0x11111110;
        
        // Mask pour le port D
        unsigned char portMaskD = 0x00010111;
        
        void setup() {
            DDRB |= portMaskB; // Passe automatiquement les pin 0-7 voulue en OUTPUT
            DDRD |= portMaskD; // Passe automatiquement les pin 8-13 voulue en OUTPUT
        }
        
        void loop() {
            portB = ( ( portB & ( ~portMaskB ) ) | portDataB[x][y] ); // Affecte la valeur voulue sur les pin 0-7 voulue
            portD = ( ( portD & ( ~portMaskD ) ) | portDataD[x][y] ); // Affecte la valeur voulue sur les pin 8-13 voulue
        }

        Pour tester, je t'invites à mettre des valeurs bidon dans tes tableau et de voir ce que ça donne ;)

        Note : en mettant 255 partout, tu auras toutes les pin sur HIGH.

        =====

        Si tu ne comprends pas mon code, je t'invite à lire le tutoriel des opérateurs bit à bit (qui doit se trouver dans l'un des cours du langage C).

        -
        Edité par lorrio 16 mars 2014 à 10:05:04

        • Partager sur Facebook
        • Partager sur Twitter
          16 mars 2014 à 10:25:04

          Merci pour les infos !
          j'ai en effet lu que la fonction pow utilisait une approximation avec ln et e... Avec bit(x) ca marche super bien aussi ;)

          J'ai conscience que mon code était absolument sale, mais c'était juste pour une application rapide de test. Mais je vais essayer de l'optimiser comme tu me le conseille, je vais essayer de poster ca d'ici ce soir.
          Et de plus le code était fait pour être facilement explicable et rapide à comprendre/modifier pour des débutants, donc avec des PORT ca va être un peu plus compliqué à gérer.

          • Partager sur Facebook
          • Partager sur Twitter
            16 mars 2014 à 10:57:05

            Là, il n'y a que toi qui peut choisir l'architecture à adapter.

            Si tu n'as pas besoin que ce soit rapide et que la RAM n'est pas un problème, alors tu peux garder ta solution.

            • Partager sur Facebook
            • Partager sur Twitter

            Arduino incompréhension....

            × 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