Arduino Delay [Tutorial]

Dans ce tutoriel, vous apprendrez à utiliser correctement la fonction delay() pour ajouter un délai entre 2 actions dans vos programmes Arduino. Ensuite, vous découvrirez pourquoi l’utilisation de delay() n’est souvent pas une bonne idée lorsque vous souhaitez faire évoluer vos programmes, et comment y remédier.

D’accord, commençons!

Table des Matières

Pourquoi avez-vous besoin de retards dans vos programmes Arduino?

Eh bien, un programme Arduino repose beaucoup sur des entrées / sorties externes pour fonctionner.

Prenons un exemple simple: vous pouvez surveiller l’état d’un bouton-poussoir 100 fois par seconde ou faire clignoter une LED toutes les 0,5 seconde.

Maintenant, comment pouvez-vous y parvenir? Un programme Arduino fonctionne comme ceci:

  • Tout d’abord, la fonction setup() est exécutée une fois.
  • Ensuite, la fonction loop() est exécutée encore et encore, jusqu’à ce que vous éteigniez votre Arduino.

Tout programme que vous écrivez sera exécuté à pleine vitesse. Donc, si vous faites clignoter une LED dans votre code, ce qui va se passer, c’est que la LED clignotera à un taux très élevé (plusieurs milliers de fois par seconde au moins).

Vous apprenez à utiliser Arduino pour construire vos propres projets?

Découvrez Arduino pour les débutants et apprenez étape par étape.

Si vous souhaitez contrôler le temps – c’est–à-dire, assurez-vous que la LED ne clignote que toutes les 0,5 seconde et non à pleine vitesse – vous devez ajouter un délai dans votre code.

Implémenter Arduino delay dans votre code

La fonction Arduino delay()

Voici un code pour faire clignoter une LED (ici nous choisissons la LED intégrée, pas besoin d’ajouter de LED externe) toutes les 0,5 secondes – c’est l’un des exemples les plus courants que vous verrez si vous commencez avec Arduino.

#define LED_PIN 13void setup() { pinMode(LED_PIN, OUTPUT);}void loop() { digitalWrite(LED_PIN, HIGH); delay(500); digitalWrite(LED_PIN, LOW); delay(500);}

Alors, comment fonctionne ce code?

D’abord, vous utilisez un « définir » afin de ne pas avoir à coder en dur le nombre « 13 » plusieurs fois dans votre code et cela rend votre programme plus lisible.

Vous configurez le mode de sortie de la broche avec la fonction pinMode().

Puis, dans la fonction loop(), vous:

  1. Allumez la LED
  2. Utilisez delay(500) pour mettre le programme en veille pendant 500 millisecondes, ou 0,5 seconde
  3. Éteignez la LED
  4. Utilisez delay(500) pour mettre le programme en veille à nouveau pendant 0,5 seconde
  5. Et revenez à l’étape 1, car la fonction loop() continue d’être exécutée encore et encore.

La fonction delay() s’attend à ce que vous donniez un certain nombre de millisecondes – et non de secondes – pour dormir. Donc, si vous pensez en quelques secondes, multipliez le nombre par 1000 et vous avez la valeur dont vous avez besoin.

Faites un délai Arduino de 1 minute

Si vous voulez faire dormir votre Arduino pendant 1 minute, ou pendant plusieurs minutes, c’est assez facile.

Prenez le nombre de minutes, multipliez-le par 60 pour obtenir le nombre de secondes, puis multipliez-le par 1000 pour obtenir le nombre de millisecondes.

Ex: delay(3 * 60 * 1000); fera dormir le programme pendant 3 minutes.

La fonction Arduino delayMicroseconds()

Si vous avez besoin d’être plus précis, vous devrez peut-être utiliser la fonction delayMicroseconds(). Avec delayMicroseconds(), vous pouvez fournir un certain nombre de microsecondes pour dormir. La durée minimale pour delay() est de 1 milliseconde, donc si vous avez besoin de dormir pendant seulement 400 microsecondes, vous avez ici une nouvelle solution.

Cette fonction peut être très utile lors de la communication avec certains composants matériels. Par exemple, l’Arduino doit envoyer des données au composant, puis lire une réponse. Disons que le composant a besoin de 6 microsecondes pour traiter la demande et fournir des données précises.

Alors dans votre programme, vous pouvez avoir quelque chose comme ceci:

...void loop() { // send data to component delayMicroseconds(6); // reach out to component again to read data}

Délai non bloquant – pourquoi vous devriez éviter d’utiliser delay()

Alors, maintenant que vous comprenez ce qu’est un délai dans Arduino, et comment l’implémenter avec delay() et delayMicroseconds(), voyons comment utiliser la fonctionnalité de retard – mais sans ces fonctions.

Pourquoi?

Lorsque vous utilisez delay(), l’exécution de votre programme s’arrête et ne reprend qu’une fois le délai terminé.

C’est OK si vous n’avez qu’une seule action à faire – exemple: clignotez une seule LED – mais que se passe-t-il si vous devez prendre en charge plusieurs composants matériels ou communiquer avec d’autres périphériques tels que des cartes Arduino ou votre propre ordinateur?

En utilisant l’exemple précédent, comment pourriez-vous faire clignoter une LED toutes les 0,5 seconde et une autre clignote toutes les 0,8 seconde?

Dans ce cas, vous serez bloqué assez rapidement. Si vous souhaitez toujours utiliser delay(), vous pouvez trouver une solution où vous utilisez des délais plus courts entre plusieurs actions, mais cela rendra votre programme plus compliqué chaque fois que vous ajoutez une nouvelle action.

La solution à cela consiste simplement à surveiller l’heure sans utiliser la fonction delay(), essentiellement pour trouver un moyen de reproduire le comportement de delay() sans l’utiliser.Exemple de code

– Arduino delay without delay ()

Réécrivons notre exemple de LED clignotante sans utiliser delay().

#define LED_PIN 13unsigned int lastTimeLedBlinked = millis();unsigned int delayBetweenBlink = 500;byte ledState = LOW;void setup() { pinMode(LED_PIN, OUTPUT);}void loop() { unsigned int timeNow = millis(); if (timeNow - lastTimeLedBlinked > delayBetweenBlink) { if (ledState == LOW) { ledState = HIGH; } else { ledState = LOW; } digitalWrite(LED_PIN, ledState); lastTimeLedBlinked = timeNow; }}

Analysons ce code ligne par ligne.

Initialisation

#define LED_PIN 13unsigned int lastTimeLedBlinked = millis();unsigned int delayBetweenBlink = 500;byte ledState = LOW;

Tout d’abord, vous initialisez 3 variables dans la portée globale:

  • lastTimeLedBlinked: cette variable sera utilisée pour stocker la dernière fois que la LED a clignoté. Fondamentalement, chaque fois que nous ferons clignoter la LED, nous mettrons à jour cette variable avec l’heure actuelle – en utilisant la fonction millis().
  • delayBetweenBlink: c’est le temps que vous souhaitez attendre entre 2 actions – ici, l’action consiste à clignoter la LED.
  • ledState: nous devrons stocker l’état de la LED actuelle (HAUT ou BAS) afin que nous puissions savoir quel était l’état précédent et agir en conséquence.

Pourquoi dans la portée globale? Eh bien, ce que nous prévoyons de faire est de mettre à jour ces variables dans la fonction loop() et d’y accéder à nouveau la prochaine fois que nous entrerons dans la fonction loop(). Si nous créons les variables à l’intérieur du loop(), les variables seront des variables locales et seront donc détruites lorsque vous quitterez la fonction loop(). Ainsi, la prochaine fois que loop() est à nouveau appelé, toutes les valeurs seront perdues et vous créerez à nouveau des variables sans valeur précédente à l’intérieur. Ici, en créant les variables en dehors de la fonction, nous pouvons les faire « survivre » et conserver leur valeur chaque fois que nous entrons dans le loop().

Implémentation de la fonctionnalité de retard Arduino dans la fonction de boucle

Maintenant, voyons ce qui se passe dans la fonction loop().

void loop() { unsigned int timeNow = millis();

Tout d’abord, vous lisez l’heure actuelle avec la fonction millis().

 if (timeNow - lastTimeLedBlinked > delayBetweenBlink) {

Et maintenant vous comparez l’heure actuelle que vous venez de lire, avec l’heure précédente où la LED a clignoté. Si suffisamment de temps s’est écoulé (plus que la valeur stockée dans delayBetweenBlink), cela signifie que vous pouvez entrer le if().

Cette structure de code – lire l’heure et la comparer à la fois précédente où vous avez effectué une action – est la façon dont vous remplacez la fonction delay(). Fondamentalement, vous calculez simplement une durée ici. Et comme vous pouvez le voir, cela signifie que votre programme contient plus de lignes pour une application simple, mais il vous donne beaucoup plus de contrôle et il est beaucoup plus évolutif.

Alors, que va-t-il se passer? Eh bien, le loop() continuera à être exécuté à pleine vitesse. Chaque fois, votre programme vérifiera si suffisamment de temps s’est écoulé. Sinon, le loop() se termine ici, car il n’entrera pas dans la structure if.

Et, quand juste assez de temps s’est écoulé, nous entrons dans le if().

Exécution de l’action

 if (ledState == LOW) { ledState = HIGH; } else { ledState = LOW; } digitalWrite(LED_PIN, ledState);

OK, vous venez d’entrer le if(), et c’est là que vous ferez l’action que vous devez faire.

Ici, nous faisons clignoter la LED. Et parce que nous ne pouvons pas savoir directement quel était l’état précédent pour la LED (puisque nous avons entré le loop() plusieurs fois et perdu toutes les variables locales créées à l’intérieur), nous obtenons cet état à partir d’une variable globale.

Ce que nous faisons avec cette variable globale est simple: si elle était FAIBLE, nous la mettons à HAUTE, et si elle était ÉLEVÉE, nous la mettons à BASSE. Et puis, bien sûr, nous mettons à jour l’état physique de la LED en conséquence, avec digitalWrite().

 lastTimeLedBlinked = timeNow; }}

Enfin, et c’est super important, nous économisons l’heure actuelle comme la dernière fois que nous avons clignoté la LED. Si nous ne le faisons pas, le programme clignotera la LED à pleine vitesse car la condition à l’intérieur du if() sera toujours vraie.

En réglant l’heure précédente à l’heure actuelle, nous « réinitialisons la minuterie ».

Ainsi, dans cet exemple, le if() ne sera entré que toutes les 500 millisecondes, soit 0,5 seconde.

Et maintenant, c’est génial car votre programme ne s’arrête pas, vous pouvez donc continuer à exécuter différentes actions indépendantes tout en « attendant » de clignoter la LED.

2 actions « en même temps »

Par exemple, disons que vous voulez clignoter une LED tous les 0.5 secondes, et une autre toutes les 0,8 seconde.

#define LED_1_PIN 13#define LED_2_PIN 10unsigned int lastTimeLed1Blinked = millis();unsigned int delayBetweenBlink1 = 500;byte led1State = LOW;unsigned int lastTimeLed2Blinked = millis();unsigned int delayBetweenBlink2 = 800;byte led2State = LOW;void setup() { pinMode(LED_1_PIN, OUTPUT); pinMode(LED_2_PIN, OUTPUT);}void loop() { unsigned int timeNow = millis(); // Action 1 - Blink LED 1 if (timeNow - lastTimeLed1Blinked > delayBetweenBlink1) { if (led1State == LOW) { led1State = HIGH; } else { led1State = LOW; } digitalWrite(LED_1_PIN, led1State); lastTimeLed1Blinked = timeNow; } // Action 2 - Blink LED 2 if (timeNow - lastTimeLed2Blinked > delayBetweenBlink2) { if (led2State == LOW) { led2State = HIGH; } else { led2State = LOW; } digitalWrite(LED_2_PIN, led2State); lastTimeLed2Blinked = timeNow; }}

Comme vous pouvez le voir, nous répétons la structure de code pour la deuxième action que nous avons ajoutée. Et les deux actions ne se dérangeront pas!

Récapitulatif

Si vous souhaitez effectuer un retard Arduino sans utiliser delay():

  1. Créez une variable globale pour stocker la dernière fois que vous avez effectué une action spécifique.
  2. Créez une autre variable globale pour stocker la durée souhaitée entre 2 actions.
  3. Dans la fonction loop(), lisez l’heure actuelle avec millis().
  4. Juste après cela, utilisez une structure if et utilisez la condition (timeNow - lastTimeActionWasExecuted > delayBetweenActions).
  5. Une fois que vous avez entré le if(), effectuez l’action.
  6. Et toujours dans le if(), stockez l’heure actuelle comme l’heure précédente.

Vous pouvez répéter ces étapes pour chaque action pour laquelle vous avez besoin d’un délai Arduino.

Quand il est ok d’utiliser delay() et delayMicroseconds()

Il y a des occasions spécifiques où l’utilisation de delay() dans votre code est toujours OK.

En voici 2:

  • Vous devez initialiser un composant lors de la configuration de votre programme, et ce composant a besoin de temps pour être initialisé – par exemple 1,5 seconde. Dans ce cas, l’utilisation de delay(1500) dans votre fonction setup() est parfaitement correcte. Fondamentalement, tout delay() dans la fonction setup() de votre programme Arduino ne sera pas un problème.
  • Comme expliqué dans la partie delayMicroseconds(), vous devez attendre quelques microsecondes (pas des millisecondes!) lors de la communication avec un composant externe. Si vous trouvez que l’utilisation de delayMicroseconds() avec un petit nombre (par exemple 10) ne perturbe pas le reste de votre programme, vous pouvez toujours l’utiliser sans trop vous inquiéter. Mais considérez-le comme une exception, pas la règle commune.

Conclusion – Utilisez Arduino delay() avec précaution

En raison de la nature des programmes Arduino, vous devrez souvent ajouter des retards dans votre code, afin que vous puissiez choisir quand exécuter certaines actions et à quelle fréquence vous souhaitez les exécuter.

Les fonctions delay() et delayMicroseconds() sont des fonctions très simples à utiliser et ont été ajoutées au langage Arduino afin que les débutants complets puissent commencer par quelque chose de simple.

Cependant, comme vous l’avez vu dans ce tutoriel, l’utilisation de delay() peut vous coincer très rapidement. Il est donc préférable de comprendre d’abord pourquoi vous en avez besoin, comment l’utiliser, puis comment obtenir le même comportement sans utiliser directement la fonction Arduino delay().

Une fois que vous aurez compris la structure de code pour vous débarrasser de delay(), vous pourrez beaucoup améliorer vos programmes Arduino, et le multitâche deviendra assez facile.

Laisser un commentaire

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