Partage
  • Partager sur Facebook
  • Partager sur Twitter

Manipulation des ports Arduino

Sujet résolu
    16 septembre 2018 à 12:44:07

    Bonjour,

    Je me suis intéresé à la manipulation des ports de mon Arduino pour gagner du temps et j'ai rencontre un probleme.

    En fait, avec le code ci-dessous j'ai 2 leds commande avec un poussoir en fonction du niveau logique. Une led est allume à l'état bas et l'autre eteint et inversement...du basique. Avec ce code tout fonctionne comme prevu, mais lorsque je supprime la ligne 10, le programme execute le code dans le bloc elese :colere:et mon bouton n'est pas appuié. Et biensur lorsque j'appui il ne fait rien.. J'ai ajouté un delay à la place de serial mais rien ne fonctionne. Si quelq'un pourrais m'éclairer sur ce sujet ca serait sympa.

    void setup()
    {
      Serial.begin(9600);
      DDRD = 0b01010010;
      PORTD |= 0b01010010;
    }
    
    void loop()
    {  
       Serial.println("DEBUT"); 
       boolean bouton = PIND & 0b00000110; // je lis l'etat du pin 2
    
       if (bouton == 0)
            PORTD = 0b00010010;
       else
            PORTD = 0b01000010;
     }
    
    



    -
    Edité par CiprianMalaes 16 septembre 2018 à 12:45:28

    • Partager sur Facebook
    • Partager sur Twitter
    La vie, c'est comme une une bicyclette, il faut avancer pour ne pas perdre l'équilibre.
      17 septembre 2018 à 0:22:00

      Bonjour,

      Si tu utilises simultanément des sorties, des entrées et le port série qui sont sur PORTD, tu dois utiliser les opérateurs binaires partout pour éviter de toucher aux 2 premiers bits du port série et au bit 2 de l'entrée quand tu écris sur les 2 sorties (de plus, ligne 11, tu lisais 2 bits donc 2 broches au lieu d'une seule):

      void setup()
      {
        Serial.begin(9600);
        DDRD | = 0b01010000;
        PORTD |= 0b01010000;
      }
       
      void loop()
      { 
         Serial.println("DEBUT");
         boolean bouton = PIND & 0b00000100; // je lis l'etat du pin 2
       
         if (bouton == 0)
              PORTD = (PORTD & ~0b01000000) | 0b00010000;
         else
              PORTD = (PORTD & ~0b00010000) | 0b01000000;
       }

      Ces lignes 14 et 16 prennent plus de cycles, puisqu'il faut lire le port dans un registre faire un AND puis un OR puis réécrire le registre dans le port, donc 4 instructions au lieu d'une seule, ce qui est un peu moins intéressant que si tu avais tout le port disponible avec toutes les broches configurées en sorties.

      Si l'état du bouton semble incohérent, peut-être que tu n'as pas mis de résistance de pull-up ou pull-down sur la broche 2 (tuto correspondant), et les variations de tension de la broche adjacente suffisent à influencer l'état de la broche quand le bouton n'est pas appuyé. Tu peux également contrôler la résistance de pull-up interne des entrées en mettant le bit correspondant de PORTD à 1.

      • Partager sur Facebook
      • Partager sur Twitter
        17 septembre 2018 à 14:03:04

        En mettant DDRD = 0b01010010;, tu déclares :

        • pin 0: 0b01010010 = INPUT
        • pin 1: 0b01010010 = OUTPUT
        • pin 2: 0b01010010 = INPUT
        • pin 3: 0b01010010 = INPUT
        • pin 4: 0b01010010 = OUTPUT
        • pin 5: 0b01010010 = INPUT
        • pin 6: 0b01010010 = OUTPUT
        • pin 7: 0b01010010 = INPUT

        Est-ce voulu d'avoir la pin 1 ou OUTPUT ?

        Vu que c'est la pin TX, je suppose que oui mais je pose la question quand même, on ne sait jamais.

        ***

        Avec cette ligne boolean bouton = PIND & 0b00000110;, tu viens lire les pins 1 et 2 et non uniquement la pin 2.

        Dès que l'une des 2 pins sera à HIGH, ta variable bouton vaudra 1.

        Vu que la pin 1 correspond à la pin TX du Serial, elle change d'état sans cesse quand le Serial envoie des données, ce qui expliques certainement le comportement que tu observes.

        ***

        Au passage, j'en profite pour dire que PORTD contrôle l'état logique de sortie en mode OUTPUT mais aussi la présence de la pull-up en mode INPUT donc attention à ce que tu fais avec.

        Comme l'a souligné alexisdm, tu devrais utiliser les opérateurs binaires pour ne pas tout modifier.

        Tu peux aussi utiliser une notion simplifiée :

        // force les bits 1 et 2 à '0'.
        PORTD &= ~0b00000110;
        // => PORTD devient : 0b.....00.
        // force les bits 1 et 2 à '1'.
        PORTD |= 0b00000110;
        // => PORTD devient : 0b.....11.




        • Partager sur Facebook
        • Partager sur Twitter
          17 septembre 2018 à 14:17:49

          Je connais bien la problematique du pin TX et dans mon example il est à 1 car il doit rester toujours à 1. je n'utilise pas ce pin. Apres je sais qu'il faut utiliser les operrations binaires pour ne pas changer l'état des autres pins mas j'ai voulu tester rapidement mon code voir si ca marche.. ce pour cet raison que je n'ai pas utilisé les operations sur les bits. Etant

          donnée que vous avez des bonnes connaissances du IDE Arduino peut etre que vous pouves m'expliquer le fait que si je supprime la ligne 10 Arduino execute le code dans le bloc else toujours et il ne réagit pas à l'appui du bouton. Ou est la logique??

          • Partager sur Facebook
          • Partager sur Twitter
          La vie, c'est comme une une bicyclette, il faut avancer pour ne pas perdre l'équilibre.
            17 septembre 2018 à 18:15:37

            Tu as une explication dans mon message précédent ;)

            lorrio a écrit:

            Avec cette ligne boolean bouton = PIND & 0b00000110;, tu viens lire les pins 1 et 2 et non uniquement la pin 2.

            Dès que l'une des 2 pins sera à HIGH, ta variable bouton vaudra 1.

            Vu que la pin 1 correspond à la pin TX du Serial, elle change d'état sans cesse quand le Serial envoie des données, ce qui expliques certainement le comportement que tu observes.

            Pour être plus précis, voici ce qu'il se passe exactement :

            Quand le Serial n'émet rien (ce qui est le cas en commentant la ligne 10), l'état de la pin TX est à HIGH (c'est c'est principe d'une liaison série TLL, quand on n'émet pas, l'état logique est '1'), donc ta variable bouton vaut toujours 1 et ton code exécute toujours le else.

            Maintenant, quand ton Serial émet des données (ce qui est le cas avec la ligne 10), l'état de la pin TX change constamment d'état entre HIGH et LOW.

            Quand le TX émet un bit HIGH, alors on est dans le même cas que précédant, ta variable bouton vaut 1 peu importe l'état du bouton et ton code exécute toujours le else.

            Quand le TX émetun bit LOW, alors l'état du TX l'influence pas ta variable bouton et donc ton code de bouton est fonctionnel.

            Au final, vu que le TX émet des successions de HIGH et LOW, ton code alterne entre "toujours else" et "if/else suivant bouton", ce qui te donne l'impression que ça marche alors que ce n'est pas vraiment le cas.

            La solution serait donc d'éditer la ligne 11 pour mettre 0b00000100 à la place de 0b00000110 afin de prendre en compte uniquement l'état de la pin 2 et non un mixte entre la pin 2 et la pin TX.

            -
            Edité par lorrio 17 septembre 2018 à 18:16:36

            • Partager sur Facebook
            • Partager sur Twitter
              18 septembre 2018 à 14:47:43

              Merci à tous les deux pour vos explications precises, notamment à lorrio,  et je m'excuse car je n'ai pas bien lu ton precedent message :D Effectivement, tu as bien explique le fonctionnement  du RX TX. J'ai teste mon nouveau code avec les operateurs binaires et ca marche super bien car le bloc s'execute en meme pas 4 us tandis que avec digitalWrite il faut 12 us. La manipulation des ports est super rapide.

              Merci.:)

              -
              Edité par CiprianMalaes 18 septembre 2018 à 15:02:46

              • Partager sur Facebook
              • Partager sur Twitter
              La vie, c'est comme une une bicyclette, il faut avancer pour ne pas perdre l'équilibre.

              Manipulation des ports Arduino

              × 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