Tutoriel Arduino: Utiliser millis() au lieu de delay()

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!

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.