La détection d'un front (facultatif)

Comme nous l'avons vu cette semaine, détecter l'appui d'un bouton se fait avec la fonction "digitalRead()". Cependant, si nous mettons juste cette lecture d'état dans la boucle principal, nous pouvons avoir des surprises.

En effet, prenons le code suivant :

1
int monBouton = 2; // bouton en broche 2
2
int compteur = 0;  // un compteur
3
int etatBouton; // L'état du bouton
4
5
void setup() {
6
  // le bouton en entrée
7
  pinMode(monBouton, INPUT); 
8
}
9
10
void loop() {
11
  // si on appuie sur le bouton
12
  etatBouton = digitalRead(monBouton);
13
  if(etatBouton == HIGH) {
14
    // alors on incrémente le compteur
15
    compteur = compteur+1;
16
  }
17
}

Dans ce code, nous incrémentons un compteur de 1 à chaque fois que l'on appuie sur un bouton. Tout du moins c'est ce que l'on aimerait... En effet, il y a un problème ! La fonction "loop" fonctionne très vite, tellement vite que votre compteur va s'incrémenter plein de fois par seconde, aussi longtemps que votre doigt reste appuyé sur le bouton, là où nous souhaiterions qu'il ne s'incrémente qu'une seule fois par appui...

Ce problème possède une solution : La détection de front.

Un front peut aussi être vu comme un changement d'état. Lorsque l'on appuie, on fera passer le niveau électrique de 0 à 1 ou le contraire. C'est ça un "front". Le but est maintenant de le détecter afin d'incrémenter notre compteur en sa présence et non pas uniquement sur un état. Pour cela nous allons devoir utiliser une variable nous servant de mémoire et qui va retranscrire l'état du bouton au moment t-1 (lors du précédent passage dans la boucle si vous préférez).

Front montantInformations[1]

Ensuite il nous suffira de comparer cette mémoire avec l'état actuel du bouton pour voir si ce dernier a changé entre les deux passages dans la boucle. Si effectivement la mémoire est différente de l'état actuel, alors le bouton a changé d'état, il y a un front. Sinon, cela signifie que le bouton est dans le même état, il n'y a pas eu de front.

Voici ce que cela pourrait donner sous la forme d'un code :

1
int monBouton = 2; // bouton en broche 2
2
int compteur = 0;  // un compteur
3
int etatBouton; // L'état du bouton
4
int memoire = LOW; // La mémoire de l'état du bouton
5
6
void setup() {
7
  // le bouton en entrée
8
  pinMode(monBouton, INPUT); 
9
}
10
11
void loop()
12
{
13
    // lecture de l'état du bouton
14
    etatBouton = digitalRead(monBouton);
15
16
    // Si le bouton a un état différent de celui enregistré ET
17
    // que cet état est "haut"
18
    if((etatBouton != memoire) && (etatBouton == HIGH))
19
    {
20
        // on incrémente le compteur
21
        compteur++;
22
    }
23
24
    // on enregistre l'état du bouton pour le tour suivant
25
    memoire = etatBouton;
26
}

Dans le code ci-dessus, l'opérateur "!=" signifie "différent de". C'est-à-dire que l'on compare la valeur de la variable "etatBouton" de la valeur enregistrée dans la variable "memoire". Si ces 2 valeurs sont différentes, alors la condition est satisfaite.

L'opérateur "&&" signifie "et". C'est-à-dire que le bloc d'instructions "if" n'est exécuté que si les 2 conditions entre parenthèses sont satisfaites (etatBouton != memoire) && (etatBouton == HIGH).