Du rythme sans delay
Comment exécuter des tâches à intervalle de temps régulier, sans bloquer le reste du programme principal ?
Pourquoi delay bloque-t-il ?
On souhaite faire clignoter une LED toutes les secondes.
Soit le programme simple suivant :
const int LED_PIN = 13; // LED intégrée
byte ETAT_LED = LOW;
const unsigned long PERIODE = 500; // ms
void setup() {
pinMode(LED_PIN , OUTPUT);
}
void loop() {
// On allume/éteint la LED
digitalWrite(LED_PIN, ETAT_LED);
// Affichage du temps écoulé (en ms) et lde l'état de la LED
Serial.print(millis());
Serial.print("\t");
Serial.println(ETAT_LED);
// On change l'état de la LED
ETAT_LED = !ETAT_LED ;
// On attend ...
delay(PERIODE);
}
Téléverser ce programme dans l’Arduino
Ouvrir le Moniteur Série
Comment ne pas utiliser delay ?
Pour éviter de bloquer l’exécution du programme, on utilise :
- la fonction
millis()qui donne le temps écoulé depuis le démarrage de l’Arduino au formatunsigned long(entier non signé de format long), - une constante
PERIODE, représentant l’intervalle de temps entre deux tâches à réaliser, - et deux variables :
tpour mémoriser le temps « courant » donné parmillis(),- On fait ce relevé le plus fréquemment possible, à chaque exécution de la boucle principale
loop().
- On fait ce relevé le plus fréquemment possible, à chaque exécution de la boucle principale
t0pour mémoriser le dernier instant où la LED a changé d’état :- On compare
t0àtpour savoir s’il est temps de réaliser la tâche, - On initialise cette variable (on lui affecte la valeur de
t) dès que la tâche est réalisée.
- On compare
Remarque : toutes les variables et constantes représentant un « temps » sont exprimées en millisecondes et doivent être de type
unsigned long.
const int LED_PIN = 13;
byte ETAT_LED = LOW;
const unsigned long PERIODE = 500; // ms
unsigned long t0 = 0;
void setup() {
pinMode(LED_PIN , OUTPUT);
Serial.begin(9600);
}
void loop() {
unsigned long t = millis();
if (t-t0 >= PERIODE) {
t0 = t;
// On allume.éteint la LED
digitalWrite(LED_PIN, ETAT_LED);
// Affichage du temps écoulé (en ms) et lde l'état de la LED
Serial.print(millis());
Serial.print("\t");
Serial.println(ETAT_LED);
// On change l'état de la LED
ETAT_LED = !ETAT_LED ;
}
}
