📡 Microcontrôleurs & IoT

🛠️ TP 1 — Module 3

Entrées / Sorties Numériques

PlatformIO · Arduino C++ · GPIO · LED · Bouton

Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico
📡 Microcontrôleurs & IoT

📝 Changelog — V0.1.2

  • Ajout note analogWrite() ESP32 core ≥ 2.0 (caveat ledc sur core 1.x).
  • (V0.1.1) Ajout slides Bibliothèque Leds et test-01.cpp.
Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico
📡 Microcontrôleurs & IoT

🆚 IDE Arduino vs PlatformIO

Critère Arduino IDE PlatformIO (VS Code)
Gestion des librairies Manuel platformio.ini automatique
Completion de code Basique IntelliSense complet
Débogage Serial.print Débogueur pas-à-pas
Gestion de projets 1 fichier Projet structuré avec src/lib/test
Contrôle de version Difficile Git natif
Multi-cartes 1 à la fois Plusieurs targets

PlatformIO = l'IDE professionnel pour l'embarqué.

Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico
📡 Microcontrôleurs & IoT

📁 Structure d'un projet PlatformIO

Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico
📡 Microcontrôleurs & IoT

⚙️ Le fichier platformio.ini

[env:esp32dev]
platform  = espressif32
board     = esp32dev
framework = arduino

; Vitesse du moniteur série
monitor_speed = 115200

; Dépendances (bibliothèques)
lib_deps =
    bblanchon/ArduinoJson @ ^6.21.0
    knolleary/PubSubClient @ ^2.8

; Filtres de moniteur série (décodage des exceptions)
monitor_filters = esp32_exception_decoder

Un seul fichier remplace des dizaines de clics dans l'IDE. 🎯

Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico
📡 Microcontrôleurs & IoT

🔄 La boucle Arduino : setup() + loop()

Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico
📡 Microcontrôleurs & IoT

📌 Les fonctions GPIO essentielles

// Configurer une broche
pinMode(pin, OUTPUT);      // Sortie (LED, relais, moteur)
pinMode(pin, INPUT);       // Entrée (capteur, inter)
pinMode(pin, INPUT_PULLUP);// Entrée avec résistance tirage interne

// Écrire une valeur
digitalWrite(pin, HIGH);   // +3.3V sur la broche
digitalWrite(pin, LOW);    // 0V sur la broche

// Lire une valeur
int val = digitalRead(pin); // Retourne HIGH (1) ou LOW (0)

// PWM (simulation analogique)
analogWrite(pin, 128);      // 50% duty cycle (0-255)

⚠️ analogWrite() sur ESP32 : disponible nativement depuis Arduino ESP32 core ≥ 2.0 (wrapper ledc).
Sur core 1.x, utiliser ledcSetup(channel, freq, res) + ledcAttachPin(pin, ch) + ledcWrite(ch, duty) à la place.

Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico
📡 Microcontrôleurs & IoT

🔌 Le Pull-up interne : INPUT_PULLUP

Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico
📡 Microcontrôleurs & IoT

💡 Premier programme complet

#include <Arduino.h>

const int LED_PIN = 26;
const int BTN_PIN = 12;

void setup() {
    Serial.begin(115200);            // Démarrage moniteur série
    pinMode(LED_PIN, OUTPUT);        // LED en sortie
    pinMode(BTN_PIN, INPUT_PULLUP);  // Bouton avec pull-up interne
    Serial.println("Démarrage OK !");
}

void loop() {
    if (digitalRead(BTN_PIN) == LOW) { // LOW = bouton pressé (pull-up)
        digitalWrite(LED_PIN, HIGH);   // Allumer la LED
        Serial.println("Bouton pressé !");
    } else {
        digitalWrite(LED_PIN, LOW);    // Éteindre la LED
    }
}
Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico
📡 Microcontrôleurs & IoT

🔍 Analysons le code

if (digitalRead(BTN_PIN) == LOW) {

Pourquoi LOW = pressé ?

Avec INPUT_PULLUP, la broche est maintenue à 3.3V (HIGH) par la résistance interne.
Quand le bouton est pressé → court-circuit vers GND (LOW).

Convention inversée : LOW signifie actif.
C'est la norme industrielle pour les boutons.

Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico
📡 Microcontrôleurs & IoT

📟 Le Moniteur Série

Votre outil de débogage numéro 1 sur MCU :

Serial.begin(115200);         // Initialiser à 115200 bauds
Serial.println("Texte");      // Message + saut de ligne
Serial.print(variable);       // Afficher une variable
Serial.printf("T=%d°C\n", t); // Format printf

Dans PlatformIO :

  • Raccourci : Ctrl + Alt + S pour ouvrir le moniteur
  • Ou : icône 🔌 en bas de l'écran
  • Assurez-vous que monitor_speed = 115200 dans platformio.ini
Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico
📡 Microcontrôleurs & IoT

⏱️ Timer non-bloquant

Ne jamais utiliser delay() dans un vrai projet — ça bloque toute la boucle !

// ❌ Mauvaise pratique : delay() bloque tout
digitalWrite(LED_PIN, HIGH);
delay(500);   // ← le programme est figé pendant 500ms
digitalWrite(LED_PIN, LOW);

// ✅ Bonne pratique : millis() non-bloquant
unsigned long previousMs = 0;
const long interval = 500;

void loop() {
    unsigned long currentMs = millis();
    if (currentMs - previousMs >= interval) {
        previousMs = currentMs;
        // Basculer la LED
        digitalWrite(LED_PIN, !digitalRead(LED_PIN));
    }
    // Le reste du programme peut tourner librement ici !
}
Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico
📡 Microcontrôleurs & IoT

📦 Bibliothèque Leds — abstraction courante

En pratique, on regroupe toutes les sorties dans un objet Leds :

#include <leds.h>

const int ledPins[] = {26, 25, 33, 32, 27, 23, 22, 21};
//                     ERR PARTOK  UP DWN STAMP UP DWN EJECT
const int numLeds = sizeof(ledPins) / sizeof(ledPins[0]); // 8

Leds leds(ledPins, numLeds);   // constructeur reçoit tableau + taille

void setup() {
    leds.setup();               // boucle interne → pinMode(pin, OUTPUT)
    leds.blinkAll(500, 3);      // séquence de démarrage : 3 cycles
}
  • setup() : configure chaque broche en OUTPUT
  • blinkAll(ms, n) : allume chaque LED n fois durant ms ms (delay interne, réservé à l'init)
  • blinkSync(pin, ms) : clignote une seule broche

➡️ Source complète : res/lib/leds/leds.h

Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico
📡 Microcontrôleurs & IoT

🚀 test-01.cpp — point de départ du TP 1

#include <Arduino.h>
#include <leds.h>

// Broches de sortie
const int ledPins[] = {26, 25, 33, 32, 27, 23, 22, 21};
const int numLeds   = sizeof(ledPins) / sizeof(ledPins[0]);
const int sw1Pin    = 12;   // bouton — câblé avec pull-up interne

Leds leds(ledPins, numLeds);

bool isButtonPressed() { return digitalRead(sw1Pin) != HIGH; }

void setup() {
    Serial.begin(115200);
    leds.setup();
    leds.blinkAll(500, 5);           // 5 clignotements au démarrage
    pinMode(sw1Pin, INPUT_PULLUP);
    Serial.println(isButtonPressed() ? "BTN pressé" : "BTN relâché");
}

void loop() {
    Serial.println(isButtonPressed() ? "BTN pressé" : "BTN relâché");
    delay(50);
}

⬆️ Fichier disponible dans res/src/test-01/test-01.cpp

Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico
📡 Microcontrôleurs & IoT

🏋️ Exercice 1 — Clignotement non-bloquant

Objectif : Faire clignoter une LED à 2 Hz (500ms ON / 500ms OFF) sans delay(), pendant que le Serial affiche un compteur toutes les secondes.

Attendu :

  1. LED clignote régulièrement
  2. Moniteur série affiche : Compteur : 1, Compteur : 2...
  3. Appuyer sur le bouton change la fréquence de clignotement (100ms ↔ 500ms)

Aide : Utilisez deux timers basés sur millis().

Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico
📡 Microcontrôleurs & IoT

🏋️ Exercice 2 — Morse SOS

Objectif : Programmer la LED pour émettre SOS en code Morse en boucle.

S = ···   (3 points courts : 200ms ON / 200ms OFF)
O = —— (3 traits longs  : 600ms ON / 200ms OFF)
S = ···   (3 points courts)
         [pause 1 seconde entre chaque SOS]

Contrainte : Zéro delay(). Utilisez une machine à états et millis().

Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico
📡 Microcontrôleurs & IoT

🎯 Synthèse du TP 1

Concept Retenir
setup() Initialisation unique au démarrage
loop() Boucle infinie, jamais bloquante idéalement
pinMode() Configurer direction de la broche
INPUT_PULLUP LOW = actif (bouton pressé)
millis() Timer non-bloquant (jamais delay())
Serial.println() Débogage via port série

Prochain TP → Programmation Orientée Objet pour structurer le code embarqué

Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico
📡 Microcontrôleurs & IoT

🧑‍💻 Questions ?

TP 1 — Entrées/Sorties Numériques
Réda BOUREBABA & Sébastien Antonico

Microcontrôleurs & IoT - V0.1.2 - 12/03/2026 04:02 - Réda BOUREBABA r.bourebaba@ynov.com & Sébastien Antonico