[Tutorial] Les interruptions temporelles avec Arduino

Publié: 7 juin 2013 dans Tutoriaux
Tags:, , ,

Bonjour à tous !

Aujourd’hui un petit billet pour vous parler des interruptions temporelles sous Arduino. C’est un sujet qui revient très souvent sur le forum donc je pense que faire un petit article évitera les multiples répétitions …

Pourquoi faire donc ?

Tout simplement pour exécuter une routine de code à intervalle régulier, sans avoir recours à delay() et donc sans bloquer votre code (enfin il faudra nuancer mais dans l’absolu c’est imperceptible).

Comment qu’on fait ?

Le principe est très simple : on a recours à la fonction millis() (ou micros() si vous avez besoin de plus de précision) qui renvoi un unsigned long correspond au nombre de millisecondes écoulées depuis le début du programme. A un moment donné, on va enregistrer cette valeur, puis régulièrement on va faire la différence entre millis() et cette valeur ce qui nous donnera le temps écoulé. Si le temps écoulé correspond à notre intervalle, alors on exécute le code correspondant, sinon, on exécute autre chose.

Exemple

Prenons un simple blink :



const byte led = 13;


void setup(){

    pinMode(led,OUTPUT);

}


void loop() {


    digitalWrite(led,HIGH);

    delay(1000);

    digitalWrite(led,LOW);

    delay(1000);


}


Donc la vous comprenez bien que pendant les deux delay(1000), votre Atmega s’emme**e et ne peux rien faire. Maintenant, soyons plus astucieux 😉 :



unsigned long Depart;

boolean Flag;

const Led 13;

const MonDelai=1000;


void setup() {


    pinMode(Led,OUTPUT);

    Depart = millis(); // Enregistrement de mon point de départ


}


void loop() {


    if((millis()-Depart)>=MonDelai){     // si 1000 ms se sont écoulées

         Flag=!Flag;    // j'inverse l'état de mon booléen

         digitalWrite(Led,Flag);   //  je change l'état de ma sortie

         Depart=millis();  // nouvelle enregistrement du point de départ

        }

// code qui s'exécutera le temps que 1000 ms se soient écoulées

}


Cette exemple montre bien combien un Atmega peut-être « sous-utilisé ». J’entends par la que bien souvent, on trouve sur le forum des personnes qui trouve leur Arduino lente alors qu’en fait c’est juste leur code qui n’est pas du tout optimisé. Ici la partie conditionnelle va prendre quelques dizaines de µs chaque seconde, ainsi on ne sollicite réellement que moins de 0.01% des ressources de l’Atmega … Cependant il faut aussi avoir conscience que si le reste de votre code est bloquant, la précision de votre intervalle va en pâtir.  L’Arduino est mono-tâche, mais si on optimise bien son code, ça peut tout à fait être transparent pour l’utilisateur 😉

Publicités
commentaires
  1. Intéressant mais si ta boucle loop() est longue, tu risques d’avoir un petit problème de précision sur le temps. C’est à dire dépasser largement le temps des 1000 millisecondes (dans ton secondes) alors que les atmega sont équipés d’une gestion d’interruptions (reset, interruptions externes aux broche INT1 et INT2, de TIMER0 et TIMER1, interruption UART). Il suffit juste de configurer les fusibles du microcontroleur à partir de ces registres.

    • battooo dit :

      D’où la remarque à la fin : « Cependant il faut aussi avoir conscience que si le reste de votre code est bloquant, la précision de votre intervalle va en pâtir. »

      Si tu ne l’as pas compris ce billet était destiné à un public débutant, et le jour où tu feras une interruption temporelle avec l’inter UART tu m’envois le code 😉