--- title: "Module 2 — Entrées/Sorties numériques & LED RGB NeoPixel" --- ## Objectifs du module - Maîtriser `digitalWrite()` et `digitalRead()` sur l'ESP32-S3. - Comprendre les résistances de tirage (pull-up / pull-down) et l'anti-rebond logiciel. - Réaliser un chenillard de LED et une lecture de bouton-poussoir. - Piloter la LED RGB NeoPixel intégrée à la carte (protocole WS2812, bibliothèque Adafruit_NeoPixel). ## 1. Rappels : sorties numériques Une broche GPIO configurée en sortie (OUTPUT) ne peut prendre que deux états électriques : HIGH (3,3 V) ou LOW (0 V). C'est la base de tout pilotage de LED, relais, transistor de puissance, etc. ```cpp #define LED_PIN 4 void setup() { pinMode(LED_PIN, OUTPUT); } void loop() { digitalWrite(LED_PIN, HIGH); delay(300); digitalWrite(LED_PIN, LOW); delay(300); } ``` ## 2. Rappels : entrées numériques et résistances de tirage Une entrée numérique non connectée (« flottante ») peut lire un état aléatoire à cause du bruit électrique. Il faut donc fixer son état par défaut avec une résistance de tirage : - `INPUT_PULLUP` : la broche est tirée à 3,3 V par défaut (état HIGH) ; le bouton doit relier la broche à GND pour donner un état LOW à l'appui. - `INPUT_PULLDOWN` : disponible sur l'ESP32-S3 (contrairement à l'AVR classique) — la broche est tirée à 0 V par défaut. ```cpp #define BUTTON_PIN 5 void setup() { Serial.begin(115200); pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { int etat = digitalRead(BUTTON_PIN); if (etat == LOW) { Serial.println("Bouton presse"); } delay(50); } ``` ::: {.callout-note title="Anti-rebond (debounce)"} Un bouton mécanique génère plusieurs transitions HIGH/LOW parasites en quelques millisecondes lors de l'appui. Un simple `delay(50)` après lecture suffit pour un usage pédagogique ; pour un projet robuste, on mesure le temps écoulé avec `millis()` plutôt que d'utiliser `delay()` (voir Module 6 sur les interruptions et timers). ::: ## 3. Exercice guidé : chenillard de LED Câblez 4 LED (avec résistances de 220 Ω) sur 4 GPIO libres, puis reproduisez un effet de chenillard : ```cpp const int leds[] = {4, 5, 6, 7}; const int nbLeds = 4; void setup() { for (int i = 0; i < nbLeds; i++) { pinMode(leds[i], OUTPUT); } } void loop() { for (int i = 0; i < nbLeds; i++) { digitalWrite(leds[i], HIGH); delay(150); digitalWrite(leds[i], LOW); } } ``` ## 4. La LED RGB NeoPixel intégrée Contrairement à une LED classique qui ne prend que deux états (allumé/éteint) ou une intensité en PWM, la LED intégrée sur la plupart des cartes ESP32-S3 DevKit est une LED adressable de type WS2812 (aussi appelée NeoPixel). Elle intègre son propre contrôleur et se pilote avec un protocole série à un seul fil, où chaque LED reçoit une trame de 24 bits (8 bits rouge, 8 bits vert, 8 bits bleu). ### 4.1 Pourquoi ce n'est pas un simple digitalWrite Le protocole WS2812 impose un timing très précis (de l'ordre de la centaine de nanosecondes) pour distinguer un bit 0 d'un bit 1. Le générer « à la main » avec digitalWrite serait peu fiable ; on utilise donc une bibliothèque dédiée qui exploite les ressources matérielles du microcontrôleur pour respecter ce timing. ### 4.2 Installation de la bibliothèque - Dans l'IDE : Croquis \> Inclure une bibliothèque \> Gérer les bibliothèques. - Rechercher « Adafruit NeoPixel » et installer la dernière version (ainsi que sa dépendance Adafruit BusIO si demandée). ::: {.callout-note title="Identifier la broche de la LED"} Sur la plupart des cartes ESP32-S3-DevKitC-1, la LED NeoPixel est reliée au GPIO48 et nécessite d'alimenter une broche annexe (souvent GPIO47 sur certaines révisions) pour l'activer. Vérifiez impérativement le schéma de votre carte : certains modèles utilisent GPIO38 ou un autre GPIO. Le code ci-dessous utilise une constante `NEOPIXEL_PIN` à adapter. ::: ### 4.3 Premier programme : allumer la LED en rouge ```cpp #include #define NEOPIXEL_PIN 48 // A adapter selon votre carte #define NB_PIXELS 1 Adafruit_NeoPixel pixels(NB_PIXELS, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800); void setup() { pixels.begin(); pixels.setBrightness(50); // Luminosite 0-255, a limiter pour ne pas eblouir pixels.setPixelColor(0, pixels.Color(255, 0, 0)); // Rouge pixels.show(); } void loop() { } ``` ### 4.4 Exercice : cycle de couleurs et respiration Objectif : faire défiler plusieurs couleurs, puis réaliser un effet de « respiration » (variation progressive de la luminosité) sur une couleur fixe. ```cpp #include #define NEOPIXEL_PIN 48 Adafruit_NeoPixel pixel(1, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800); void setup() { pixel.begin(); pixel.setBrightness(80); } void loop() { // Cycle de couleurs pixel.setPixelColor(0, pixel.Color(255, 0, 0)); pixel.show(); delay(400); pixel.setPixelColor(0, pixel.Color(0, 255, 0)); pixel.show(); delay(400); pixel.setPixelColor(0, pixel.Color(0, 0, 255)); pixel.show(); delay(400); // Effet respiration en bleu for (int b = 0; b <= 255; b += 5) { pixel.setBrightness(b); pixel.setPixelColor(0, pixel.Color(0, 0, 255)); pixel.show(); delay(15); } for (int b = 255; b >= 0; b -= 5) { pixel.setBrightness(b); pixel.setPixelColor(0, pixel.Color(0, 0, 255)); pixel.show(); delay(15); } } ``` ## 5. Exercice final : bouton + NeoPixel Combinez les notions du module : à chaque appui sur un bouton-poussoir (avec `INPUT_PULLUP` et anti-rebond), la LED NeoPixel doit changer de couleur en suivant un cycle défini (rouge → vert → bleu → blanc → éteint → rouge...). | Étape | Comportement attendu | |---------|------------------------------------| | Démarrage | LED éteinte | | 1er appui | LED rouge | | 2e appui | LED verte | | 3e appui | LED bleue | | 4e appui | LED blanche | | 5e appui | Retour à éteint, le cycle recommence | ## Checklist de fin de module - [ ] Je sais configurer et lire un bouton avec `INPUT_PULLUP`. - [ ] Je comprends pourquoi un debounce est nécessaire. - [ ] J'ai identifié la broche exacte de la LED NeoPixel sur ma carte. - [ ] J'ai réalisé l'exercice combinant bouton et changement de couleur.