Ardu? No!Initiation ≫ while

while

Nous avions déjà vu une boucle, le for que l'on utilise généralement quand le nombre de boucles est connu à l'avance. Nous allons voir une deuxième boucle que l'on utilise au contraire quand le nombre d'itération n'est pas forcément connu à l'avance.

Reprenons le programme qui fait clignoter la led:

void setup() {
  pinMode(LED_BUILTIN, OUTPUT); // Configuration de la broche de la led
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH); // Allumer la LED
  delay(500);
 
  digitalWrite(LED_BUILTIN, LOW); // Éteindre la LED
  delay(500);
}

Dans la page précédente, nous n'avons pas gardé la structure première étape "Allumer la led et attendre", deuxième étape "Éteindre et attendre". Le code a été complètement transformé pour qu'il boucle sans arrêt. Dans cette page, nous allons au contraire garder la structure en deux étapes, et nous allons afficher des nombres aléatoires pendant les 500ms correspondant au delay(500); . Il s'agit de remplacer la fonction bloquante delay par du code permettant de faire autre chose.

Tant que

Ce que nous allons faire s'exprime simplement en français par tant que 500ms ne se sont pas écoulées, on envoie un nombre aléatoire. Cela ressemble un peu au if mais ce dernier ne fait l'instruction suivante qu'une seule fois si la condition est vraie, alors qu'avec le while (c'est le mot anglais pour tant que), l'instruction suivante sera répétée tant que la condition est vraie.

La femme d'un informaticien lui disait habituellement "si tu va au marché, achète une pomme, si il y en a à vendre bien sûr!". Et cela s'est toujours bien passé (condition "SI"). Mais un jour, par erreur, elle lui a dit "Va au marché pour acheter un poulet". Puis pensant à la pomme, elle a rajouté "Et tant que tu y es, achète aussi une pomme, si il y en a à vendre bien sûr!". Grave erreur! L'informaticien est allé au marché, mais dès qu'il est arrivé, il a acheté une pomme. Mais la condition tant que étant toujours vraie, notre informaticien en a acheté encore une. Il ne pouvait pas s'arrêter d'acheter une pomme à la fois car il était toujours au marché...

La structure du while est:

while (<condition>) <instruction>;

Cela ressemble un peu au if, mais la clause else ne peut pas exister. Sinon, la condition est entre parenthèse et si on veut exécuter plusieurs instructions, il faut mettre une instruction composée (suite d'instructions entre accolades).

Notre programme

Reprenons la phrase tant que 500ms ne se sont pas écoulées, on envoie un nombre aléatoire. Nous avons déjà vu la condition. Ce peut être par exemple:

millis() - dernierChangement <= DEMI_PERIODE

Il faudra avant initialiser dernierChangement comme on l'a fait dans la page précédente. Le remplacement des deux premières lignes de code de loop() étaient:

digitalWrite(LED_BUILTIN, HIGH); // Allumer la LED
delay(500);

vont être maintenant:

digitalWrite(LED_BUILTIN, HIGH); // Allumer la LED
dernierChangement = millis();
while (millis() - dernierChangement <= DEMI_PERIODE) // Pendant 500 ms
  Serial.println(random(100)); // Affiche un nombre de 0 à 99

J'ai écrit le while sur deux lignes, car le commentaire "Affiche..." n'est valable que pour le Serial.print....

On s'inspirera de la page précédente pour l'initialisation (le setup), et reprenez les unsigned long. Je vous laisse compléter l'autre moitié de loop. Aide?const word DEMI_PERIODE = 500; word dernierChangement; void setup() { pinMode(LED_BUILTIN, OUTPUT); // Configuration de la broche de la led Serial.begin(115200); // Pour pouvoir afficher dans la console } void loop() { digitalWrite(LED_BUILTIN, HIGH); // Allumer la LED dernierChangement = millis(); while (word(millis()) - dernierChangement <= DEMI_PERIODE) // Pendant 500 ms Serial.println(random(100)); // Affiche un nombre de 0 à 99 digitalWrite(LED_BUILTIN, LOW); // Éteindre la LED dernierChangement = millis(); while (word(millis()) - dernierChangement <= DEMI_PERIODE) // Pendant 500 ms Serial.println(random(100)); // Affiche un nombre de 0 à 99 }