Header Ads

Micro Python: utilisation des boutons

Le pyboard dispose de 2 petits boutons, libellés USR et RST. Le bouton RST (reset) est un bouton de réinitialisation matérieln, s'il est prssé alors la carte pyboard redémarre entièrement (équivalent d'une mise hors tension suivit d'une remise sous tension).
Micro Python PyBoard: le microcontroleur qui
se programme nativement en python

Le bouton USR (user, soit utilisateur) est un bouton destiné à votre usage personnel. Il est contrôlé par l'intermédiaire de l'objet Switch. Ecrivez le code suivant pour créer un objet Switch:
>>> sw = pyb.Switch()
Souvenez-vous qu'il faut taper import pyb si vous obteniez une erreur vous informant que le nom pyb n'existe pas.
Grâce à l'objet switch vous pouvez obtenir le statut du bouton:
>>> sw()
False
Qui affiche False si le bouton n'est pas pressé ou True si le bouton est pressé. Essayez de maintenir le bouton enfoncé pendant l'exécution de la commande ci-dessus.

Callback bouton
Qu'est-ce qu'un callback?
En informatique, une fonction de rappel (callback en anglais) ou fonction de post-traitement est une fonction qui est passée en argument à une autre fonction. Cette dernière peut alors faire usage de cette fonction de rappel comme de n'importe quelle autre fonction, alors qu'elle ne la connaît pas par avance.
Source: Fonction de rappel sur Wikipedia
L'objet switch  
switch est un terme anglais signifiant "bouton" ou "interrupteur". Nous disions donc que le switch est un objet vraiment très simple mais il dispose également d'une fonctionnalité avancée: la fonction sw.callback(). La fonction callback permet de mettre en place quelque-chose à exécuter lorsque le bouton est pressé (et utilise une interruption). Le mieux, c'est de partir de l'exemple ci-dessus pour comprendre comment les interruptions fonctionnent.
Essayez d'exécuter le code suivant sur l'invite de commande:
>>> sw.callback(lambda:print('bouton enfonce!'))
Qui informe le bouton qu'il doit imprimer un message 'bouton enfonce!' à chaque fois que le bouton est enfoncé. Faites un essai: pressez le bouton USR et regardez le message qui apparait sur la sortie de votre PC.
Notez que cet affichage interrompera tout ce que vous tapez. Ceci est un exemple de routine d'interruption qui s'exécute de façon asynchrone.
Un autre exemple à essayer:
>>> sw.callback(lambda:pyb.LED(1).toggle())
Dans cet exemple, le callback inverse (toggle) l'état de la LED rouge à chaque fois que le bouton est pressé. Et cela fonctionnera aussi pendant qu'un autre code s'exécute.

Vous pouvez passer n'importe quelle fonction (qui prend 0 arguments) en tant que fonction callback pour le switch. Ci-dessus, nous utilisons la fonctionnalité lambda (expression lambda) de Python, cela permet de créer une fonction anonyme (sans nom) à la volée. Mais vous pourriez également faire ceci:
>>> def f():
...   pyb.LED(1).toggle()
...
>>> sw.callback(f)
Ce bout de code crée une fonction appelée f et l'utilise somme fonction callback pour le switch. Vous pouvez utiliser cette methode lorsque le code de la fonction de rappel est plus compliqué que ce que autorise les expressions lambda.

Les interruptions: détails techniques

Abordons ensemble les détails de ce qui se passe avec la fonction de rappel (callback) du switch. Lorsque vous enregistrez une fonction avec sw.callback(), l'objet switch configure le déclenchement d'une interruption (falling edge sur le flanc descendant du signal) sur la broche à laquelle est attaché le bouton utilisateur. Cela signifie que le microcontroleur surveillera les changements d'état de la broche, et voici ce qu'il se passe:
  1. Lorsque le bouton (switch) est pressé, il y a un changement de signal sur la broche (la broche passe du niveau BAS au niveau HAUT) et le microcontroleur détecte ce changement.
  2. Le microcontroleur termine l'exécution de l'instruction machine en cours, stop l'exécution du programme et sauve son état actuel (pousse l'état des registres sur la pile). Cela à pour éffet de suspendre l'exécution de votre code (par exemple for example your running Python script.
  3. Le microcontroleur commence à exécuter le code de gestion de l’interruption (cela s'appelle "interrupt handler") associé avec le bouton poussoir. Le code de gestion de l'interruption retrouve la fonction que vous avez enregistré à l'aide sw.callback() et l'exécute.
  4. La fonction de rappel (callback) est exécutée jusqu'à sa fin, puis retourne le contrôle de l'exécution au code de gestion de l'interruption (interrupt handler).
  5. Le code de gestion de l'interruption termine son exécution et le microcontrôleur est notifié qu'il à a traité l'interruption.
  6. Le microcontroleur restaure l'état sauvé à l'étape 2.
  7. Le code qui était en cours d'exécution au moment de l'interruption reprend son court. A part "la pause" le programme est incapable de savoir qu'il y a eu une interruption.
La séquence d'événement décrite ci-dessus est un peu plus compliqué lorsque plusieurs interruptions arrivent en même temps. Dans ce cas, l'interruption avec la plus haute priorité est exécutée d'abord, puis les autres dans leur ordre de priorité. L'interruption du bouton (switch) est configuré avec la priorité la plus basse.

Brancher un bouton
Utiliser le bouton de la carte c'est bien... mais brancher son propre bouton c'est mieux
Brancher
Brancher un bouton sur PyBoard. Source: Tutoriel MCHobby
Pour ce montage, nous utilisons un bouton poussoir (disponible ici) avec un empattement de 2.54mm.
Ce bouton servira à ramener le potentiel de la broche Y10 à la masse (0 volts). Notez le raccordement sur le bouton, cette façon de procéder permet d'utiliser un bouton de ce type dans tous les sens ;-).
Il n'y a pas d'autres raccordements... nous allons utiliser une fonctionnalité du microcontrôleur STM. En effet, en activant une broche en entrée, il est possible d'indiquer au microcontroleur qu'il faut activer la résistance Pull-Up. Cette résistance Pull-UP (interne au microcontroleur) ramène le potentiel de la broche au niveau haut. Donc, sans aucun branchement, cette broches est naturellement au niveau logique 1 (haut).
Il nous restera alors a utiliser un dispositif (comme un bouton, switch magnétique ou autre type d'interrupteur... même un bout de fil) pour forcer le potentiel à la masse.
C'est un jeu d'enfant, simple et marche super bien.
Si vous désirez plus d'information à propos des boutons, résistances pull-up, pull-down, vous pouvez consulter l'article que nous avons écrit sur notre Blog.

Le code 
Le petit bout de code ci-dessous surveille l'état de la broche Y10. Lorsque le bouton est enfoncé, la broche passe au niveau bas (ramené à la masse, donc la valeur 0) et le programme inverse l'état de la LED rouge de la carte.

import pyb
# Configure la broche en entree avec PULL_UP interne
# La Pull_up ramène automatiquement le potentiel de la
# broche au niveau haut.
btn = pyb.Pin( 'Y10', pyb.Pin.PULL_UP )

# boucle infinie
while True:
   # lorsque le bouton est enfonce le potentiel de
   # la broche est forcé a la masse (niveau bas)
   if btn.value() == 0:
      # changer l'état de la LED 1 (rouge)
      pyb.LED(1).toggle()
   pyb.delay( 500 )

Tutoriel
Vous trouverez bien d'autres information sur Micro Python Pyboard dans les tutoriels de Micro Python de MCHobby.
Notre tutoriel sur le branchement bouton contient d'ailleurs quelques informations complémentaires.

Où Acheter
Très engagé dans les projets innovateurs et open-source, MC Hobby propose aujourd'hui une gamme Micro Python.
Vous y trouverez: