← Retour au chapitre

Étape 3 / 3

Synthèse : LED + Serial + timing

Combiner millis(), Serial et LEDs dans un mini-projet non-bloquant.

Chapitres précédents non terminés
Pour un apprentissage optimal, termine d'abord : PWM : varier l'intensité

Synthèse : tout assembler

Maintenant on combine les deux super-pouvoirs de ce chapitre : millis() pour le timing non-bloquant et Serial Monitor pour la communication. Le résultat : 3 LEDs qui clignotent chacune à leur rythme, et on peut changer leur vitesse en envoyant des commandes série.

C'est ça le multitâche Arduino : pas de threads, pas d'OS — juste un loop() qui tourne ultra-vite et vérifie à chaque passage si c'est le moment d'agir. Simple et efficace.

Schéma du circuit

3 LEDs sur les pins D8, D9 et D10, chacune avec sa résistance 220Ω.

D8 → R → LED rouge | D9 → R → LED jaune | D10 → R → LED verte

D8220ΩD9220ΩD10220Ω

Montage pas à pas

3 LEDs (rouge col 8, jaune col 14, verte col 20) avec chacune sa résistance 220Ω verticale.

++151015202530abcdeabcdefghijfghij151015202530++
100%

Code : millis() + Serial combinés

Le programme gère 3 tâches en parallèle (les 3 LEDs) et écoute les commandes série sans jamais bloquer. Envoie a, b ou c pour basculer entre vitesse lente et rapide.

const int LED_A = 8;
const int LED_B = 9;
const int LED_C = 10;

unsigned long prevA = 0, prevB = 0, prevC = 0;
unsigned long intA = 500, intB = 800, intC = 1200;
bool stA = LOW, stB = LOW, stC = LOW;

void setup() {
  Serial.begin(9600);
  pinMode(LED_A, OUTPUT);
  pinMode(LED_B, OUTPUT);
  pinMode(LED_C, OUTPUT);
  Serial.println("3 LEDs non-bloquantes + Serial");
  Serial.println("Envoie a/b/c pour changer la vitesse");
}

void loop() {
  unsigned long now = millis();

  // LED A
  if (now - prevA >= intA) {
    prevA = now;
    stA = !stA;
    digitalWrite(LED_A, stA);
    Serial.print("A:");
    Serial.println(stA ? "ON" : "OFF");
  }

  // LED B
  if (now - prevB >= intB) {
    prevB = now;
    stB = !stB;
    digitalWrite(LED_B, stB);
  }

  // LED C
  if (now - prevC >= intC) {
    prevC = now;
    stC = !stC;
    digitalWrite(LED_C, stC);
  }

  // Commandes Serial
  if (Serial.available()) {
    char c = Serial.read();
    if (c == 'a') intA = (intA == 500) ? 100 : 500;
    if (c == 'b') intB = (intB == 800) ? 200 : 800;
    if (c == 'c') intC = (intC == 1200) ? 300 : 1200;
  }
}

Simulateur : 3 LEDs non-bloquantes + Serial

Les 3 LEDs clignotent à des intervalles différents (500ms, 800ms, 1200ms). Le log Serial montre chaque changement d'état avec le timestamp.

AA rouge (500ms)
BB jaune (800ms)
CC verte (1200ms)
Prêt. Clique "Lancer" pour démarrer.
0.0s

Exercice final : combine les deux

Dans la boucle loop(), complète les deux vérifications essentielles :

1. Comment vérifier si l'utilisateur a envoyé quelque chose ?

if (()) {

2. Quelle fonction donne le temps actuel sans bloquer ?

unsigned long now = ();

Idées de mini-projets

Avec millis() et Serial, tu peux construire des programmes vraiment interactifs. Voici des idées :

⏱ Chronomètre Serial

Envoie "start" et "stop" pour contrôler un chronomètre. Affiche le temps écoulé avec millis().

🎹 Piano Serial

Chaque touche (a à g) joue une note différente sur un buzzer avec tone(), sans bloquer les LEDs.

🎮 Jeu de réflexe

Une LED s'allume au hasard. Le joueur doit taper "!" le plus vite possible. Affiche le temps de réaction.

📡 Dashboard capteur

Lis un capteur toutes les 2 secondes (sans delay!) et affiche les données formatées dans le Serial Monitor.

À retenir — Chapitre 9

  • delay() bloque tout le programme — à éviter dans les projets complexes.
  • millis() + previousMillis = timing non-bloquant pour du multitâche.
  • Serial.begin(9600) ouvre la communication série. print/println pour envoyer, available/read pour recevoir.
  • Chaque tâche indépendante a besoin de son propre set de variables (prev, interval, state).
  • Le Serial Monitor est le meilleur outil de debug — utilise-le pour vérifier les valeurs, les timings et les états.

Récapitulatif du chapitre 9

  • delay() bloque tout le programme — à éviter pour le multitâche.
  • millis() retourne le temps écoulé sans bloquer — c'est le chronomètre interne.
  • Le pattern if (millis() - prev >= interval) permet de gérer plusieurs tâches en parallèle.
  • Serial.begin(9600) ouvre la communication série — obligatoire dans setup().
  • Serial.print() envoie des données vers le PC — c'est l'outil de debug n°1.
  • Serial.available() + Serial.read() permettent de recevoir des commandes du PC.

Tu maîtrises maintenant le timing non-bloquant et la communication série. Au prochain chapitre, tu découvriras les LED RGB et le mélange de couleurs !

Valide cette étape quand tu as terminé la lecture et la manipulation.

← Exo 11 : Parle-moi — Serial Monitor Aller au quiz du chapitre →

Electro-Lab - support pédagogique Arduino (MVP).

IFOSUP Wavre - Cours Drones et Robotique.