Imprimer

Dans cet article, nous allons aborder la notion d'interruption et la gestion d'un front.

Une interruption est une manière d'interrompre le traitement en boucle réalisé par votre microcontrôleur

La gestion d'un front sert à détecter un changement d'état sur un capteur, la problématique étant d'arriver à compter correctement ce nombre de changements alors que le microcontrôleur est extrêmement rapide.

 

 

 

Les interruptions

Un microcontrôleur Arduino effectue en boucle les mêmes actions de votre boucle loop(). Mais il effectue séquentiellement les actions de cette boucle. 

Le principe des interruptions permet au microcontrôleur de réaliser d'autres actions (lire un capteur par exemple) en parallèle de la boucle loop. Ainsi, la carte Arduino Uno possède deux broches pouvant gérer des interruptions (broche 2 INT0 et broche 3 INT1).

Ci-dessous un exemple avec un bouton poussoir dont l'état est surveillée par une interruption. Chaque appui sur le bouton poussoir sera comptabilisé et afficher dans la boucle principale.

Le montage :

 

Le code :

int boutonPin  = 2 ;
int pin13 = 13 ;
int compteur = 0 ;

//  Pour qu'on puisse changer la valeur d'une variable depuis une fonction de
// gestion d'interruption, il faut que la variable soit déclaré "volatile"
volatile boolean changed = false;

void doContact() {
  changed = true;
  compteur++;
}

void setup() { 
  // Broche en entrée avec résistance de pull-up
  pinMode(boutonPin, INPUT_PULLUP);
  pinMode(pin13,OUTPUT);
  
  // Attacher notre fonction ISR, detection de flanc déscendant (5v vers 0v)
  attachInterrupt(0, doContact, FALLING);
  
  // Montrer que nous sommes la 
  Serial.begin (9600);
  Serial.println("Fin setup");
} 

void loop(){
  if ( changed ) {
    changed = false;
    Serial.print("Ha ! Vous avez touche le bouton ");
    Serial.print(compteur);
    Serial.println(" fois");
    // on allume la LED pendant 1 seconde
    digitalWrite(pin13,HIGH);
    delay(1000);
    digitalWrite(pin13,LOW);
    
  }
  delay(5000);
}

 

 

Comment gérer un front 

En utilisant une interruption, on a vu précédemment qu'il est possible de compter le nombre d'appui sur un bouton poussoir. Mais on peut procéder autrement, en gérant la notion de front.

Si nous nous limitons mettons juste à lire l'état via digitalRead(), votre compteur du nombre d'appui sur le bouton" va être astronomique, car durant le temps on le bouton sera appuyé puis relaché, ce temps minime sera très grand au regard d'arduino qui aura eu le temps de passer dans la boucle un grand nombre de fois.

Ci-dessous l'exemple gérant mal ce compteur :

 

int monBouton = 2; // bouton en broche 2
int compteur = 0;  // un compteur
int etatBouton; // L'état du bouton
 
void setup() {
  // le bouton en entrée
  pinMode(monBouton, INPUT); 
}
 
void loop() {
  // si on appuie sur le bouton
  etatBouton = digitalRead(monBouton);
  if(etatBouton == HIGH) {
    // alors on incrémente le compteur
    compteur = compteur+1;
  }
}

 

La solution : la détection de front.

Un front peut aussi être vu comme un changement d'état. Lorsque l'on appui, on fera passe le niveau électrique de 0 à 1 ou le contraire. C'est ca 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).

 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 :

 

int monBouton = 2; // bouton en broche 2
int compteur = 0;  // un compteur
int etatBouton; // L'état du bouton
int memoire = LOW; // La mémoire de l'état du bouton
 
void setup() {
  // le bouton en entrée
  pinMode(monBouton, INPUT); 
}
 
void loop()
{
    // lecture de l'état du bouton
    etatBouton = digitalRead(monBouton);
     // Si le bouton a un état différent de celui enregistré ET que cet état est "haut"
    if((etatBouton != memoire) && (etatBouton == HIGH))
    {
        // on incrémente le compteur
        compteur++;
    }
 
    // on enregistre l'état du bouton pour le tour suivant
    memoire = etatBouton;
}

Bibliographie

Cet article est issu du cours MOOC "la fabrique numérique".

D'autres sources : http://eskimon.fr/category/arduino

https://zestedesavoir.com/tutoriels/537/arduino-premiers-pas-en-informatique-embarquee/743/gestion-des-entrees-sorties/3422/tp-feux-de-signalisation-routiere/