Répondre à la discussion
Affichage des résultats 1 à 24 sur 24

Programmation d'un anti-rebond



  1. #1
    bigbrownies

    Post Programmation d'un anti-rebond

    Bonjour,

    Je me retrouve actuellement face à un problème.
    Voyez vous, je commande les menus de mon afficheur LCD avec un BP connecté à un microprocesseur ATMEGA328p
    Je le programme sous Arduino 1.0.5.

    Le problème, c'est les rebonds à l'appuie et au relâchement du BP.
    Tout d'abord mon BP est un NF. il est branché avec une résistance PULL-DOWN. Voici un petit schéma explicatif :
    Sans titre 1.jpg

    Umes1 est la tension que j'aimerais envoyer dans le µC.
    Umes2 représente la solution Hardware que sans doute des gens m'auraient proposé. Mais vu que je vais pas m'amuser a acheter 1 résistance de 100k et 1 condensateur de 100nF, je refuse cette solution.

    Passons coté Software. Utilisant Arduino j'ai donc essayé plusieurs solutions.
    Les interruptions du µC, mais je ne m'en sort pas avec l'anti rebond & l'interruption. logiciellement, pour supprimer un rebond, il faut juste retarder la prise en compte du signal d'une centaine ou deux de ms. Mes tentatives d'utilisation de temporisation dans mes interruptions sont des échecs.
    - Delayms() ne fonctionne pas (normal)
    - j'ai fais une tempo avec millis() mais ca n'a pas fonctionné.
    - j'ai essayé d'utiliser une combinaison de attachInterrupt(...) et detachInterrupt(...) mais même après un detachInterrupt(...) le µC garde en mémoire un rebond et relance une interruption après le attachInterrupt(...). Il y a une histoire de "FLAG" et d'aller bidouiller dans les registre mais je n'ai pas réellement compris.

    Je suis aller chercher une bibliothèque "Bounce" mais cela ne me plait pas puisque ça ne passe pas par une interruption. du coup l'appuie du bouton n'est pas réactif.

    Si vous pouviez m'aider à résoudre ce problème, je vous en serait reconnaissant.

    Voila le code de la méthode des attach /detach :
    Code:
    unsigned long int attente;
    
    void setup() {
      Serial.begin(9600);
      
      pinMode(2,INPUT);
      digitalWrite(2,HIGH);
    
      attachInterrupt(0,menu, FALLING);
    }
    
    void loop() 
    {
      if(millis() > attente+200)
      {
        attachInterrupt(0, menu, FALLING);  
      }
    }
    
    void menu(void)
    {
      Serial.println("je change de menu");
      detachInterrupt(0);
      attente = millis();
    }
    Cordialement, b.b

    PS : si vous avez besoin de plus de détails pour le code par exemple, demandez moi.

    -----


  2. Publicité
  3. #2
    gcortex

    Re : Programmation d'un anti-rebond

    Citation Envoyé par bigbrownies Voir le message
    , il faut juste retarder la prise en compte du signal d'une centaine ou deux de ms.
    Non

    Il faut faire une tempo après chaque (1er) changement d'état

    20ms suffit.

    PS : R1=100 R2=100K C=220nF
    Dernière modification par gcortex ; 07/04/2014 à 16h49.

  4. #3
    gcortex

    Re : Programmation d'un anti-rebond

    L'information étant prise immédiatement

  5. #4
    bigbrownies

    Re : Programmation d'un anti-rebond

    R1 et c1 n'existent pas ^^.
    Ma pull down à 12k est raisonnable.
    Si tu me dit que 20ms suffisent, ok mais ça ne change pas le problème. toutes les tempos que j'ai essayé de faire avec l'interruption ne fonctionnent pas.

  6. #5
    PA5CAL

    Re : Programmation d'un anti-rebond

    Bonjour


    1) Sur le principe, le filtre passe-bas de ton schéma est insuffisant pour traiter seul les rebonds. Il faut aussi lui adjoindre une entrée présentant un cycle d'hystérésis. Sinon quelques oscillations résultant des rebonds du contact risquent d'être encore perçus lors du passage de la tension de sorie autour du seuil de commutation.


    2) Dans ton code, l'initialisation de la pin 2 réalise l'activation de la résistance de pull-up interne de l'ATMega; et suggère donc, contrairement à ce que tu indiques par ailleurs, que tu utilises un contact situé entre cette pin et la masse ;
    Code:
      pinMode(2,INPUT);
      digitalWrite(2,HIGH);
    S'agissant d'un contact NF (normalement fermé), l'appui sur le bouton ouvre ce contact, et c'est au relâchement que les rebonds se produisent. S'il s'agit d'un contact à la masse avec pull-up interne, les rebonds apparaissent lorsque le niveau logique de l'entrée 2 repasse à 0.

    Je ne sais pas si cela correspond vraiment à ce que tu souhaites.

  7. A voir en vidéo sur Futura
  8. #6
    bigbrownies

    Re : Programmation d'un anti-rebond

    Je souhaite garder mon pull down, il suffit donc que je remplace :
    Code:
    digitalWrite(2,HIGH);
    par :
    Code:
    digitalWrite(2,LOW);
    Ce qui fait que je désactive ma résistance de pull-up interne et que mon schéma avec la pull-down devient correct ?

    Ce que j'aimerais, c est :
    Bouton au repos : 5V sur l'entrée
    Bouton appuyé : 0V sur l'entrée

    Donc quand j'appuie sur mon bouton j'ai un premier front descendant, au relâchement, un certain nombres de fronts descendants indésirables apparaitront.

    Par curiosité(puisque je ne cherche pas de solution hardware), qu'entends tu par trigger ? ce serait une porte logique "non-inverseuse" qui permettrait de créer un signal TOUT ou RIEN ? pour éviter les oscillations.

  9. Publicité
  10. #7
    bigbrownies

    Re : Programmation d'un anti-rebond

    Voila ce que j'ai pensé faire :
    Code:
    unsigned long int attente;
    int valid_int = 0;
    
    void setup() {
      Serial.begin(9600);
      
      pinMode(2,INPUT);
      digitalWrite(2,LOW);
    
      attachInterrupt(0,menu, FALLING);
      attachInterrupt(0,delayInt, RISING);
    }
    
    void loop() 
    {
      if(millis() > attente+200 && valid_int == 1)
      {
        attachInterrupt(0, menu, FALLING);
        attachInterrupt(0, delayInt, RISING);
        valid_int = 0; 
      }
    }
    
    void menu(void)
    {
      Serial.println("je change de menu");
    
    }
    
    void delayInt(void)
    {
      valid_int = 1;
      attente = millis();
      detachInterrupt(0);
    }
    principe de fonctionnement :
    si front descendant perçu sur la pin 2 alors on lance le changement de menu, des qu'un front montant apparait, on désactive les interruptions, puis après un certain délais, on remet en route les interruptions.
    Même problème que j'ai déjà rencontré mais pas résolu. le µC a la capacité de garder en mémoire une interruption qu'il a perçu (même si elles sont désactivés). du coup le premier rebond est pris en compte. Il faut aller voir dans le registre de l'interruption du µC ATMEGA328P, ce que je m'efforce de faire pour comprendre. Pour le moment, je n'ai pas trouvé comment régler le problème.

  11. #8
    nornand

    Re : Programmation d'un anti-rebond


  12. #9
    bigbrownies

    Re : Programmation d'un anti-rebond

    Je te remercie nornand, mais je ne cherche pas ça. Le bouton ne passe pas par une interruption.
    Il n'est donc pas prioritaire sur le reste du programme.

  13. #10
    bigbrownies

    Re : Programmation d'un anti-rebond

    voila un lien qui mène à la datasheet http://www.atmel.com/Images/doc8161.pdf
    A la page 72, chapitre 12.2.3 :
    Il est dit que le Bit INTF0 est mise à 1 si une interruption est détecté. Pour le reset :
    Alternatively, the flag can be cleared by writing a
    logical one to it.
    Il suffirait de le remplir par un 1.

    Je ne vois pas comment remplir le bit INTF0 par un 1.

    Peut être un morceau de code ressemblant à ça:
    Code:
    if(INTF0)
        {
          INTF0 << 1;
        }
    mais le "<<" ne fait que décaler les bits et rajouter des 0 à droite, ce qui n'est pas recherché ici.

  14. #11
    azad

    Re : Programmation d'un anti-rebond

    Une action sur ton bouton fait sauter à une méthode …. si le bouton rebondi, on s'en fiche puisque tu es déjà dans la méthode appelée.
    Et ta méthode, contient

    x = millis();
    while (millis() < x+ delai_souhaité {
    }

    A toi de déterminer la valeur à donner à delai_souhaié en fonction de la qualité de ton bouton poussoir. 10 ou 20 mS devraient suffire.
    On peut supposer qu'après ce temps, le bouton ait fini par se stabiliser.
    Dernière modification par azad ; 07/04/2014 à 19h23.

  15. #12
    bigbrownies

    Re : Programmation d'un anti-rebond

    Merci azad pour ta réponse. Voila ce que j'ai compris de ta manière de faire :
    Code:
    unsigned long int attente;
    
    void setup() {
      Serial.begin(9600);
      
      pinMode(2,INPUT);
      digitalWrite(2,LOW);
    
      attachInterrupt(0,menu, FALLING);
    }
    
    void loop() 
    {
      
    }
    
    void menu(void)
    {
      attente = millis();
      while (millis() < attente+100);
      Serial.println("je change de menu");
    
    }
    Sinon, ça ne fonctionne pas. Il ne prend même pas en compte mon interruption.
    Ensuite, il est fortement déconseillé et je suis d'accord, de figer un programme, et encore moins dans une interruption.

    Cordialement, b.b

    PS : Si quelqu’un est calé dans la modification de bit de registre et les interruptions, ce serait le pied.

  16. Publicité
  17. #13
    azad

    Re : Programmation d'un anti-rebond

    Pourquoi utiliser une interruption ?
    Et ta boucle while n'a pas besoin de contenir autre chose que l'élaboration du délai souhaité. Ou alors ce n'est pas un simple anti-rebonds que tu souhaites.

  18. #14
    bigbrownies

    Re : Programmation d'un anti-rebond

    Je souhaite utiliser une interruption pour avoir une réaction instantanée du système.
    Ensuite ma boucle while tourne dans le vide ici ^^ :
    Code:
    while (millis() < attente+100);
    la ligne d'en dessous c est pour éviter de mettre une 10ène de ligne de code inutile à la compréhension de l'anti rebond (mon changement de menu).

  19. #15
    azad

    Re : Programmation d'un anti-rebond

    Il me semble que tenir à une réaction instantanée tout en utilisant un interrupteur affecté de rebondissement tient de la gageure. Tu as nécessairement un temps perdu à attendre que ton interrupteur soit devenu stable.
    Pour une vraie réponse instantanée, il faut du hard. En l'occurrence chaque poussoir est un repos/travail, suivi par une bascule.(ou deux portes Nand) Avec cela, pas une seule microseconde de perdue. Il existe en CMOS ou TTL des circuits pouvant lire 8 interrupteurs et simplifiant considérablement le câblage. Mais le repos/travail reste indispensable.

  20. #16
    gcortex

    Re : Programmation d'un anti-rebond

    Citation Envoyé par azad Voir le message
    Il me semble que tenir à une réaction instantanée tout en utilisant un interrupteur affecté de rebondissement tient de la gageure.
    Et pourtant je l'ai fait maintes et maintes fois (en soft)
    Dernière modification par gcortex ; 07/04/2014 à 20h06.

  21. #17
    bigbrownies

    Re : Programmation d'un anti-rebond

    Par contre mettre un composant DIP 14 broches pour utiliser 1 porte logique sur les 6, c est une perte de place et d'argent (je ne vais pas commander 1 circuit logique a 30centimes avec 5€ de frais de port), je trouve.
    Je suis d'accord que ce serait plus propre et plus facile.
    C'est pour ça que j'ai opté pour une solution logicielle qui est du coup sans coût.

    gcortex : utilises-tu des interruptions ? ou juste un test "if" ?
    Dernière modification par bigbrownies ; 07/04/2014 à 21h17.

  22. #18
    bigbrownies

    Re : Programmation d'un anti-rebond

    J'ai réussi logiciellement avec des interruptions:

    Code:
    int valid_int0 = 0, reset_int0 = 0;
    unsigned long int attente = 0;
    int menu_c = 1;
    int i = 0;
    
    void setup() {
      Serial.begin(9600);
      
      pinMode(2,INPUT);
      digitalWrite(2,LOW);
    
      attachInterrupt(0,menu, CHANGE);
    }
    
    void loop() 
    {
      if(reset_int0)
      {
        valid_int0 = 0;
        if(millis() > attente+500)
        {
          reset_int0 = 0;
          attente = 0;
          i = 0;
        }
      }
      
      if (valid_int0)
      {
        valid_int0 = 0;   
        switch(menu_c)
        {
          case 1:
            Serial.println("page1 vers 2");
            menu_c = 2;
          break;
          
          case 2:
            Serial.println("page2 vers 3");
            menu_c = 3;
          break;
          
          case 3:
            Serial.println("page3 vers 1");
            menu_c = 1;
          break; 
        }
      }
      
      //noInterrupts(); //désactive toutes les intéruptions 
      //interrupts(); //active toutes les interruptions
    }
    
    void menu(void)
    {
      i++;
      if(i==1)
      {
        valid_int0 = 1;
      }
      if(i==2)
      {
        reset_int0 = 1;
        attente = millis();    
      }
    }
    Mon problème c'est que j'essayais de tout mettre dans l'interruption mais c est seulement la prise en compte de l'appuie qui devait être interprété à travers une variable.

  23. Publicité
  24. #19
    terriblement

    Re : Programmation d'un anti-rebond

    Tu fais une interruption qui s'active toutes les ... disons 2ms (donc avec un timer)
    => Pas besoin de cabler sur une entrée d'interruption

    Dans cette boucle, tu vérifieras systématiquement l'état du port à surveiller ( là ou se situe ton bouton).
    Si changement d'état détecté (nouvelle valeur différente de l'ancienne valeur, tu auras besoin d'une variable ), alors tu mets une variable à 0 (appelons la "port_stable").
    si aucun changement d'état, tu incrémentes "port_stable" de 1. (pense à la déclarer en "static" ou en variable globale, pour éviter qu'elle soit réinitialisée à chaque fois que tu entres dans ta boucle).

    si port_stable > 20 (donc en gros 40ms si on interrupt toutes les 2ms avec le timer), alors tu mets une variable globale qui s'appelera par exemple "pression_bouton_1" à 1.

    Dans ton programme tu prendras soin de vérifier si "pression_bouton_1" est à 0 ou 1 selno ce que tu veux faire.

    Voila en gros

  25. #20
    bigbrownies

    Re : Programmation d'un anti-rebond

    Effectivement, c'est pas mal.
    Pour le moment j'ai utilisé la bibliothèque "timerOne". Pour un BP c'est suffisant mais je pense me replonger dans le problème de l'interruption externe car ça peut toujours être utile.

  26. #21
    annjy

    Re : Programmation d'un anti-rebond

    Bonsoir,

    j'ai l'impression qu'il faudra bientôt un Tianhe-2 pour traiter les rebonds d'un switch......

    un peu cher.....

    cdlt,
    JY

  27. #22
    bigbrownies

    Re : Programmation d'un anti-rebond

    C'est juste une question de s'adapter à ce que je possède soit pas de grosse résistance et de condo. Je fais donc avec ce que j'ai, un µC.
    Si je devais monter un projet sérieux alors je commanderais une porte logique TTL, une résistance et un condo, puis j'utiliserais une simple interruption sans problème.
    Et puis, ca ne fait pas de mal de chercher ce genre de solution, ce sera toujours réutilisable dans d'autres circonstances.

  28. #23
    gcortex

    Re : Programmation d'un anti-rebond

    Citation Envoyé par bigbrownies Voir le message
    gcortex : utilises-tu des interruptions ? ou juste un test "if" ?
    Pas d'interruption : Juste un while (bouton relaché) avec si besoin une séquence à l'intérieur.

  29. #24
    bigbrownies

    Re : Programmation d'un anti-rebond

    Est-il possible de cumuler une interruption externe et par timer ?
    J'ai l'impression que ça bug chez moi, et j'ai beau vérifier mon code, je ne vois pas où est l'erreur.

  30. Publicité

Sur le même thème :

Discussions similaires

  1. anti rebond
    Par florian85 dans le forum Électronique
    Réponses: 9
    Dernier message: 02/05/2011, 08h48
  2. Anti rebond
    Par willoup dans le forum Électronique
    Réponses: 3
    Dernier message: 24/03/2009, 21h32
  3. BP anti-rebond
    Par jum0034 dans le forum Électronique
    Réponses: 10
    Dernier message: 19/09/2008, 14h31
  4. anti rebond
    Par mattheo25 dans le forum Électronique
    Réponses: 7
    Dernier message: 26/07/2007, 13h03
  5. Anti rebond
    Par zanzeoo dans le forum Électronique
    Réponses: 3
    Dernier message: 07/08/2004, 10h56