Leçon 5 / 8
Leçon 05 · Arduino

PWM et contrôle de LED / moteur

La PWM : principe de modulation de largeur d'impulsion

La PWM (Pulse Width Modulation, ou modulation de largeur d'impulsion) est une technique qui consiste à faire basculer rapidement une sortie numérique entre HIGH et LOW. En jouant sur la proportion du temps passé à l'état haut, on simule une tension intermédiaire.

Deux paramètres clés définissent un signal PWM :

  • La fréquence — nombre de cycles par seconde (en Hz). Sur l'Arduino Uno, elle est d'environ 490 Hz sur la plupart des pins PWM (980 Hz sur les pins 5 et 6).
  • Le rapport cyclique (duty cycle) — pourcentage du temps pendant lequel le signal est à l'état haut. 0 % = toujours bas (éteint), 100 % = toujours haut (plein régime), 50 % = demi-puissance.

Concrètement : une LED connectée à une pin PWM avec un rapport cyclique de 50 % semble deux fois moins lumineuse qu'à 100 %, car elle ne reçoit de l'énergie qu'à moitié du temps. L'œil humain (et un moteur) perçoit la valeur moyenne.

Pins PWM sur l'Arduino Uno

Toutes les pins numériques ne supportent pas la PWM. Sur l'Arduino Uno, les pins PWM sont repérées par le symbole ~ sur la carte :

  • Pins PWM : 3, 5, 6, 9, 10, 11
  • Les autres pins numériques (0, 1, 2, 4, 7, 8, 12, 13) ne supportent que HIGH / LOW.

Astuce visuelle : sur l'Arduino Uno, les pins PWM sont précédées d'un tilde ~ sérigraphié à côté du numéro (ex. ~3, ~5, etc.). Repère-le avant de câbler.

analogWrite(pin, 0–255) : varier la luminosité d'une LED

La fonction analogWrite() génère un signal PWM sur une pin compatible. Elle prend deux arguments :

  • pin — numéro d'une pin PWM (3, 5, 6, 9, 10 ou 11 sur l'Uno)
  • value — rapport cyclique de 0 (0 %, éteint) à 255 (100 %, plein)
Arduino C++ — analogWrite basique
const int LED_PIN = 9;   // pin PWM ~9

void setup() {
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  analogWrite(LED_PIN, 0);    // LED éteinte
  delay(1000);
  analogWrite(LED_PIN, 128);  // LED à ~50 % de luminosité
  delay(1000);
  analogWrite(LED_PIN, 255);  // LED à pleine luminosité
  delay(1000);
}

Fade in / fade out : boucle avec analogWrite

En incrémentant ou décrémentant progressivement la valeur passée à analogWrite() dans une boucle, on obtient un effet de fondu — la LED monte et descend doucement en luminosité.

Arduino C++ — Fade in / out
const int LED_PIN = 9;

void setup() {
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  // Fade in : 0 → 255
  for (int brightness = 0; brightness <= 255; brightness++) {
    analogWrite(LED_PIN, brightness);
    delay(8);  // ~2 secondes pour monter
  }

  // Fade out : 255 → 0
  for (int brightness = 255; brightness >= 0; brightness--) {
    analogWrite(LED_PIN, brightness);
    delay(8);
  }
}

Servomoteur : Servo.h

Un servomoteur est un moteur à position contrôlée : on lui indique un angle (0° à 180°) et il s'y place précisément. La bibliothèque Servo.h, incluse par défaut dans l'IDE Arduino, gère le signal PWM spécifique (impulsions de 1 ms à 2 ms).

Câblage typique d'un servo :

  • Fil rouge → 5 V
  • Fil marron / noir → GND
  • Fil orange / jaune (signal) → n'importe quelle pin numérique (ex. pin 9)
Arduino C++ — Servomoteur
#include <Servo.h>

Servo monServo;  // crée un objet Servo

void setup() {
  monServo.attach(9);   // connecte le servo à la pin 9
}

void loop() {
  monServo.write(0);    // position 0°
  delay(1000);
  monServo.write(90);   // position 90° (centre)
  delay(1000);
  monServo.write(180);  // position 180°
  delay(1000);
}

Moteur DC avec transistor NPN

Un moteur DC consomme bien plus de courant qu'une sortie Arduino ne peut en fournir (max ~40 mA par pin). On utilise un transistor NPN (ex. 2N2222, BC547) comme interrupteur commandé : la pin Arduino pilote la base du transistor, qui laisse ou coupe le courant vers le moteur.

Schéma de câblage :

  • Collecteur du transistor → borne – du moteur
  • Émetteur → GND
  • Base → résistance 1 kΩ → pin PWM Arduino
  • Borne + du moteur → alimentation externe (ex. 9 V ou 12 V)
⚠️

Diode flyback obligatoire ! Un moteur DC est une charge inductive. Quand il s'éteint, il génère une surtension inverse (back-EMF) qui peut détruire le transistor — et l'Arduino. Place une diode 1N4007 en antiparallèle sur le moteur : anode côté GND (–), cathode côté alimentation (+). Elle dérivera la surtension sans dommage.

Arduino C++ — Moteur DC via transistor NPN
const int MOTEUR_PIN = 9;  // pin PWM ~9 → base du transistor

void setup() {
  pinMode(MOTEUR_PIN, OUTPUT);
}

void loop() {
  // Accélération progressive
  for (int vitesse = 0; vitesse <= 255; vitesse += 5) {
    analogWrite(MOTEUR_PIN, vitesse);
    delay(50);
  }
  delay(2000);

  // Arrêt progressif
  for (int vitesse = 255; vitesse >= 0; vitesse -= 5) {
    analogWrite(MOTEUR_PIN, vitesse);
    delay(50);
  }
  delay(2000);
}

Driver L298N : pont en H pour deux moteurs

Le module L298N intègre un pont en H double : il peut alimenter deux moteurs DC indépendamment, contrôler leur vitesse (via PWM) et leur direction (avant / arrière). C'est le composant de base des petits robots à deux roues.

Brochage du module L298N :

  • ENA / ENB — enable des moteurs A et B. Connecté à une pin PWM → contrôle la vitesse.
  • IN1 / IN2 — direction du moteur A (ex. IN1=HIGH, IN2=LOW → avant ; IN1=LOW, IN2=HIGH → arrière).
  • IN3 / IN4 — direction du moteur B (même logique).
  • 12V — alimentation des moteurs (jusqu'à 12 V, séparée de l'Arduino).
  • GND — masse commune avec l'Arduino.
  • 5V — sortie 5 V régulée (peut alimenter l'Arduino si jumper présent).
Arduino C++ — Driver L298N : vitesse + direction
// Moteur A connecté à ENA (pin 9, PWM), IN1 (pin 7), IN2 (pin 8)
const int ENA = 9;
const int IN1 = 7;
const int IN2 = 8;

void setup() {
  pinMode(ENA, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
}

// Avancer à une vitesse donnée (0-255)
void avancer(int vitesse) {
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  analogWrite(ENA, vitesse);
}

// Reculer à une vitesse donnée (0-255)
void reculer(int vitesse) {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  analogWrite(ENA, vitesse);
}

// Arrêt
void arreter() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  analogWrite(ENA, 0);
}

void loop() {
  avancer(200);   // ~78 % de vitesse
  delay(2000);
  arreter();
  delay(500);
  reculer(150);
  delay(2000);
  arreter();
  delay(500);
}
// À retenir
  • La PWM simule une tension variable en faisant basculer rapidement une sortie entre HIGH et LOW.
  • Sur l'Arduino Uno, les pins PWM sont les 3, 5, 6, 9, 10, 11 (repérées par ~).
  • analogWrite(pin, 0–255) — 0 = éteint, 255 = plein régime, 128 ≈ 50 %.
  • Pour un servomoteur, utilise #include <Servo.h> puis servo.attach() et servo.write(angle).
  • Moteur DC = transistor NPN + diode flyback 1N4007 obligatoire pour protéger le circuit.
  • Le driver L298N (pont en H) permet de contrôler vitesse et direction de deux moteurs DC.