Pas de delay()!¶
Introduction¶
La fonction delay() qui est populaire auprès des débutants a un gros problème. En effet, elle bloque le programme pendant un certain temps. Pendant ce temps, le programme ne fait rien. C'est comme si le programme était en pause. C'est un problème car si le programme est en pause, il ne peut pas réagir aux événements qui se produisent. Par exemple, si le programme est en pause pendant 1 seconde, il ne peut pas réagir à un appui sur un bouton pendant cette seconde.

millis() est une fonction qui permet de mesurer le temps écoulé depuis le démarrage du programme. Elle retourne un nombre entier qui représente le temps écoulé en millisecondes. Par exemple, si le programme a été démarré il y a 1 seconde, la fonction millis() retournera 1000.
À première vue, vous pouvez douter de l'utilité de cette fonction. Cependant, elle est extrêmement utile pour plusieurs scénarios, souvent remplaçant delay() complètement. C'est ce que nous allons voir dans cette leçon.
Utiliser millis() comme delay()¶
Voici un exemple qui remplace delay() par millis().
NE PAS FAIRE CECI DANS VOTRE CODE, C'EST UNE DÉMONSTRATION. LISEZ L'ARTICLE AU COMPLET
| Mauvais exemple d'utilisation de millis() | |
|---|---|
Si vous voulez arrêter 1 seconde à chaque fin de boucle, le code précédent est un peu fou. On pourrait seulement utiliser delay(1000) à la place.
Pourquoi utiliser millis() au lieu de delay()?¶
Nous allons maintenant voir l'avantage de millis() par rapport à delay().
millis() est plus précis¶
Le premier avantage que nous allons aborder est la précision du timing. Du point de vue du code, nous avons abordé ce sujet dans le dernier chapitre. Avec millis(), nous pouvons nous assurer que la boucle s'exécute aussi souvent que nous le souhaitons, indépendamment du 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 puisque nous ne connaissons pas la durée d'exécution de la boucle.
Un chronométrage précis comme celui-ci est très utile pour échantillonner à une certaine fréquence ou pour exécuter des filtres, entre autres choses.
millis() n'est pas bloquant¶
L'autre avantage de millis() est qu'il ne nous empêchera pas d'exécuter du code pendant l'"attente".
Disons que nous voulons imprimer "Hello" en série une fois par seconde tout en faisant d'autres choses pendant ce temps. Ceci n'est pas possible avec delay() puisqu'il met en pause tout le code. Voici une façon de le faire :
Ce bout de code est assez similaire au premier morceau, sauf qu'il ne bloque pas le reste du programme lorsqu'il n'imprime pas en série.
Exemple : un planificateur de tâches simple¶
Écrivons un exemple simple dans lequel nous créons un planificateur qui imprime certains bouts de texte à des intervalles différents.
Exercice : Copiez ce code et envoyez-le à votre carte Arduino. Qu'observez-vous ?
-
Code
-
Résultat

On constate la simplicité de l'implémentation de ce planificateur. Il suffit de vérifier si le temps écoulé depuis la dernière exécution de la tâche est supérieur à l'intervalle souhaité. Si c'est le cas, nous exécutons la tâche et nous mettons à jour le temps de la dernière exécution.
Ainsi l'utilisation de millis() nous permet de créer du code relativement simple et facile à maintenir.
Explication de la limite de millis()¶
La valeur maximum d'un unsigned long est de 4 294 967 295 car un unsigned long est de 4 octets donc 2^32-1.
Si nous divisons cette valeur par 1000, nous obtenons 4 294 967 secondes. On divise par 60, on obtient 71 582 minutes. On divise par 60, on obtient 1 193 heures. On divise par 24, on obtient 49.7 jours.