Chapitre 5

Repartons de ce montage décrit dans la rubrique Arduino réalisations. Il permet de mesurer la vitesse d’un moteur.

Le programme publié fait son boulot. Ou plus exactement il fait ce qu’il peut pour ramener un résultat correct. Il est facile de voir que cette façon de programmer a ses limites.

Par exemple, remplaçons la barre 3 trous meccano elec qui se déplace au milieu de la fourche optique par une roue barillet 6 trous meccano elec. On peut se dire qu’on a un dispositif analogue à 3 barres 3 trous et qu’il suffit d’un petit calcul pour trouver la vitesse de rotation. La vérité c’est que ça ne fonctionne pas bien, comme si les changements d’états arrivaient trop vite, que l’on en loupe quelques uns ce qui donne des résultats variables et souvent faux.

Pour comprendre ce qui se passe, changeons d’échelle de temps et de domaine :

La standartiste

Cette standardiste est passionnée de poésie ; elle lit des poèmes toute la journée ou presque et quand elle lit, pas question de décrocher le téléphone. Plus exactement son rythme est le suivant : 10 minutes de lecture, une minute de prise d’appels…et ainsi de suite toute la journée.

Ca ne serait pas gếnant si elle interrompait sa lecture en cas d’appel mais non…elle ne veut pas entendre parler de ça. Elle loupe donc une belle quantité d’appels…

Bon revenons à l’Arduino… Quand la fonction loop() se déroule, l’Arduino déroule tout un tas d’instructions qui prennent du temps et il n’est pas du tout à l’affût des changements d’état qui peuvent arriver : c’est le rôle de quelques instructions écrites dans le programme mais, quand l’Arduino exécute les autres instructions, il est sourd aux évènements qui pourraient se passer, il faut attendre le prochain passage sur les instructions qui « écoutent ». Si les évènements se succèdent très vite cela devient un problème : l’Arduino peut louper des changements d’état. Par exemple la Pin 2 est passée de l’état haut à l’état bas mais l’Arduino, qui était occupé à autre chose, n’a rien vu, rien entendu.

Il existe une façon très élégante de résoudre ce problème : utiliser les interruptions de l’Arduino. De cette façon, même quand le programme déroule sa boucle en exécutant les instructions de la boucle loop(), il reste en permanence à l’affût des changements.


// Chapitre 5 

long chrono = 0; // valeur courante du chrono

long chrono_depart = 0; // valeur de départ du chrono

long duree_test = 15000; // test sur 15 secondes

volatile long nb_chgt = 0; // nb de changement etat Pin

void setup () {

  Serial.begin (19200);

  chrono_depart = millis();

// l'interruption zero correspond à la pin 2
// on enregistre tous les changements d'état

  attachInterrupt(0,gere_int0,CHANGE); 

}

void loop() {

  chrono = millis ();

// est-ce que le test est fini ?

  if (chrono - chrono_depart > duree_test) {
// petite ruse : il y a 4 changements d'état par tour
// en faisant un test sur 15 secondes le nb de chgt
// a la meme valeur que le nombre de tours par minute

  Serial.print ("Vitesse : ");
  Serial.print (nb_chgt);
  Serial.println (" trs/min");
// une fois que l'affichage est fait on execute une boucle vide
// ainsi on a l'affichage de la vitesse une seule fois

  while (1) {}

  }

}

// Gestion de l'interruption 0

void gere_int0() {
    nb_chgt = nb_chgt + 1 ;
}

Le programme est très court et… plus simple que le programme précédent proposé.

On résume : On a le choix entre deux interruptions, la 0 et 1 (on les connaît par leur numéro, rien de spécial à comprendre). On va choisir, par exemple l’interruption zéro.

L’interruption zéro a le travail suivant à réaliser :
– surveiller les changements d’état de la Pin 2
– si changement, interrompre immédiatement le déroulement des instructions de la fonction loop()
– déclencher la fonction de notre choix (voir l’instruction attachInterrupt() )
– reprendre l’exécution de la boucle loop() là où elle s’était interrompue
– continuer à surveiller les changements d’état de la Pin2 …

L’avantage de cette façon d’utiliser les interruptions c’est qu’on ne loupe pas des changements très rapides, l’inconvénient c’est qu’on a deux interruptions possibles seulement la 0 et la 1 qui surveillent respectivement la PIn2 et la Pin 3.

Pour les évènements lents, cette façon de programmer n’est nullement obligatoire. Mais il est très intéressant de constater qu’avec cette technique on peut suivre sans problème des mouvements très rapides.

Si on met une roue barillet 6 trous, pas de pb, l’Arduino suit le rythme des changements d’état.
Une 8 trous fonctionne aussi et… je suis allé cherché une roue barillet 10 trous, pas très courante, ça marche aussi. Avec cette roue, en ramenant la durée du test à 3 secondes, on affiche directement le nb de changements d’états qui est aussi la vitesse en tours/min. En réduisant la durée du test à 1 seconde et en affichant 3 fois le nombre de changements d’état, on obtient aussi la vitesse en tours/min.