Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Commentez, partagez et proposez des Tutos en langage C !
Faire un anti-rebond
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#1 Message par Jérémy » jeu. 13 août 2015 17:21

Bonjour à tous,

Je vous propose de vous expliquer le phénomène , anti-rebond , qu'il faut traiter dès que l'on utilise un interrupteur, en particulier ,nos chers boutons-poussoirs.

On appelle phénomène rebond , le fait que le contact d'un BP n'est pas franc, de part l’élasticité des matériaux utilisés et de l'architecture mécanique , induisant plusieurs pic de tension, très rapide.
Le passage de l'état haut à l’état bas, peut donc être interpréter plusieurs fois lors d'un seul appui, si votre programme tourne vite !

Il y a plusieurs méthodes pour palier à ceci, certaines avec des inconvénients .
Image



voici un rebond, lors du passage de l’état bas à l’état haut d'un bouton poussoir.

On remarque lors de l'appui des pics se forment avant de se stabiliser à l’état haut .

Ce sont ces rebonds qu'il va falloir "masquer".




Image


Méthode en hard :

Mettre un condensateur en parallèle sur le BP , au plus prêt de celui ci .
Ainsi lors de la montée et de la descente du pic de tension, le condensateur va "amortir" ces pics de tension et les "lisser" en quelques sortes.




Méthode en Soft:

Pour des questions de raisonnement , je détermine qu'au repos le BP est relâché et que la broche du µC, est donc relié a GND (par la pull-down), Lors d'un appui on met le potentiel de la broche à Vcc.

1/ créer une pause afin d'attendre la stabilisation de la tension . et ré-vérifier l’état haut pour valider l'action a faire.

On obtiendrai ceci :

Code : Tout sélectionner

while(1)        // Ici c'est notre boucle sans fin.
 {
   if (BP == 1)            // Si le BP est appuyé
   
      
{delay_ms(10);}   // On marque une pause pour attendre la stabilisation à l'état haut.
                            // Je met les accolades par reflex même si avec une seule action dans le "if" je pouvais m'en passé.
                    
           if 
(BP == 1)            // Si après la pause l’état est toujours à 1 (Vcc) alors valide notre action , et on peut l’exécuter.
           
           
{Action à réaliser après un appui}
  }


les inconvénients de cette méthode sont que le programme est bloqué pendant les 10ms de pause .Pause qui est peut être variable suivant les BP, leurs mécaniques , leurs anciennetés etc ( entre 10ms et 50ms en général).
Et la deuxième , c'est que si vous laissé appuyer trop longtemps, il se peut que le programme fasse un deuxième tour et détecte un autre appui ;

2/ amélioration de la première méthode

Pour palier au problème de répétition d'appui, lors d'un appui prolongé , nous allons autoriser le programme à repartir seulement quand le BP est relâché .
Ainsi je vais créer une boucle vide , tant que le BP sera à l'état haut.

Code : Tout sélectionner

while(1)        // Ici c'est notre boucle sans fin.
 {
   if (BP == 1)            // Si le BP est appuyé
   
      
{delay_ms(10);}   // On marque une pause pour attendre la stabilisation à l'état haut
                            // Je met les accolades par reflex même si avec une seule action dans le "if" je pouvais m'en passé.
                    
           if 
(BP == 1)            // Si après la pause l’état est toujours à 1 (Vcc) alors valide notre action , et on peut l’exécuter.
           
           
{Action à réaliser après un appui}
  
      while 
(BP ==1) {}    // Ici notre boucle qui tourne sur elle même, tant que le BP est appuyé il faut donc obligatoirement relâché le BP pour sortir .
      {delay_ms(10);}   // On marque une pause pour attendre la stabilisation à l'état bas. 
  }
 


Dans cette méthode, c'est nous même qui bloquons le programme, si jamais le bouton reste appuyé. Mais on ne peut effectuer plusieurs fois la même action si on laisse le doigt appuyé . c'est a vous de faire des compromis et de trouve ce qui vous va le mieux .

3/ La meilleure pour moi
Ici on va compliquer un peu, mais cela va libérer le programme. En effet ce qui nous bloque c'est le fait de détecter et comparer l'appui sur le BP .
Pour palier à ce problème nous allons travailler avec un flag ( *drapeau ).

Voici le déroulement du programme :

- On détecte l'appui du BP, par un passage à l'état haut et on temporise pour éviter les rebonds (rien de neuf).
- On passe notre flag à 1 . Ce flag à pour but de nous indiqué que le BP à été appuyé(mémorisation) . Donc nous avons eu un front montant.
- Ensuite l'astuce: On compare l'état actuel du BP , à l'état d’avant( notre mémorisation) .
- Si nous avons eu un front montant, et que maintenant nous sommes à l'état bas , c'est qu'il y a eu un front descendant, donc un appui.

Code : Tout sélectionner

 //#################################     Boucle infinie    #########################################

while(1)                 // Ici c'est notre boucle sans fin.
 {
   if (BP == 1)          // Si notre Bp est appuyé
  {
      delay_ms(10);      // On fait une pause stabiliser notre niveau logique . ( avec 1ms ça suffit sur mes BP).
       etat_Bp = 1;     // On met notre flag à 1, pour signaler que notre Bp à été appuyé
    }
    
 
// L'astuce es ici
if (etat_Bp == 1 && (BP == 0))      // Si notre BP à été appuyé ET qu'actuellement sont état est relâché. Alors c'est qu'il y a front descendant donc un appui est validé
{                               // Si notre BP n'avait pas été appuyé donc état_Bp =0 , nous aurions pas incrémenter notre chiffre.
  unite++;               // Si notre BP à été appuyé mais que son état  actuel est toujours appuyé , nous aurions pas incrémenter notre chiffre.
  etat_Bp = 0;          // Résultat on as bien détecter un front montant ( BP appuyé) et un front descendant (BP relâché)
  delay_ms(10);         // On incrémente le chiffre
                   // Ici on remet notre flag à 0 pour ré-armer notre détection de front montant
 }                  // On fait une pause pour le éviter les rebonds au relâchement

   affichage() ;
 }                      // Nous arrivons à la parenthèse de la boucle infini, donc on repart au début et ainsi de suite .
}                       // Fin de notre fonction principale                  


Voila , je n'ai pas trouvé mieux pour faire un anti-rebond efficace !

Maintenant ceux qui travaille avec MikroC peuvent utilisé la fonction "button" , qui simplifie le code, car elle comprends l’état du bouton , la tempo .
Voici le même exemple en utilisant "button".

Code : Tout sélectionner

 //#################################     Boucle infinie    #########################################

while(1)                 // Ici c'est notre boucle sans fin.
 {

  if ( Button(&PORTC, 0, 10, 1))  // ( nom du port, N° broche du BP, temporisation anti rebond (10ms), état du BP (0 ou 1) )
         etat_Bp = 1;             // On met notre flag à 1, pour signaler que notre Bp à été appuyé

  if ( etat_Bp == 1 && Button(&PORTC, 0, 10, 0))   // comparaison de notre ancien état(état BP) , à l’état actuel avec tempo ( fonction "button")
      {
       unite++;        // On incrémente le chiffre
       etat_Bp = 0;    // Ici on remet notre flag à 0 pour ré-armer notre détection de front montant
      }

   affichage() ;

 }                      // Nous arrivons à la parenthèse de la boucle infini, donc on repart au début et ainsi de suite .
}                       // Fin de notre fonction principale            


Image


Configuration :

-IDE : MikroC Pro for PIC Version 6.6.2
-Compilateur : Mikro prog suite fo PIC V 2.32
-Plaque Easy PIC V7






L'objectif :
Visualiser l'effet indésirable du rebond ( ou plutôt de l'appui prolongé)
Je n'ai pas réussis à faire un programme permettant de compter le nombre de pics de tension lors d'un appui. Encore une fois si un Expert passe par la !

[spoil]

Code : Tout sélectionner

 //#################################     Boucle infinie    #########################################

while(1)                 // Ici c'est notre boucle sans fin.
 {
   if (BP == 1)              // Si le BP est appuyé
      delay_ms(10);          // On attend pour stabilisation
           if (BP == 1)         // Si il est toujours appuyé ce n'est pas un rebond
           {unite++;}           // On incrémente le chiffre
            
            while 
(BP ==1){ affichage() ;}        // Ici on boucle tant qu'on a pas relâché le BP.Delay_us Mais je n'aurai plus d'affichage
                                                      // Comme ceci bloque, alors j'ai mis l’affichage dans la boucle pour la démo !

   affichage() ;

 }                      // Nous arrivons à la parenthèse de la boucle infini, donc on repart au début et ainsi de suite .
}                       // Fin de notre fonction principale                     
[/spoil]

La vidéo est un peu sombre pour limiter les scintillement des afficheurs.
http://www.dailymotion.com/video/x31kqz9

Conseils :

- Les flags, sont des variables de type "bit" , donc pouvant prendre la valeur de 0 et 1 seulement. Ils sont très utiles, car prendre peu de place, et peuvent changer d’état facilement ( en leur ajoutant 1 par exemple il passe 1 à 0 ou de 0 à 1) .

- dans les programmes j’écris par exemple "etat_Bp == 1" , ceci peut être remplacé implicitement par "etat_Bp" , cela serait interprété pareil . maintenant si vous n'êtes pas à l’aise , continuer d'écrire avec "==" ça évitera les ennuis .
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Tuto N°4, Faire un anti-rebond
mazertoc
Passioné
Passioné
Messages : 201
Enregistré en : juillet 2015
Localisation : Auvernha

#2 Message par mazertoc » dim. 16 août 2015 19:59

Remarques :
- mettre une résistance en série avec le condensateur
- on peut mettre, selon son schéma, le BP côté 0V

Tuto N°4, Faire un anti-rebond
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#3 Message par Jérémy » lun. 17 août 2015 00:45

Ok mazertoc, j'ai apporté la modification pour montrer la pull-up et la pull-down .

Par contre concernant le résistance en série sur le condo j'ai un gros doute quand même. je n'ai pas trouvé un schéma , montrant ceci . Et du coup ça limiterai le temps de charge du condo non ?
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Tuto N°4, Faire un anti-rebond
mazertoc
Passioné
Passioné
Messages : 201
Enregistré en : juillet 2015
Localisation : Auvernha

#4 Message par mazertoc » lun. 17 août 2015 17:10

Jérémy a écrit :Par contre concernant le résistance en série sur le condo j'ai un gros doute quand même. je n'ai pas trouvé un schéma , montrant ceci . Et du coup ça limiterai le temps de charge du condo non ?

Je viens d'en voir #1 !!!

Le but c'est de limiter le courant instantanné à la décharge du condensateur (améliore la durée de vie des contacts).
Le temps de charge est aussi augmenté.

Faire un anti-rebond
HULK28
Avatar de l’utilisateur
Amateur
Amateur
Messages : 106
Enregistré en : août 2015
Localisation : IdF

#5 Message par HULK28 » mer. 23 sept. 2015 16:09

Bonjour,

la gestion des appuis bouton est importante à comprendre, il y a plein de façons de considérer la chose.

Voici une liste non exhaustive mais qui rassemble les principales problématiques rencontrées:

-> l'appui est validé au relâchement du bouton
-> l'appui est validé dès l'appui du bouton (sur front montant ou descendant)
-> l'appui est validé après une durée prédéterminée
-> l'appui est mémorisé et sera utilisé ultérieurement lorsque la tâche principale sera disponible
-> l'appui est mémorisé et sera utilisé si un autre évènement survient, sinon il sera annulé

Tous ces cas peuvent être gérés par le software.

Lors d'un appui il survient une multitude de rebonds générés par plusieurs phénomènes, il n'y a pas de profil type, ces rebonds répondent et dépendent toujours des mêmes causes, leur nombres et leur durée varient selon :

-> souplesse/dureté du rappel mécanique
-> type de rappel mécanique (lamelle élastique ou ressort)
-> humidité relative
-> intensité du courant circulant (coupé/ouvert)
-> impédance de la ligne
-> la forme du contact (circulaire ou autres)
-> la résistance du contact
-> durée de vie du contact (la variation dans le temps de sa qualité)
-> profil du modèle de l'appui (force et manière dont l'appui est exercé)

Le choix doit se faire selon le résultat attendu, il n'y a pas une seule bonne méthode.
On peut avoir besoin d'une réactivité (type manette de jeu) ou que l'appui soit pris en compte lorsque l'utilisateur le décide au jugé, ou encore que l'appui soit enregistré (par exemple si une séquence est en cours et que l'on connait la prochaine question que l'on veut passer aussitôt le processus fini), ou encore faire un choix qui sera mémorisé et pris en compte si et seulement si le résultat qui est en cours peut présenter un résultat aléatoire ou de nature variable (par exemple si le résultat est VRAI alors l'appui sera pris en compte, si il est FAUX il sera ignoré)
"Pour la carotte, le lapin est la parfaite incarnation du mal" -Robert Shecley-


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité