[Interruptions] Filtrage necessaire ?

Bonjour,

Je poursuis mon apprentissage de l'Arduino. Mon objectif est de réaliser un compteur kilométrique pour ma voiture "ancienne", avec laquelle je participe à des rallyes historiques.

Aujourd'hui, elle est équipée d'un bête compteur de velo sur la roue avant. La précision est très bonne. L'idée, c'est de ne plus utiliser le compteur de velo mais l'Arduino. Le fil qui sort du capteur est un interrupteur tout simple : 2 fils, qui font contact à chaque passage de la roue.

J'ai donc réalisé le montage le plus simple possible: 1 interrupteur sur ma bread board (qui simule le capteur), un fil sur la pin 21 de mon Mega2560, un fil sur le "GND". Et je compte les impulsions via l'interruption n°2.

Apres quelques tests, tout marche plutôt bien, sauf que j'ai parfois des suprises : lorsque j'appuie sur l'interrupteur, il me décompte 2 ou 3 impulsions. Si au lieu de passer par l'interrupteur je fais se "toucher" les 2 fils, là, c'est encore pire: parfois 4/5 impulsions sont décomptées.

J'imagine qu'en réalité il y a des micro-coupures, et que plusieurs "FALLING" de mon interruption sont détectés. Est-ce le bon diagnostic ? Et quelle est la solution dans pareil cas pour "filtrer" ces micro-coupures ? Étant informaticien, la première solution qui me vient à l'esprit est de résoudre le problème par programmation (par exemple, ne prendre en compte l'interruption que si la précédente s'est produite au moins 30 ms auparavant, sachant qu'à 150km/h j'aurai en gros 25 impulsions par secondes, soit 1 toute les 40ms maxi)

Est-ce une bonne piste ? Existe-t-il une solution plus "propre" ?

D'avance merci pour vos réponses :slight_smile:

Ton filtrage par prog est une bonne idée, mais risque de bien alourdir ton soft (l'arduino reste un arduino). mets un condensateur de 100nF en parallèle sur ton entrée (entre l'INT et la masse), tu verras, ça aide pas mal... les deux (filtre électronique et programmation) seront ensemble une arme de défense redoutable!

Hello etheriel,

Je viens justement de passer au moins 15 jours à discuter par mail avec un ami électronicien et à expérimenter concrètement des systèmes hardware anti-rebond en vue de fabriquer une carte de développement pour les AVR.

Ton problème est typiquement celui des rebonds produits par tout bouton-poussoir, interrupteur, etc...

Voici ci-dessous le montage qui m'a donné entière satisfaction. Avec un tel système il n'y a strictement plus moyen de produire le moindre rebond. Une pression (rapide ou lente) sur le bouton ne donne qu'une seule impulsion en sortie. Cette impulsion peut alors être détectée par une interruption externe (INT0 ou autre) sans aucun ajout de programmation d'attente.

Le système se compose de 2 résistances, d'une diode et d'un condensateur de 100nF (un petit condensateur céramique. Ceci constitue un filtre RC déjà pas mal efficace. Ce filtre est suivi d'une porte du CD40106 qui est un chip comportant 8 portes qui sont des Triggers de Schmitt. Ces petites bêtes ont l'immense avantage d'avoir deux seuils de basculement différents, ce qui bloque tout rebond qui parviendrait encore à traverser le filtre. La sortie du Trigger se raccorde à l'Atmega à travers une résistance de 330 Ohms.

Si tu as des questions, je t'écoute.

Je suis tout à fait d'accord qu'il est préférable de traiter le problème à la base en supprimant électroniquement les effets des rebonds plutôt que de les masquer avec de l'informatique.

Pourtant le schéma de Jean-Marie, que j'ai déjà vu, me pose problème en ce qui concerne l'égalité des constantes de temps de charge et de décharge.

Que se passe-t-il physiquement ?
L'inter est formé d'une lame ressort qui vibre au moment des changements d'état (passage d'"ouvert" à "fermé" et vice versa). Pour des petits inters la période des vibrations est de l'ordre de quelques millisecondes.

Que veut-on ?
Que la tension qui commande l'arduino reste le plus près possible de OV et en tout cas ne dépasse jamais le seuil de détection du "0" ou "1" de l'arduino. Sur mon exemplaire ce seuil est égal à 2,4V avec un hystérésis inférieur à 40mV.

On a donc intérêt a ce que le condensateur se décharge le plus complètement et le plus rapidement possible quand la lame fait contact et qu'il se charge beaucoup plus lentement quand la lame s'ouvre afin qu'il n'atteigne jamais les 2,4V fatidiques.
Donc pour moi la constante de temps de décharge (Tau_décharge = R2C1) doit être au minimum inférieure au 1/50 de la constante de temps de charge (Tau_charge = R1C1). Donc R2<<R1.

Le trigger de schmitt est par contre une très bonne idée mais il n'est pas obligatoire de passer par un modèle "tout fait" dont l'hystérésis n'est pas modifiable.
Un comparateur à collecteur ouvert comme le LM393 est idéal pour cette application.
Ci dessous un lien vers une datasheet de LM393 où on trouve un exemple de trigger de schmitt avec le moyen de calculer l'hystérésis (voir page 5).
http://www.datasheetcatalog.org/datasheets/150/50345_DS.pdf

Hello 68tjs,

C'est vrai, on peut faire un Trigger avec un LM393 ainsi qu'avec beaucoup d'autres amplificateurs opérationnels. Je n'ai jamais essayé le LM393 mais j'ai fait des essais avec un LM324 en mono-alimentation 5V et cela marche aussi bien qu'avec un Trigger "officiel" comme le CD40106. Personnellement, j'ai jeté mon dévolu sur le 40106 car il comporte 6 Triggers et avec 2 chips, je peux traiter jusqu'à 12 boutons ou interrupteurs.

Pour la valeur des résistances, tu plaides pour que R2 soit nettement inférieur à R1. Et c'est vrai que dans ce cas, lorsqu'on appuie sur le bouton, la tension chute très rapidement à zéro.
Cependant, les rebonds se produisent de la même manière quand tu relâches le bouton. Autrement dit, lorsque tu relâches le bouton, la tension commence à remonter vers le +5V mais les rebonds se produisent dans le sens inverse de l'appui : les rebonds sont formés par des micro-contacts qui se produisent encore avec le 0V. Comme R2 est faible, la rechute de tension est brutale. Si jamais le tension du condensateur vient de dépasser le seuil supérieur (qui fait passer la sortie à 1), cette brutale chute de tension risque éventuellement de faire repasser l'autre seuil à la baisse.
Lorsque R1 et R2 sont élevés, ils empêchent les variations brutales de la tension du condensateur, que ce soit à la hausse ou à la baisse et donc on se tient loin des zones à risque. Maintenant, je suis bien conscient que la marge est très large avec les valeurs que j'indique. J'ai fait des expériences avec diverses valeurs de résistances. Je suis descendu jusqu'à R1 = R2 = 1,8K et même ces valeurs ne m'ont donné aucun rebond mais il est clair que plus on descend, plus on s'approche de la possibilité d'un vilain rebond qui parvient tout juste à faire rebasculer le trigger.

Les valeurs du schéma que je propose retardent le signal de sortie de 20 à 30 ms, aussi bien pour le front montant que pour le front descendant, de sorte que la durée totale du signal de sortie est à peu près équivalent à la durée du signal entrant.
Si ce retard est un problème pour le programme, on peut réduire la valeur des résistances.

Je voudrais ajouter une information pour etheriel. Au lieu de capter la réponse par une interruption externe, il serait préférable de la capter par un timer configuré en compteur externe. En effet, une interruption provoque chaque fois un appel à une ISR (interrupt service routine) et cela fait perdre pas mal de cycles à l'Atmega. Un compteur s'incrémente automatiquement à chaque impulsion d'entrée, sans intervention logicielle, de sorte que l'Arduino peut traiter une fréquence d'impulsion plus élevée sans perte de données. Le compteur ne produit une interruption qu'à chaque overflow.

Cependant, les rebonds se produisent de la même manière quand tu relâches le bouton.

Non c'est là la méprise.
Quand tu "ferme" le circuit des micro oscillation de quelques dixième de mm suffisent à "ouvrir" le circuit.
Mais en sens inverse les mêmes micro oscillations sont incapables de "fermer" le circuit où alors l'inter est vraiment mauvais.

Je serais d'accord avec toi seulement s'il s'agissait d'un inverseur où il existe deux circuits qui sont fermés alternativement.

Personnellement je ne met pas de diode et je place la résistance R2 en série avec l'inter, cad en parallèle sur C1, son rôle est de protéger le condensateur en limitant le courant maximal, 100 ohm ou 1k me suffise. Je place aussi une résistance de 1k en série avec l'entrée du micro (à raz du micro). Son rôle ? -> anti-bétise (on ne sait jamais les fausses manip que l'on peut faire en phase de mise au point).

Quant au trigger de schmitt on peut effectivement en faire avec un ampli opérationnel mais dans ce cas on ne maitrise pas aussi bien l'hystéréris qu'avec un comparateur et surtout un comparateur à collecteur ouvert.

Un comparateur est un type particulier d'ampli op :

  • très grand gain
  • vitesse de commutation élevée
  • en contre partie des deux avantages précédents : mauvaise linéarité -> c'est normal il n'est fait pour amplifier, les vrais ampli op sont eux optimisé pour.
    Le collecteur ouvert oblige à mettre une résistance entre la sortie et l'alim positive mais permet de maitriser le schéma, il suffit de faire les calculs de l'exemple que j'ai cité pour bien le comprendre.
    Ce qu'il faut voir dans cet exemple c'est que le schéma équivalent n'est pas le même selon que la sortie du comparateur est au rail négatif ou au rail positif et c'est grace à cette modification du schéma équivalent que l'on peut avoir deux valeurs de commutation et donc de l'hystérésis.

Hello 68tjs

J'ai fait quelques petits tests avec un bouton poussoir du type tact switch comme pour le reset de l'Arduino. Le bouton est raccordé d'un côté à GND et de l'autre côté à +5V à travers une résistance de 10K. Le point commun entre le bouton et la résistance est raccordé à la pin PB0 d'un Atmega1284, ce qui correspond à l'entrée du Timer/compteur 0. Le quartz est de 16 MHz. L'état du compteur est affiché par 8 leds sur le port A. Le programme est écrit en assembleur.

Pour l'étude des rebonds à l'appui du bouton, je compte les fronts montants sur 40 tests consécutifs:
0,1,1,0,0,0,0,0,0,0,2,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0

Pour les rebonds au relâchement du bouton, je compte les fronts descendants:
4,1,3,2,3,3,0,0,8,4,0,2,1,1,2,2,16,1,1,0,2,0,1,0,1,0,66,1,0,7,2,0,0,2,4,2,10,3,0,1

Je me suis demandé si cela changerait quelque chose de mettre la résistance entre le bouton et GND et de raccorder le point commun au µC.

Dans ce cas, à l'appui du bouton, ce sont les fronts descendants qui constituent des rebonds:
0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,0,0

Au relâchement, les rebonds sont des fronts montants :
0,0,4,2,13,1,28,1,0,1,0,0,0,0,1,1,1,0,1,0,79,0,0,1,1,0,0,1,0,0,0,0,0,5,0,0,1,1,0,0

Ma conclusion ne concerne évidemment que mon bouton poussoir. Celui-ci montre des rebonds plus nombreux au relâchement sur 80 tests.

J'ai oublié de mentionner que le schéma que j'ai présenté provient du site suivant : https://sites.google.com/site/kfodorprojects/home/electronics-projects-1/hex-switch-debouncer-module, lui-même faisant référence à un article détaillé : Debouncing Contacts and Switches

Le schéma que tu as proposé je l'avais déjà vu mais je ne me rappelais plus où.

Pour mon expérience personnelle avec un poussoir référence :
Boutons-poussoirs - Go tronic Poussoir D6
J'ai supprimé tout effet de rebond avec juste la résistance de tirage (dîte "pull up") en entrée micro et un condensateur de 100nF en // sur les broches du poussoir.
C'était osé de se limiter à un schéma aussi simpliste mais j'avais la flemme de câbler et j'ai tenté pour voir et ça a marché sans problème (je n'aurais pas pris ces risques en programmation mais là je suis plus en terrain de connaissance :grin:).

Info : j'activais les interruptions PCINTx sur le port C (broches A0 à A5) et donc avec PCINTx j'étais sensible uniquement au changement d'état a savoir "état bas -> état haut" ou "état haut -> état bas".
J'ai bien pu vérifier que je n'avais qu'une seule interruption quand je pressais le bouton et qu'une seule quand je relachais le bouton.

Résistance en série avec le poussoir:
Pour faire simple je n'ai évoqué que la fonction anti-bétise mais elle a une autre fonction : celle d'amortir le circuit.

Il faut savoir qu'un fil rectiligne dans l'air présente une inductance linéique d'environ 10nH par cm.
Si le poussoir est relié par des fils de 10 cm on a donc une inductance d'environ 200nH. Si les fils forment une boucle ils constituent l'embryon d'un bobinage et il faut ajouter 300 à 400nH.
Le schéma équivalent est donc un circuit série capa (100nF) self (~600nH) et résistance (celle des fils ~0,5 ohms).
Et là en voulant améliorer on fait pire que si on n'avait rien fait car le circuit RLC se met à osciller.

Pour éviter les oscillations on peut agir sur l'amortissement du circuit RLC en ajoutant une résistance en série ou en diminuant l'inductance.
Pour diminuer l'inductance c'est simple il suffit de torsader les fils du poussoir entre eux :

  • la surface de la boucle devient quasi nulle.
  • les deux conducteurs étant très proches et le courant étant le même à l'aller qu'au retour le champ électrique créé par le conducteur aller est annulé par le champ électrique du conducteur de retour et au lieu d'avoir 10nH par cm on n'a quasiment plus rien.

Dans la réalité chaque modèle de poussoir est différent et il faut s'adapter mais torsader les fils et mettre entre 100 et 1K ohms en série sont deux actions simples qui ne coûtent rien et qui peuvent éliminer bien des problèmes.

Pour mon expérience personnelle avec un poussoir référence :
Boutons-poussoirs - Go tronic Poussoir D6
J'ai supprimé tout effet de rebond avec juste la résistance de tirage (dîte "pull up") en entrée micro et un condensateur de 100nF en // sur les broches du poussoir.
C'était osé de se limiter à un schéma aussi simpliste mais j'avais la flemme de câbler et j'ai tenté pour voir et ça a marché sans problème

Je viens d'essayer. ça marche !

J'ai fait 256 essais consécutifs avec une résistance pull-down de 10K et un condensateur céramique de 100nF en parallèle avec le bouton. Liaison au µC par un câble de 10 cm ==> pas un seul rebond.
Merci 68tjs. Cela va simplifier ma carte de développement et me faire gagner de la place.

P.S. Cela ne me fera pas gagner des sous car j'avais déjà acheté les CD40106 !

Bonjour,

Et donc, pour le profane que je suis, à quoi ressemble le cablage de cette solution ? Est-ce lié à l'utilisation de ce bouton poussoir ?
Car dans mon cas, en condition reelle, ce ne sera pas un bouton poussoir mais "2 fils qui se touchent" qu'il faudra que je surveille :wink:

Je n'ai pas eu le temps d'essayer la solution avec un condensateur en // au bouton poussoir (il faut dire aussi que.... je n'ai pas de condensateur à la maison ! je viens d'en commander)

Merci pour vos reponses

Hello etheriel,

Le schéma de l'expérience que je viens de réaliser est extrêmement simple :

J'ai remplacé le bouton poussoir par les deux fils qui viennent de ta roue. Dans cette configuration, c'est le front montant que tu dois surveiller car lorsque les deux fils font contact, la tension appliquée au µC passe brusquement de 0V à +5V.

Tu peux également mettre la résistance entre le condensateur et le +5V. Le fil qui va au µC doit toujours provenir de la jonction entre la résistance et le condensateur. Dans ce cas, c'est le front descendant que tu dois prendre en compte.

Ce système composé d'une résistance et d'un condensateur présente quand même un plus grand risque d'erreur que les systèmes plus complexes.

Merci beaucoup pour ces explications claires. Je vais tester ca "en reel" dès que j'aurai recu mes condensateurs.
Le test sera facile: mes 2 roues sont équipées de capteur (pour palier à une crevaison / perte d'un capteur / ...) : sur l'une je laisserai mon compteur de velo, et sur l'autre je mettrai mon montage. Il suffira de comparer les 2 valeurs :slight_smile:

Je vous tiens au courant, et potentiellement je reviendrai avec d'autres questions :wink:

Merci !

Hello etheriel

Je vous tiens au courant, et potentiellement je reviendrai avec d'autres questions smiley-wink

Tu es le bienvenu pour d'autres questions. En revanche, ce serait sympa de nous faire part de tes observations en comparant les 2 roues.

Pas de souci, je vous ferai un "retex" comme on dit :slight_smile:

Je voudrais ajouter une constatation importantepour le dernier schéma que j'ai proposé.

A une quinzaine de cm de l'atmega, il y a une lampe de bureau posée sur la table. C'est une lampe halogène avec un transfo 12V dans le pied. Lorsque j'actionne l'interrupteur de la lampe, cela occasionne de multiples rebonds que l'atmega comptabilise.

J'ai essayé le branchement inverse, c'est-à-dire avec la résistance entre le condensateur et le +5V (et la liaison au µC raccordée entre la résistance et le condensateur). C'est pareil, l'interrupteur de la lampe déclenche de multiples rebonds.

Si je place la lampe à 50 cm de l'atmega, c'est encore la même chose.

Donc, le système est très sensible aux parasites de la tension secteur. Il vaut mieux le savoir.

Et si tu blinde ta carte arduino dans un boîtier métallique relié à une masse, est-ce que ça fait la même chose ?

Parce que le schéma n'y a peut-être rien à voir mais ça peut être le micro qui capte des émissions électromagnétiques produites par la lampe halogène.

le schéma n'y a peut-être rien à voir mais ça peut être le micro qui capte des émissions électromagnétiques produites par la lampe halogène

Je me demande si ce n'est pas plutôt du transfo de la lampe que je dois me protéger.
Enfin, pour vérifier si le schéma est en cause, j'ai refait le schéma avec le CD40106.
Eh bien, le schéma n'y est pour rien. J'obtiens les mêmes rebonds lorsque j'actionne l'interrupteur de la lampe.

J'ai essayé de mettre les breadboards du montage dans une vieille boîte à biscuit raccordée à la masse par une pince. Je ferme la boîte, j'actionne l'interrupteur, je rouvre la boîte ... et l'atmega a de nouveau comptabilisé des rebonds (mais la lampe était toujours à 15 cm de la boîte).

Bonjour,

Comme promis, un premier retour d'experience. J'ai reçu mes condensateurs vendredi, et ce WE, j'ai realisé le montage. J'ai placé la resistance entre le 5V et le bouton poussoir. Manuellement (en faisant toucher les 2 fils), j'ai tout de suite vu qu'il n'y avait plus ces rebonds.
Et donc, petit test grandeur nature: je sors mon ancetre de son hivernage, je branche le compteur de velo sur un capteur, l'arduino sur l'autre, et en voiture !

Résultat de ce petit test: 2.15 km sur le compteur de velo, 2.16 sur l'arduino (1255 impulsions, soit 2.165km exactement). Il y a donc une "poignée" d'impulsions qui manquent, mais c'est très faible. Vitesse "de pointe": 118km/h (20 impulsions/seconde). A priori ca passe.

Je vais donc faire des tests bcp plus long, à priori mercredi. Je vous ferai à nouveau un retour.

Et concernant les interferences du 220v, pas de souci, je suis à l'abri dans ma vieille guimbarde :slight_smile:

Merci beaucoup pour votre aide !

Merci etheriel pour ce petit rapport d'expérience.

Il y a donc une "poignée" d'impulsions qui manquent

Je ne comprend pas très bien. Tu dis que le compteur vélo te donne 2,15 km alors que l'Arduino t'en donne 2,16. D'après ce que je comprends, l'arduino t'a donc donné plus d'impulsions que le compteur vélo puisqu'il comptabilise une plus longue distance, c'est-à-dire plus de tours de roue. Pourquoi dis-tu alors qu'il y a une poignée d'impulsions qui manquent ?

oups: "quelques impulsions en trop" (ou ratées par le compteur de velo).
J'en saurai plus sur une plus grande distance. Et je vous en ferai un compte-rendu