Compter les tours avec une fourche optique – utilisation des interruptions

Pour être sûr de ne pas louper un événement (par exemple plus de lumière reçue par le détecteur de la fourche optique), il faut trouver un moyen de le traiter immédiatement, même quand le programme est occupé à tout autre chose, par exemple faire un calcul ou attendre par un appel à delay() … En effet, lorsqu’il n’est pas précisément en train d’exécuter les quelques lignes du programme qui sont à l’affût du changement d’état, l’Arduino est sourd !

Les interruptions permettent, toutes affaires cessantes, de traiter un événement dès qu’il se produit, en interrompant provisoirement l’exécution du programme. Une fois l’interruption traitée, le programme reprend son cours là où il en était resté.

Si vous ne savez pas du tout ce que c’est qu’une interruption, jetez un coup d’oeil ici.

Le programme précédent est simplifié, il va supporter des vitesses de rotation plus élevées… que des avantages !


/*
   Compte-tours avec fourche optique
   et roue encodeuse 10 dents
   DFrobot SEN0038
   utilisation des interruptions
    
       
 */
 
int FO = 2; // fourche optique relié à la pin 2 
 
int E1 = 5; //M1 Controle de vitesse PWM
 
int M1 = 4; //M1 Controle du sens de rotation

// on va stocker les chgts d'état de la fourche

volatile long chgt_fo = 0;


// la fonction de traitement de l'interruption

void compte_chgt()
{

chgt_fo ++ ;

}

 
void marche_avant(char a) //Marche avant
{
  analogWrite (E1,a); // PWM (reglage vitesse)
  digitalWrite(M1,HIGH); // sens de rotation
} 
 
void marche_arriere (char a) //Marche arrière
{
  analogWrite (E1,a); // PWM (reglage vitesse)
  digitalWrite(M1,LOW); // sens de rotation
}

void stop_moteur () 
{
  analogWrite (E1,0); // PWM (reglage vitesse)
  delay(100);
}
 
 
/////////////////////////////////////////////////////////////////////
void marche_nb_pas( int vitesse, int nb_pas, char sens)
/////////////////////////////////////////////////////////////////////

{

int nb_top = 0;

chgt_fo = 0;


// lancer le moteur

 if (sens == 'A') {
      marche_avant (vitesse);
     }
     
 if (sens == 'R') {
      marche_arriere (vitesse);
     }
     

while ( nb_top < nb_pas  ) {     
   
   // pour une dent passée,
   // deux changements d'état :
   // lumière=> pas de lumière
   // pas de lumière => lumière
   
   // c'est la fonction de traitement
   // de l'interruption qui s'occupe
   // d'incrémenter la variable chgt_fo
     
    nb_top = chgt_fo / 2;
    
  //  Serial.print ("*************** nb_top : ");
    
   // Serial.println(nb_top);    
  
     
  }     
 

stop_moteur();
}
 
 
// Executee une seule fois
 
void setup() {
   
   // initialiser la communication serie
    
   Serial.begin(9600);
    
   pinMode(E1, OUTPUT); // E1 est utilisee en sortie
    
   pinMode(M1, OUTPUT); // M1 est utilisee en sortie
   
   pinMode(FO,INPUT); // fourche optique reliée pin 2
   
   // l'interruption 0 (pin 2) déclenche la fonction compte_chgt
   
   attachInterrupt(0, compte_chgt, CHANGE);     
   
  
}
 
// executee en boucle
 
void loop() {
  
    
   Serial.println("On avance de 20 pas");
   // 10 pas = 1 tour
   
   marche_nb_pas(200,20,'A');
   
   delay(3000);
    
   
  Serial.println("On recule de 5  pas");
   
   marche_nb_pas(200,5,'R');
   
   delay(3000);
   
  
  Serial.println("On recule de 15 pas");
   
   marche_nb_pas(200,15,'R');    
    
  delay(3000);
}