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)
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é.
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)
#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.
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).
// 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);
}
- 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>puisservo.attach()etservo.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.