Ligne 169 : |
Ligne 169 : |
| # ... <small>d'autres contraintes peuvent exister, référez vous à la [https://micropython.org/resources/docs/en/latest/wipy/library/machine.Pin.html documentation de MicroPython]</small> | | # ... <small>d'autres contraintes peuvent exister, référez vous à la [https://micropython.org/resources/docs/en/latest/wipy/library/machine.Pin.html documentation de MicroPython]</small> |
| | | |
− | == Exemple == | + | === Exemple === |
| Dans cet exemple nous allons prendre le contrôle de la LED HeartBeat et la faire changer d'état à chaque fois que l'on presse sur le bouton raccorder sur GP8. | | Dans cet exemple nous allons prendre le contrôle de la LED HeartBeat et la faire changer d'état à chaque fois que l'on presse sur le bouton raccorder sur GP8. |
| | | |
Ligne 213 : |
Ligne 213 : |
| Voila, vous pouvez maintenant presser le bouton et voir la LED HeartBeat changer d'état à chaque pression. | | Voila, vous pouvez maintenant presser le bouton et voir la LED HeartBeat changer d'état à chaque pression. |
| | | |
− | Nous avons utilisé l'option {{fname|0=trigger=Pin.IRQ_FALLING}} car l'entrée est configurée en Pull-Up. L'entrée GP8 est donc continuellement au niveau haut... et passe au niveau bas lorsque l'on presse sur le bouton poussoir. Il faut donc détecter le flanc descendant du signal. | + | Nous avons utilisé l'option {{fname|1=trigger=Pin.IRQ_FALLING}} car l'entrée est configurée en Pull-Up. L'entrée GP8 est donc continuellement au niveau haut... et passe au niveau bas lorsque l'on presse sur le bouton poussoir. Il faut donc détecter le flanc descendant du signal. |
| + | |
| + | Tel que définit ci-avant, il est possible de déclencher la fonction callback directement |
| + | <syntaxhighlight lang="python"> |
| + | # Appel direct de la fonction callback |
| + | i() |
| + | </syntaxhighlight> |
| + | |
| + | Une interruption peut également être désactivée avec {{i.disable()}} et réactivée avec {{i.enable()}}. |
| + | |
| + | === Déparasitage des boutons === |
| + | Vous aurez certainement remarqué que, suivant les cas, la LED heartbeat change d'état une ou plusieurs fois même si vous pressez une seule fois le bouton. |
| + | |
| + | Cela arrive souvent avec les boutons mécaniques où le contact n'est pas franc mais passer pas une phase transitoire avec plusieurs rebond avant le contact définitif. |
| + | |
| + | [[Fichier:Switchbounce.jpg|480px]]<small><br />Exemple de contact parasite lors du relâchement d'un bouton.<br />Le même phénomène se produit lorsque le bouton est pressé.</small> |
| + | |
| + | Ce sont ces rebonds qui déclenchent plusieurs fois l'interruption. |
| + | |
| + | == Déparasitage des boutons == |
| + | Il y a différentes techniques de déparasitages. Si vous utilisez les interruptions & callback, vous aurez besoin d'utiliser une méthode de déparasitage matérielle. |
| + | * [http://wiki.mchobby.be/index.php?title=Entr%C3%A9e_Bouton#D.C3.A9parasitage_des_boutons Déparasitage des boutons pour Arduino] (information utile en tous les cas) |
| + | * [http://www.eng.utah.edu/~cs5780/debouncing.pdf http://www.eng.utah.edu/~cs5780/debouncing.pdf] (''anglais'') - document très intéressant avec explications détaillées et différentes techniques de déparasitage. |
| + | |
| + | === déparasitage logiciel === |
| + | Si vous avez lisez l'état du bouton dans votre programme, vous pourrez utiliser une méthode de déparasitage logiciel comme celle-ci utilisé ci-dessous. |
| + | |
| + | <font color="red">Nous avons créé une classe {{fname|PullUpButton}} qui fait du déparasitage logiciel sur une entrée équipée d'un bouton avec résistance pull-up. Cette classe est stockée dans le fichier '''debounce.py'''</font> |
| + | |
| + | Vous pouvez télécharger le fichier '''debounce.py''' et le placer directement dans le répertoire {{fname|/flash/lib/}} de votre WiPy. |
| + | |
| + | {{download-box|Téléchargez debounce.py|http://df.mchobby.be/wipy/debounce.py}} |
| + | |
| + | [[Fichier:Hack-wipy-button-debounce.jpg|800px]] |
| + | |
| + | Voici comment exploiter la classe {{fname|PullUpButton}}, cet exemple attends que le bouton soit presser 5x pour sortir de la boucle de comptage. |
| + | |
| + | <syntaxhighlight lang="python"> |
| + | from debounce import PullUpButton |
| + | import time |
| + | |
| + | btn = PullUpButton( 'GP8' ) |
| + | |
| + | counter=0 |
| + | while counter < 5: |
| + | print( 'presser le bouton svp' ) |
| + | while not btn.is_pressed(): |
| + | time.sleep_ms( 100 ) |
| + | counter=counter+1 |
| + | print( 'counter = %i' % counter ) |
| + | </syntaxhighlight> |
| + | |
| + | ce qui produit le résultat suivant après '''exactement''' 5 pressions physiques sur le bouton... les rebonds de contact ne viennent plus nous importuner. |
| + | |
| + | <nowiki>presser le bouton svp |
| + | counter = 1 |
| + | presser le bouton svp |
| + | counter = 2 |
| + | presser le bouton svp |
| + | counter = 3 |
| + | presser le bouton svp |
| + | counter = 4 |
| + | presser le bouton svp |
| + | counter = 5</nowiki> |
| + | |
| + | ==== Classe PullUpButton ==== |
| + | Pour les plus curieux, voici l'implémentation de la classe {{fname|PullUpButton}} que vous trouverez dans le fichier {{fname|debounce.py}}. |
| + | |
| + | Vous pouvez clairement y voir une seconde relecture de l'entrée après un délais de 10 millisecondes. C'est là qu'intervient le déparasitage logicielle de l'entrée. |
| + | |
| + | <syntaxhighlight lang="python"> |
| + | from machine import Pin |
| + | import time |
| + | |
| + | class PullUpButton: |
| + | """ Classe pour gérer un bouton pull-up sur une broche X. |
| + | Détecte lorsque la broche passe à 0 """ |
| + | p = None # Pin object |
| + | state = None # Last known state |
| + | |
| + | def __init__( self, button_pin ): |
| + | self.p = Pin( button_pin, Pin.IN, pull=Pin.PULL_UP ) |
| + | self.state = self.p.value() |
| + | |
| + | def is_pressed(self): |
| + | """ vérifie si le bouton est pressé / détecte le changement |
| + | d'état. Ne sera signalé qu'une seule fois! """ |
| + | val = self.p.value() |
| + | result = False |
| + | if val != self.state: |
| + | # relecture dans 10 ms (deboucing) |
| + | time.sleep_ms( 10 ) |
| + | val2 = self.p.value() |
| + | if val == val2: # valeur stable :) |
| + | self.state = val |
| + | result = (val == 0) # Is pressed |
| + | return result |
| + | </syntaxhighlight> |
| | | |
| {{HACK-WIPY-TRAILER}} | | {{HACK-WIPY-TRAILER}} |