Arduino,Les micros contrôleurs Création d’une librairie de gestion des boutons

Création d’une librairie de gestion des boutons


1. Objectif

L’objectif de ce tutoriel sera double :

  1. Comment créer et mettre en place une librairie que l’on pourra réutiliser dans nos projets
  2. Créer une librairie de gestion des boutons

En effet, il est souvent souhaitable de transférer une partie de code qui nous semble fini et surtout réutilisable. Il existe en C++ la possibilité de réaliser des librairies, nous en consommons tous qui peuvent être téléchargé et installé dans l’IDE arduino. Nous allons donc voir comment réaliser une librairie et comment l’installer sur notre environnement de travail Arduino.

Afin de remplir ce premier objectif, nous allons réaliser une librairie concrète. Dans nos projets Arduino, nous utilisons souvent de boutons poussoir, il en existe de différentes formes. En informatique, nous pouvons utiliser ce que l’on appel des événements, ces événements permettent de lancer des actions (vos méthodes) quand des états interviennent (Etat de la souris par exemple). Il existe tout une gamme d’événements dont nous détaillerons la liste pour des boutons. L’objectif est donc de réaliser une librairie de gestion de boutons. Il sera possible de gérer plusieurs boutons.

A propos du code source :

Vous remarquerez que j’attache la plus grande importance à commenter mon code. Un code bien commenté, c’est un code mieux compris. Malgrès tout dans ce tutoriel, je détaillerai certaines notions clés.

1. Pré requis

a. Connaissance utile :

Nous allons ici utiliser des notions avancé de programmation. En C++ nous réalisons de la programmation objet. Ici, il sera utile d’avoir les notions de base de la programmation objet. Savoir la différence entre private, public, ..  En effet, nottre librairie va nous permettre de déclarer un objet ManageButton qui permettra la gestion des boutons.

 

3. Matériel utilisé

  • 1 Arduino Nano
  • 1 bouton poussoir
  • 1 résistances de 10K Ohms.
  • Quelques cables : 2 rouges, 1 bleu et 1 noir.

4. Schéma

5. La librairie button

Le but étant de réaliser une librairie, nous allons dans un premier temps expliquer comment cela se passe en C++, comment il faut découper son code, puis dans un second temps nous verrons ce qui doit être produit dans la librairie button.

a. Notions sur les librairies

une librairie est stocké dans 2 fichiers dont les extensions sont respectivement .h et .cpp.

1.Le fichier .h

Un fichier .h contient la description de la librairie également appelé les prototypes de nos objets. On peut y ajouter les inclusions d’autres librairies, la déclaration de constantes, d’énumération, de structures et d’objets. Pour la déclaration d’objets, seront décrit les prototypes (Signature) de chacun méthode, propriété et variable membre. Celles ci, regroupé sous différents label suivant la porté des méthodes. Pour rappel :

  • private signifie que la porté se limite à l’intérieur de l’objet (Les variables ou méthodes ne seront connu que dans l’objet lui même)
  • protected signifie que la porté se limite à la class ainsi qu’à ses enfants (S’il y a héritage).
  • public signifie que la porté sera globale.

Vous noterez que je nomme toujours mes variables avec des préfixes :

  • m_ pour les membres
  • p_ pour les paramètres de méthodes
  • v_ pour les variables locales.

Cette notation me permet de produire un code plus lisible et plus simple à comprendre. En effet, du premier coup d’œil on peut identifier la porté d’une variable.

2. Le fichier .cpp

Le fichier .cpp est tout simplement l’implémentation des différentes définitions réalisées dans le fichier .h

b.Contenu de la librairie button

Il y a pas mal de chose à dire ici. Je vais essayer de décrire l’essentiel et de ne pas vous collez un mal de crâne ;). Néanmoins, pour une bonne compréhension, nous devons voir et expliquer ce que l’on souhaite réaliser. Parler un peu d’algorithmie puisqu’il va falloir coder ces concepts.

1. Cahier des charges

La librairie devra permettre de gérer un ou plusieurs boutons poussoirs dont on souhaite pouvoir connaitre l’état. Evidemment un bouton ne possède que deux états de base :

  • relâché (release)
  • enfoncé (press)

Néanmoins, en informatique on connait d’autres états de boutons qui sont lié à l’enchaînement de ces deux états de base : Le clic, le double clic, … Nous souhaitons donc pouvoir gérer tous ces autres états sachant que certains se combinerons : Si je press et que je relache rapidement un bouton, l’état de relâchement sera actionné mais également l’état de clic. Cela veut dire qu’instantanément, un bouton peut avoir plusieurs états.

Voici la liste des états que l’on souhaite avoir :

  • Change : permet de savoir si l’état du bouton change.
  • Up : permet de savoir si le bouton est relâché.
  • Press : permet de savoir si le bouton est en cours pression.
  • Release : permet de savoir s’il n’y a aucune activité sur le bouton.
  • Clic : permet de savoir si le bouton a été pressé puis relâché dans un temps imparti.
  • Double clic : permet de savoir si le bouton a réalisé 2 clic successivement dans un temps imparti
  • clic moyen : permet de savoir si le bouton a réalisé un clic dont on est resté appuyé un temps imparti supérieur au temps du clic et inférieur au temps du clic long
  • clic long : permet de savoir si le bouton a réalisé un clic dont on est resté appuyé un temps imparti supérieur au temps du clic moyen

Nous voyons ici qu’il y a des notions de temporalité qui on leur importance. En effet, en fonction de temps de pression les états peuvent être différents. Il faut également noter qu’un état en lui même se doit de durer un certain temps.

2. Algorithmie

a. Les états

Afin de gérer les états multiples d’un bouton (également simultanément), nous allons utiliser directement les notions les plus fondamentales. En effet, un octet est composé de bits. Nous pouvons stocker sur un octet différents états simultanément en choisissant les bits sur lesquels on stock un état.

[pastacode lang= »cpp » manual= »%2F*%0ABit%200%20-%3E%200%20%3A%20release%2C%201%20%3A%20OnPressed.%0ABit%201%20-%3E%200%20%3A%20release%2C%201%20%3A%20OnUp.%0ABit%202%20-%3E%200%20%3A%20ras%2C%201%20%3A%20OnClick.%0ABit%203%20-%3E%200%20%3A%20ras%2C%201%20%3A%20OnDblClick.%0ABit%204%20-%3E%200%20%3A%20ras%2C%201%20%3A%20OnMediumClick.%0ABit%205%20-%3E%200%20%3A%20ras%2C%201%20%3A%20OnLongClick.%0ABit%206%20-%3E%200%20%3A%20Pas%20de%20changement%2C%201%20%3A%20changement%20d’%C3%A9tat(s)%0A*%2F%0Aenum%20mask%0A%7B%0A%09PRESSEDMASK%20%3D%201%2C%0A%09UPMASK%20%3D%202%2C%0A%09CLICKMASK%20%3D%204%2C%0A%09DBLCLICKMASK%20%3D%208%2C%0A%09MEDIUMCLICKMASK%20%3D%2016%2C%0A%09LONGCLICKMASK%20%3D%2032%2C%0A%09CHANGEMASK%20%3D%2064%0A%7D%3B » message= »Extrait de button.h permettant de gérer les états » highlight= » » provider= »manual »/]

Ensuite, en utilisant des masques, il est possible de savoir si l’état est activé ou non.

[pastacode lang= »cpp » manual= »bool%20ManageButton%3A%3AHasStatus(byte%20p_status%2C%20byte%20p_mask)%0A%7B%0A%09return%20(p_status%20%26%20p_mask)%20%3D%3D%20p_mask%3B%0A%7D » message= »Extrait de button.cpp qui permet savoir si un état est activé ou non » highlight= » » provider= »manual »/]

Il est également possible modifier les états avec ces mêmes masques

[pastacode lang= »cpp » manual= »void%20ManageButton%3A%3ASetToStatus(byte%20%26p_status%2C%20byte%20p_mask)%0A%7B%0A%09p_status%20%3D%20p_status%20%7C%20p_mask%3B%0A%7D%0A%0Avoid%20ManageButton%3A%3AUnSetToStatus(byte%20%26p_status%2C%20byte%20p_mask)%0A%7B%0A%09p_status%20%3D%20p_status%20%26%20(255%20%5E%20p_mask)%3B%0A%7D » message= »Extrait de button.cpp permet de modifier les états. » highlight= » » provider= »manual »/]

b. L’automate.

Nous avons vu qu’une notion temporelle intervient. Il faut stocker des états intermédiaires nous permettant d’atteindre d’autres états. En effet, pour réaliser  un double clic par exemple, il faut avoir déjà effectué un clic qu’il faut avoir mémorisé. Nous avons vu que dans le cahier des charges ces états, que l’on va appeler événements seront déclenché selon des temporalités établi.

[pastacode lang= »cpp » manual= »%23define%20LISTENDELAY%09%09%0910%09%09%2F%2F%20D%C3%A9lai%20minimum%20pour%20r%C3%A9aliser%20des%20actions%20li%C3%A9%20au%20bouton.%0A%23define%20REBOUNDDELAY%09%09400%09%09%2F%2F%20D%C3%A9lai%20minimun%20pour%20annuler%20l’action%20pr%C3%A9c%C3%A9dente.%0A%23define%20MEDIUMREBOUNDDELAY%091000%09%2F%2F%20D%C3%A9lai%20m%C3%A9dian%20pour%20une%20action%20m%C3%A9dian.%0A%23define%20LONGREBOUNDDELAY%093000%09%2F%2F%20D%C3%A9lai%20long%20pour%20une%20action%20longue.%0A%23define%20DBLCLICKDELAY%09%09600%09%09%2F%2F%20D%C3%A9lai%20pour%20r%C3%A9aliser%20un%20double%20clic. » message= »Extrait de button.h, liste des temporalités » highlight= » » provider= »manual »/]

afin de gérer cet enchaînement d’état, nous devons utiliser un automate (vous pouvez aller voir ce lien pour en comprendre un peu plus). Cet automate nous permettra de garantir l’enchaînement des actions et donc la cohérence des différents états mis en place. Cette automate sera stocké dans une méthode appelé Listen puisqu’elle sera la méthode a appeler dans le loop afin « d’écouter » les différents bouton.

Je vous passe l’explication détaillé de la méthode Listen (C’est celle ci qui peut vous donner un bon mal de crâne).

3.Contenu du fichier .h

Vous allez retrouver les différents points déjà abordé auxquels vont venir s’ajouter la structure de bouton. En effet comme nous devons gérer un automate et des notions de temporalité, il nous faut pour chaque bouton stocker différentes informations qui seront dans cette structure.

Dans les méthodes, il nous une méthode Add afin de rajouter des boutons.

Nous avons également un ensemble de méthode On et Is qui permettent de savoir si un état est actionné ou non. Ces méthodes sont rendus simplissime par le fait que l’ensemble des états sont stockés dans l’octet qui est modifié dans la méthode Listen.

[pastacode lang= »cpp » manual= »%2F*%20Button.h%0APar%20S%C3%A9bastien%20DELAPORTE%20Mai%202016%0Alicence%20GNU%20GPL%20https%3A%2F%2Ffr.wikipedia.org%2Fwiki%2FLicence_publique_g%25C3%25A9n%25C3%25A9rale_GNU%0A*%2F%0A%23if%20defined(ARDUINO)%20%26%26%20ARDUINO%20%3E%3D%20100%0A%09%23include%20%22arduino.h%22%0A%23else%0A%09%23include%20%22WProgram.h%22%0A%23endif%0A%0A%23define%20LISTENDELAY%09%09%0910%09%09%2F%2F%20D%C3%A9lai%20minimum%20pour%20r%C3%A9aliser%20des%20actions%20li%C3%A9%20au%20bouton.%0A%23define%20REBOUNDDELAY%09%09400%09%09%2F%2F%20D%C3%A9lai%20minimun%20pour%20annuler%20l’action%20pr%C3%A9c%C3%A9dente.%0A%23define%20MEDIUMREBOUNDDELAY%091000%09%2F%2F%20D%C3%A9lai%20m%C3%A9dian%20pour%20une%20action%20m%C3%A9dian.%0A%23define%20LONGREBOUNDDELAY%093000%09%2F%2F%20D%C3%A9lai%20long%20pour%20une%20action%20longue.%0A%23define%20DBLCLICKDELAY%09%09600%09%09%2F%2F%20D%C3%A9lai%20pour%20r%C3%A9aliser%20un%20double%20clic.%0A%0A%2F*%0ABit%200%20-%3E%200%20%3A%20release%2C%201%20%3A%20OnPressed.%0ABit%201%20-%3E%200%20%3A%20release%2C%201%20%3A%20OnUp.%0ABit%202%20-%3E%200%20%3A%20ras%2C%201%20%3A%20OnClick.%0ABit%203%20-%3E%200%20%3A%20ras%2C%201%20%3A%20OnDblClick.%0ABit%204%20-%3E%200%20%3A%20ras%2C%201%20%3A%20OnMediumClick.%0ABit%205%20-%3E%200%20%3A%20ras%2C%201%20%3A%20OnLongClick.%0ABit%206%20-%3E%200%20%3A%20Pas%20de%20changement%2C%201%20%3A%20changement%20d’%C3%A9tat(s)%0A*%2F%0Aenum%20mask%0A%7B%0A%09PRESSEDMASK%20%3D%201%2C%0A%09UPMASK%20%3D%202%2C%0A%09CLICKMASK%20%3D%204%2C%0A%09DBLCLICKMASK%20%3D%208%2C%0A%09MEDIUMCLICKMASK%20%3D%2016%2C%0A%09LONGCLICKMASK%20%3D%2032%2C%0A%09CHANGEMASK%20%3D%2064%0A%7D%3B%0A%0A%2F%2F%20Structure%20d’un%20bouton%0Astruct%20Button%20%7B%09%09%09%09%09%09%09%0A%09byte%20Pin%3B%09%09%09%09%09%09%09%2F%2F%20Pin%20sur%20lequel%20le%20bouton%20est%20cabl%C3%A9.%0A%09byte%20Status%3B%09%09%09%09%09%09%2F%2F%20Statut%20courant%0A%09bool%20IsPreviousClick%3B%09%09%09%09%2F%2F%20Avons%20nous%20d%C3%A9j%C3%A0%20un%20click%20pour%20r%C3%A9aliser%20une%20double%20%3F%0A%09byte%20CurrentValue%3B%09%09%09%09%09%2F%2F%20Valeur%20captur%C3%A9e%20du%20bouton.%0A%09unsigned%20int%20PressTime%3B%09%09%09%09%2F%2F%20Temps%20auquel%20le%20bouton%20est%20press%C3%A9.%0A%09unsigned%20int%20ReleaseTime%3B%09%09%09%2F%2F%20Temps%20auquel%20le%20bouton%20est%20relach%C3%A9.%0A%7D%3B%0A%0Aclass%20ManageButton%0A%7B%0Aprivate%3A%0A%09unsigned%20long%20int%20m_currentTime%3B%09%2F%2F%20D%C3%A9lai%20en%20milliseconde%20depuis%20le%20d%C3%A9marrage%20de%20l’arduino%2C%20captur%C3%A9%20lors%20de%20l’%C3%A9coute%20du%20statut%20du%20bouton.%0A%09unsigned%20long%20int%20m_previousTime%3B%09%2F%2F%20D%C3%A9lai%20en%20milliseconde%20depuis%20le%20d%C3%A9marrage%20de%20l’arduino%2C%20captur%C3%A9%20lors%20de%20la%20pr%C3%A9c%C3%A9dente%20%C3%A9coute%20du%20statut%20du%20bouton.%0A%0A%09Button%20*m_btnList%3B%09%09%09%09%09%2F%2F%20Liste%20des%20boutons.%0A%09byte%20m_nbButton%3B%09%09%09%09%09%2F%2F%20Nombre%20de%20bouton%0A%09%0A%09void%20SetToStatus(byte%20%26p_status%2C%20byte%20p_mask)%3B%09%09%2F%2F%20Ajoute%20au%20statut%20p_status%20le%20mask%20p_mask.%0A%09void%20UnSetToStatus(byte%20%26p_status%2C%20byte%20p_mask)%3B%09%2F%2F%20Retire%20au%20statut%20p_status%20le%20mask%20p_mask.%0A%09bool%20HasStatus(byte%20p_status%2C%20byte%20p_mask)%3B%09%09%09%2F%2F%20V%C3%A9rifie%20si%20le%20statut%20p_status%20poss%C3%A8de%20le%20mask%20p_mask.%0Apublic%3A%0A%09%2F%2F%20Constructeurs%0A%09ManageButton(byte%20p_pin)%3B%0A%09%09%0A%09%2F%2F%20Methodes%0A%09void%20Add(byte%20p_pin)%3B%09%09%09%09%2F%2F%20Ajoute%20un%20bouton%20%C3%A0%20la%20gestion%20des%20boutons%0A%09byte%20GetStatus(byte%20p_btn%20%3D%201)%3B%09%09%2F%2F%20Demande%20le%20statut%20du%20bouton%20p_btn.%0A%09void%20listen(void)%3B%09%09%09%09%09%2F%2F%20M%C3%A9thode%20d’%C3%A9coute%20de%20l’%C3%A9tat%20des%20boutons.%0A%09void%20Release(byte%20p_btn%20%3D%201)%3B%09%09%2F%2F%20Force%20la%20remise%20au%20status%20de%20repos%20d’un%20bouton.%0A%09bool%20OnChange(byte%20p_btn%20%3D%201)%3B%09%09%2F%2F%20Est%20ce%20que%20le%20bouton%20p_btn%20est%20changement%20d’%C3%A9tat%20%3F%0A%09bool%20OnUp(byte%20p_btn%20%3D%201)%3B%09%09%09%2F%2F%20Est%20ce%20que%20le%20bouton%20p_btn%20est%20en%20cours%20relachement%20%3F%0A%09bool%20OnPress(byte%20p_btn%20%3D%201)%3B%09%09%2F%2F%20Est%20ce%20que%20le%20bouton%20p_btn%20est%20en%20cours%20pression%20%3F%0A%09bool%20OnRelease(byte%20p_btn%20%3D%201)%3B%09%09%2F%2F%20Est%20ce%20que%20le%20bouton%20p_btn%20est%20relach%C3%A9%20%3F%0A%09bool%20OnClick(byte%20p_btn%20%3D%201)%3B%09%09%2F%2F%20Est%20ce%20que%20le%20bouton%20p_btn%20a%20effectu%C3%A9%20un%20simple%20clic%20%3F%0A%09bool%20OnDblClick(byte%20p_btn%20%3D%201)%3B%09%2F%2F%20Est%20ce%20que%20le%20bouton%20p_btn%20a%20effectu%C3%A9%20un%20double%20clic%20%3F%0A%09bool%20OnMediumClick(byte%20p_btn%20%3D%201)%3B%09%2F%2F%20Est%20ce%20que%20le%20bouton%20p_btn%20a%20effectu%C3%A9%20un%20clic%20moyennement%20long%20%3F%0A%09bool%20OnLongClick(byte%20p_btn%20%3D%201)%3B%09%2F%2F%20Est%20ce%20que%20le%20bouton%20p_btn%20a%20effectu%C3%A9%20un%20clic%20long%20%3F%0A%09bool%20IsPressed(byte%20p_btn%20%3D%201)%3B%09%09%2F%2F%20Est%20ce%20que%20le%20bouton%20p_btn%20est%20press%C3%A9%20%3F%0A%09bool%20IsUp(byte%20p_btn%20%3D%201)%3B%09%09%09%2F%2F%20Est%20ce%20que%20le%20bouton%20p_btn%20est%20relach%C3%A9%20%3F%0A%7D%3B » message= »librairie button.h » highlight= » » provider= »manual »/]

4.Contenu du fichier .cpp

l’implémentation de la librairie préalablement défini dans le fichier .h

[pastacode lang= »cpp » manual= »%2F*%0AAuthor%20%3A%20S%C3%A9bastien%20DELAPORTE%20%09%0ADate%20%3A%2005%2F2016%0AVersion%20%3A%200.9.1%0A*%2F%0A%0A%23include%20%22Button.h%22%0A%0A%2F%2F%20Constructors%0AManageButton%3A%3AManageButton(byte%20p_pin)%0A%7B%0A%09this-%3Em_nbButton%20%3D%201%3B%0A%09this-%3Em_btnList%20%3D%20(Button%20*)malloc(m_nbButton%20*%20sizeof(Button))%3B%0A%09this-%3Em_btnList%5B0%5D.Pin%20%3D%20p_pin%3B%0A%09this-%3Em_btnList%5B0%5D.Status%20%3D%200%3B%0A%09this-%3Em_btnList%5B0%5D.PressTime%20%3D%200%3B%0A%09this-%3Em_btnList%5B0%5D.ReleaseTime%20%3D%200%3B%0A%09pinMode(this-%3Em_btnList%5B0%5D.Pin%2C%20INPUT)%3B%0A%7D%0A%0Avoid%20ManageButton%3A%3AAdd(byte%20p_pin)%0A%7B%0A%09this-%3Em_nbButton%2B%2B%3B%0A%09realloc(this-%3Em_btnList%2C%20m_nbButton%20*%20sizeof(Button))%3B%0A%09this-%3Em_btnList%5Bm_nbButton%20-%201%5D.Pin%20%3D%20p_pin%3B%0A%09this-%3Em_btnList%5Bm_nbButton%20-%201%5D.Status%20%3D%200%3B%0A%09this-%3Em_btnList%5Bm_nbButton%20-%201%5D.PressTime%20%3D%200%3B%0A%09this-%3Em_btnList%5Bm_nbButton%20-%201%5D.ReleaseTime%20%3D%200%3B%0A%09pinMode(this-%3Em_btnList%5Bm_nbButton%20-%201%5D.Pin%2C%20INPUT)%3B%0A%7D%0A%0Avoid%20ManageButton%3A%3ASetToStatus(byte%20%26p_status%2C%20byte%20p_mask)%0A%7B%0A%09p_status%20%3D%20p_status%20%7C%20p_mask%3B%0A%7D%0A%0Avoid%20ManageButton%3A%3AUnSetToStatus(byte%20%26p_status%2C%20byte%20p_mask)%0A%7B%0A%09p_status%20%3D%20p_status%20%26%20(255%20%5E%20p_mask)%3B%0A%7D%0A%0Abool%20ManageButton%3A%3AHasStatus(byte%20p_status%2C%20byte%20p_mask)%0A%7B%0A%09return%20(p_status%20%26%20p_mask)%20%3D%3D%20p_mask%3B%0A%7D%0A%0Avoid%20ManageButton%3A%3ARelease(byte%20p_btn)%0A%7B%0A%09byte%20v_newStatus%20%3D%200%3B%0A%09SetToStatus(v_newStatus%2C%20CHANGEMASK)%3B%0A%09this-%3Em_btnList%5Bp_btn%20-%201%5D.Status%20%3D%20v_newStatus%3B%0A%7D%0A%0Avoid%20ManageButton%3A%3Alisten(void)%0A%7B%0A%09%2F%2F%20Sauvegarde%20temporelle%0A%09this-%3Em_previousTime%20%3D%20this-%3Em_currentTime%3B%09%09%2F%2F%20On%20sauvegarde%20l’ancienne%20capture%20temporelle%09%09%09%09%09%09%09%09%09%09%09%09%0A%09this-%3Em_currentTime%20%3D%20millis()%3B%09%09%09%09%09%09%09%09%09%2F%2F%20Capture%20du%20nombre%20de%20millisecondes%0A%09%2F%2F%20Algo%20de%20recherche%20du%20statut%0A%09if%20(this-%3Em_currentTime%20-%20this-%3Em_previousTime%20%3E%3D%20LISTENDELAY)%09%2F%2F%20Il%20est%20possible%20de%20modier%20le%20statut%20dans%20ce%20cas%0A%09%7B%0A%09%09for%20(int%20i%20%3D%200%3B%20i%20%3C%20this-%3Em_nbButton%3B%20i%2B%2B)%0A%09%09%7B%0A%09%09%09%2F%2F%20On%20va%20v%C3%A9rifier%20si%20on%20est%20en%20changement%20de%20statut%0A%09%09%09byte%20v_state%20%3D%20digitalRead(this-%3Em_btnList%5Bi%5D.Pin)%3B%0A%09%09%09if%20(this-%3Em_btnList%5Bi%5D.CurrentValue%20!%3D%20v_state)%0A%09%09%09%7B%09%2F%2F%20On%20change%20d’%C3%A9tat%0A%09%09%09%09this-%3Em_btnList%5Bi%5D.CurrentValue%20%3D%20v_state%3B%0A%09%09%09%09SetToStatus(this-%3Em_btnList%5Bi%5D.Status%2C%20mask%3A%3ACHANGEMASK)%3B%09%09%09%09%09%09%09%09%2F%2F%20Donc%20changement%20de%20statut%0A%09%09%09%09if%20(this-%3Em_btnList%5Bi%5D.CurrentValue)%0A%09%09%09%09%7B%0A%09%09%09%09%09%2F%2F%20On%20appuie%0A%09%09%09%09%09this-%3Em_btnList%5Bi%5D.PressTime%20%3D%20this-%3Em_currentTime%3B%0A%09%09%09%09%09SetToStatus(this-%3Em_btnList%5Bi%5D.Status%2C%20mask%3A%3APRESSEDMASK)%3B%09%09%09%09%09%09%09%2F%2F%20On%20met%20le%20pressed%0A%09%09%09%09%7D%0A%09%09%09%09else%0A%09%09%09%09%7B%0A%09%09%09%09%09%2F%2F%20On%20relache%0A%09%09%09%09%09this-%3Em_btnList%5Bi%5D.ReleaseTime%20%3D%20this-%3Em_currentTime%3B%0A%09%09%09%09%09SetToStatus(this-%3Em_btnList%5Bi%5D.Status%2C%20mask%3A%3AUPMASK)%3B%09%09%09%09%09%09%09%09%09%09%2F%2F%20On%20est%20donc%20en%20relachement%0A%09%09%09%09%09unsigned%20int%20v_deltaTemp%20%3D%20this-%3Em_currentTime%20-%20this-%3Em_btnList%5Bi%5D.PressTime%3B%0A%09%09%09%09%09if%20(v_deltaTemp%20%3E%3D%20LONGREBOUNDDELAY)%0A%09%09%09%09%09%7B%0A%09%09%09%09%09%09SetToStatus(this-%3Em_btnList%5Bi%5D.Status%2C%20mask%3A%3ALONGCLICKMASK)%3B%09%09%09%09%2F%2F%20On%20met%20le%20long%20click%0A%09%09%09%09%09%09this-%3Em_btnList%5Bi%5D.IsPreviousClick%20%3D%20false%3B%0A%09%09%09%09%09%7D%0A%09%09%09%09%09else%20if%20(v_deltaTemp%20%3E%3D%20MEDIUMREBOUNDDELAY%20%26%26%20%20v_deltaTemp%20%3C%20LONGREBOUNDDELAY)%0A%09%09%09%09%09%7B%0A%09%09%09%09%09%09SetToStatus(this-%3Em_btnList%5Bi%5D.Status%2C%20mask%3A%3AMEDIUMCLICKMASK)%3B%09%09%09%2F%2F%20On%20met%20le%20medium%20click%09%09%0A%09%09%09%09%09%09this-%3Em_btnList%5Bi%5D.IsPreviousClick%20%3D%20false%3B%0A%09%09%09%09%09%7D%0A%09%09%09%09%09else%20if%20(v_deltaTemp%20%3CMEDIUMREBOUNDDELAY)%0A%09%09%09%09%09%7B%0A%09%09%09%09%09%09if%20(this-%3Em_btnList%5Bi%5D.IsPreviousClick)%20%2F%2F%20Si%20on%20avait%20d%C3%A9j%C3%A0%20un%20simple%20click%20avant%0A%09%09%09%09%09%09%7B%0A%09%09%09%09%09%09%09if%20(v_deltaTemp%20%3C%3D%20DBLCLICKDELAY)%0A%09%09%09%09%09%09%09%7B%0A%09%09%09%09%09%09%09%09SetToStatus(this-%3Em_btnList%5Bi%5D.Status%2C%20mask%3A%3ADBLCLICKMASK)%3B%09%09%09%2F%2F%20On%20met%20le%20double%20click%09%09%09%09%09%09%09%0A%09%09%09%09%09%09%09%09this-%3Em_btnList%5Bi%5D.IsPreviousClick%20%3D%20false%3B%0A%09%09%09%09%09%09%09%7D%0A%09%09%09%09%09%09%7D%0A%09%09%09%09%09%09else%0A%09%09%09%09%09%09%7B%0A%09%09%09%09%09%09%09if(!HasStatus(this-%3Em_btnList%5Bi%5D.Status%2C%20mask%3A%3ADBLCLICKMASK))%0A%09%09%09%09%09%09%09%7B%0A%09%09%09%09%09%09%09%09SetToStatus(this-%3Em_btnList%5Bi%5D.Status%2C%20mask%3A%3ACLICKMASK)%3B%09%09%09%09%09%09%2F%2F%20On%20met%20le%20simple%20click%0A%09%09%09%09%09%09%09%09this-%3Em_btnList%5Bi%5D.IsPreviousClick%20%3D%20true%3B%0A%09%09%09%09%09%09%09%7D%0A%09%09%09%09%09%09%7D%0A%09%09%09%09%09%7D%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%09else%20%2F%2F%20On%20ne%20change%20pas%20d’%C3%A9tat%0A%09%09%09%7B%0A%09%09%09%09this-%3Em_btnList%5Bi%5D.CurrentValue%20%3D%20v_state%3B%0A%09%09%09%09UnSetToStatus(this-%3Em_btnList%5Bi%5D.Status%2C%20mask%3A%3ACHANGEMASK)%3B%09%09%09%09%09%09%2F%2F%20Donc%20changement%20de%20statut%0A%09%09%09%09if%20(this-%3Em_currentTime%20-%20this-%3Em_btnList%5Bi%5D.PressTime%20%3E%3D%20REBOUNDDELAY)%0A%09%09%09%09%7B%0A%09%09%09%09%09UnSetToStatus(this-%3Em_btnList%5Bi%5D.Status%2C%20mask%3A%3APRESSEDMASK)%3B%09%09%09%09%09%2F%2F%20On%20retire%20le%20relachement%0A%09%09%09%09%7D%0A%09%09%09%09if%20(this-%3Em_currentTime%20-%20this-%3Em_btnList%5Bi%5D.PressTime%20%3E%3D%20DBLCLICKDELAY)%0A%09%09%09%09%09this-%3Em_btnList%5Bi%5D.IsPreviousClick%20%3D%20false%3B%0A%09%09%09%09if%20(this-%3Em_currentTime%20-%20this-%3Em_btnList%5Bi%5D.ReleaseTime%20%3E%3D%20REBOUNDDELAY)%0A%09%09%09%09%7B%0A%09%09%09%09%09UnSetToStatus(this-%3Em_btnList%5Bi%5D.Status%2C%20mask%3A%3AUPMASK)%3B%09%09%09%09%09%09%09%09%2F%2F%20On%20retire%20le%20relachement%0A%09%09%09%09%09UnSetToStatus(this-%3Em_btnList%5Bi%5D.Status%2C%20mask%3A%3ALONGCLICKMASK)%3B%09%09%09%09%2F%2F%20On%20retire%20le%20long%20click.%0A%09%09%09%09%09UnSetToStatus(this-%3Em_btnList%5Bi%5D.Status%2C%20mask%3A%3AMEDIUMCLICKMASK)%3B%09%09%2F%2F%20On%20retire%20le%20medium%20click.%0A%09%09%09%09%09UnSetToStatus(this-%3Em_btnList%5Bi%5D.Status%2C%20mask%3A%3ADBLCLICKMASK)%3B%09%09%09%09%09%2F%2F%20On%20retire%20le%20double%20click.%0A%09%09%09%09%09UnSetToStatus(this-%3Em_btnList%5Bi%5D.Status%2C%20mask%3A%3ACLICKMASK)%3B%09%09%09%09%09%09%09%2F%2F%20On%20retire%20le%20simple%20click.%09%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A%09%7D%0A%09else%0A%09%7B%0A%09%09%2F%2F%20On%20a%20pas%20assez%20de%20d%C3%A9lai%2C%20le%20d%C3%A9lai%20courant%20reprend%20la%20valeur%20du%20pr%C3%A9c%C3%A9dent.%0A%09%09this-%3Em_currentTime%20%3D%20this-%3Em_previousTime%3B%0A%09%7D%0A%7D%0A%0Abyte%20ManageButton%3A%3AGetStatus(byte%20p_btn)%0A%7B%0A%09return%20this-%3Em_btnList%5Bp_btn%20-%201%5D.Status%3B%0A%7D%0A%0Abool%20ManageButton%3A%3AOnChange(byte%20p_btn)%0A%7B%0A%09return%20HasStatus(this-%3Em_btnList%5Bp_btn%20-%201%5D.Status%2C%20CHANGEMASK)%3B%0A%7D%0A%0Abool%20ManageButton%3A%3AOnPress(byte%20p_btn)%0A%7B%0A%09return%20HasStatus(this-%3Em_btnList%5Bp_btn%20-%201%5D.Status%2C%20mask%3A%3APRESSEDMASK)%3B%0A%7D%0A%0Abool%20ManageButton%3A%3AOnUp(byte%20p_btn)%0A%7B%0A%09return%20HasStatus(this-%3Em_btnList%5Bp_btn%20-%201%5D.Status%2C%20mask%3A%3AUPMASK)%3B%0A%7D%0A%0Abool%20ManageButton%3A%3AOnRelease(byte%20p_btn)%0A%7B%0A%09return%20this-%3Em_btnList%5Bp_btn%20-%201%5D.Status%20%3D%3D0%3B%0A%7D%0A%0Abool%20ManageButton%3A%3AOnClick(byte%20p_btn)%0A%7B%0A%09return%20HasStatus(this-%3Em_btnList%5Bp_btn%20-%201%5D.Status%2C%20mask%3A%3ACLICKMASK)%3B%0A%7D%0A%0Abool%20ManageButton%3A%3AOnDblClick(byte%20p_btn)%0A%7B%0A%09return%20HasStatus(this-%3Em_btnList%5Bp_btn%20-%201%5D.Status%2C%20mask%3A%3ADBLCLICKMASK)%3B%0A%7D%0A%0Abool%20ManageButton%3A%3AOnMediumClick(byte%20p_btn)%0A%7B%0A%09return%20HasStatus(this-%3Em_btnList%5Bp_btn%20-%201%5D.Status%2C%20mask%3A%3AMEDIUMCLICKMASK)%3B%0A%7D%0A%0Abool%20ManageButton%3A%3AOnLongClick(byte%20p_btn)%0A%7B%0A%09return%20HasStatus(this-%3Em_btnList%5Bp_btn%20-%201%5D.Status%2C%20mask%3A%3ALONGCLICKMASK)%3B%0A%7D%0A%0Abool%20ManageButton%3A%3AIsPressed(byte%20p_btn)%0A%7B%0A%09return%20this-%3Em_btnList%5Bp_btn%20-%201%5D.CurrentValue%3D%3D1%3B%0A%7D%0A%0Abool%20ManageButton%3A%3AIsUp(byte%20p_btn)%0A%7B%0A%09return%20this-%3Em_btnList%5Bp_btn%20-%201%5D.CurrentValue%20%3D%3D%200%3B%0A%7D%0A » message= »librairie button.cpp » highlight= » » provider= »manual »/]

 

6. L’installation de la librairie

Maintenant que nous avons réalisé notre librairie .h et son .cpp nous aimerions l’installer sur notre machine afin de pouvoir l’utiliser facilement dans des programmes.

Sur votre IDE arduino, dans fichier>préférence, vous pouvez l’emplacement ou sont stockées les librairie (encadré rouge).

Ce répertoire de votre machine contient un répertoire libraries qui l’ensemble des librairies installées. Il vous suffit alors créer un répertoire button et d’y déposer les deux fichiers de notre librairie (Vous faite cela lorsque c’est vous qui créez et installez la librairie).

Vous pouvez ensuite créer un fichier readme.txt dans ce même dossier pour mettre vos crédits, … Ensuite vous pouvez zipper le répertoire.

En effet sous l’IDE arduino, il est possible d’installer des librairies à partir de fichier .zip. Et voilà, le tour est joué. Vous savez comment créer et installer une librairie ainsi que la diffuser.

Vous pouvez télécharger la librairie button sur ce lien.

7. Le programme de test de la librairie.

Le montage est rudimentaire, le code tout aussi simple. Le but est d’afficher les différents statuts sur le moniteur. Ca défile un peu vite mais on peut voir les différents changements.

Sur une ligne j’affiche les différents états et sur la seconde les valeurs. O pour inactif et X pour statut actif.

[pastacode lang= »cpp » manual= »%23include%3CButton.h%3E%09%09%09%09%09%2F%2F%20Inclusion%20de%20la%20librairie%20de%20gestion%20des%20boutons.%0A%0A%23define%20BTN1%202%09%09%09%09%09%09%2F%2F%20Pin%20du%20bouton%0A%0AManageButton%20m_btns(BTN1)%3B%09%09%09%2F%2F%20Init%20de%20la%20lib%20de%20boutons%0A%0A%2F%2F%20Affichage%20du%20status%20X%20activ%C3%A9%2C%20O%20inactif.%0Avoid%20AffStatus(bool%20p_val)%0A%7B%0A%09if(p_val)%0A%09%09Serial.print(%22X%20%7C%22)%3B%0A%09else%0A%09%09Serial.print(%22O%20%7C%22)%3B%0A%7D%0A%0A%0A%2F%2F%20Affichage%20des%20diff%C3%A9rents%20status.%0Avoid%20PrintButtonStatus()%0A%7B%0A%09Serial.println(%22Ch%7CUP%7CPr%7CRe%7CCl%7CDC%7CMC%7CLC%7CIP%7CIU%7C%22)%3B%0A%09AffStatus(m_btns.OnChange())%3B%0A%09AffStatus(m_btns.OnUp())%3B%0A%09AffStatus(m_btns.OnPress())%3B%0A%09AffStatus(m_btns.OnRelease())%3B%0A%09AffStatus(m_btns.OnClick())%3B%0A%09AffStatus(m_btns.OnDblClick())%3B%0A%09AffStatus(m_btns.OnMediumClick())%3B%0A%09AffStatus(m_btns.OnLongClick())%3B%0A%09AffStatus(m_btns.IsPressed())%3B%0A%09AffStatus(m_btns.IsUp())%3B%0A%09Serial.println(%22%22)%3B%0A%7D%0A%0Avoid%20setup()%0A%7B%09%09%0A%09Serial.begin(9600)%3B%09%09%09%09%2F%2F%20On%20init%20le%20port%20s%C3%A9rie%20pour%20avoir%20une%20console.%0A%09pinMode(BTN1%2C%20INPUT)%3B%09%09%09%2F%2F%20Inputs%20%3A%20Bouton%0A%7D%0A%0Avoid%20loop()%0A%7B%0A%09m_btns.listen()%3B%09%09%09%09%2F%2F%20Permet%20de%20g%C3%A9rer%20les%20status%20des%20boutons.%0A%09PrintButtonStatus()%3B%09%09%09%2F%2F%20Affichage%20des%20diff%C3%A9rents%20status.%0A%09delay(100)%3B%0A%7D%0A » message= »testButtonLib.ino » highlight= » » provider= »manual »/]

Voyez plutôt en image.

Étiquettes : , ,

5 commentaires sur “Création d’une librairie de gestion des boutons”

  1. Bonjour, je vous écrit concernant la librairie button, bravo et merci pour votre travail, je voudrais savoir comment implémenter des boutons supplémentaire dans le fichier ino. Merci d’avance pour votre réponse et meilleures salutations

    Francis Buchwalder

  2. Bonjour M.Delaporte,

    Je teste votre bibliothèque sur une carte elegoo uno R3 pour un petit projet étudiant.

    Après avoir installé les fichiers et lancé le programme test tout fonctionne bien sur le moniteur et ce pendant une minute, après cela le moniteur n’affiche plus les clicks mais seulement la présence d’interruptions, auriez-vous une idée ?

    Bien cordialement.

  3. Bonjour Francis, et bien il faut regarder la librairie et le code présenté ici. Mais en gros, il faut définir un BTN avec le pin qui le pilote

    Sébastien.

Leave a Reply

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

Related Post