Une fonction Arduino bien connue est delay()
qui interrompt le programme pendant une quantité de millisecondes spécifiée en paramètre.
millis()
, d’autre part, est une fonction qui renvoie la quantité de millisecondes qui se sont écoulées depuis le démarrage du programme.
À première vue, vous pouvez douter de l’utilité de cette fonction. Le fait est qu’il est extrêmement utile dans de nombreux scénarios, « remplaçant » souvent delay()
complètement. Voyons d’abord comment nous pouvons utiliser millis()
presque exactement comme delay()
.
Les problèmes de calendrier sont souvent présents dans la programmation.
En utilisant millis() comme delay()
int period = 1000;unsigned long time_now = 0;void setup() {Serial.begin(115200);}void loop() {time_now = millis(); Serial.println("Hello"); while(millis() < time_now + period){//wait approx. ms}}
Si vous voulez que votre code se mette en pause pendant 1000 ms à la fin de chaque itération de boucle, le code ci-dessus est un peu idiot. Vous pouvez simplement utiliser delay(1000)
à la place. La seule différence entre le code ci-dessus et un code avec delay(1000)
à la fin est que la boucle du code ci-dessus s’exécutera assez précisément une fois par seconde. La boucle dans un code avec delay(1000)
s’exécutera un peu moins fréquemment car il faut également un certain temps pour exécuter Serial.println("Hello")
.
Pourquoi utiliser millis() au lieu de delay()?
Nous allons maintenant examiner deux avantages avec millis()
par rapport à delay()
.
Timing précis
Le premier avantage dont nous parlerons est le timing précis. En termes de code, nous avons couvert cela dans le dernier chapitre. Avec millis()
, nous pouvons nous assurer que la boucle s’exécute aussi souvent que nous le souhaitons, quel que soit le temps d’exécution (évidemment tant que le temps d’exécution est inférieur à la période souhaitée). Avec delay()
, ce n’est pas possible car nous ne savons pas combien de temps dure le temps d’exécution de la boucle.
Une synchronisation précise comme celle-ci est très utile lors de l’échantillonnage à une certaine fréquence ou de l’exécution de filtres, entre autres.
Non bloquant
L’autre avantage avec millis()
est qu’il ne nous empêchera pas d’exécuter du code en « attente ».
Disons que nous voulons imprimer « Bonjour » en série une fois par seconde tout en faisant d’autres choses entre-temps. Cela n’est pas possible avec delay()
car il met en pause tout le code. Voici une façon de le faire:
int period = 1000;unsigned long time_now = 0;void setup() {Serial.begin(115200);}void loop() {if(millis() >= time_now + period){time_now += period;Serial.println("Hello");} //Run other code}
Ce morceau de code est assez similaire au premier morceau, sauf qu’il ne bloque pas le reste du programme lorsqu’il n’est pas imprimé en série.
Exemple: un Planificateur simple
Écrivons un exemple simple où nous créons un planificateur qui imprime certains bits de texte à différents intervalles.
#define INTERVAL_MESSAGE1 5000#define INTERVAL_MESSAGE2 7000#define INTERVAL_MESSAGE3 11000#define INTERVAL_MESSAGE4 13000unsigned long time_1 = 0;unsigned long time_2 = 0;unsigned long time_3 = 0;unsigned long time_4 = 0;void print_time(unsigned long time_millis);void setup() {Serial.begin(115200);}void loop() {if(millis() >= time_1 + INTERVAL_MESSAGE1){time_1 +=INTERVAL_MESSAGE1;print_time(time_1);Serial.println("I'm message number one!");} if(millis() >= time_2 + INTERVAL_MESSAGE2){time_2 +=INTERVAL_MESSAGE2;print_time(time_2);Serial.println("Hello, I'm the second message.");} if(millis() >= time_3 + INTERVAL_MESSAGE3){time_3 +=INTERVAL_MESSAGE3;print_time(time_3);Serial.println("My name is Message the third.");} if(millis() >= time_4 + INTERVAL_MESSAGE4){time_4 += INTERVAL_MESSAGE4;print_time(time_4);Serial.println("Message four is in the house!");}}void print_time(unsigned long time_millis){Serial.print("Time: ");Serial.print(time_millis/1000);Serial.print("s - ");}
Voici à quoi ressemblent les 60 premières secondes du moniteur série:
C’est un moyen agréable et facile de synchroniser les exécutions dans votre code. Vous pouvez également exécuter un autre code simultanément.
micros() et Débordant
Tout comme delay()
a une version en microsecondes appelée delayMicroseconds()
, millis()
a micros()
. Si vous avez besoin d’une meilleure résolution, micros()
peut être la voie à suivre.
Cependant, sachez que micros()
débordera après environ 70 minutes, par rapport aux 50 jours de millis()
. Cela signifie que les valeurs de retour des fonctions recommenceront à zéro.
Plus important encore: pour savoir comment éviter le problème de débordement, lisez cet article de blog.
Résumé
millis()
et micros()
sont des fonctions très pratiques à utiliser lors de tâches de synchronisation. Si vous n’en êtes pas au courant, vous pourriez finir par utiliser delay()
à la place, ce qui ne fonctionnera pas toujours aussi bien (voire pas du tout).
Pour plus de conseils Arduino & astuces, consultez notre catégorie de blog de tutoriels Arduino. Restez à l’écoute pour plus de contenu lié à Arduino à l’avenir!