PWM - La modulation de la largeur d'impulsion

Introduction
Arduino permet de faire du contrôle de sortie en digital (tout ou rien) ou en analogique (de 0 à 5v en 256 paliers).
Cela peu sembler amplement suffisant... mais présente néanmoins des limites importantes.

Arduino est également capable de faire du contrôle de sortie par "modulation de largeur d'impulsion".
Cette méthode permet de combler les manquements du contrôle analogique.

Les limitations du contrôle analogique
Lorsque l'on désire contrôler la luminosité d'une Led ou encore la vitesse d'un moteur DC, le fait d'appliquer une tension plus faible ou plus importante (contrôle analogique) n'implique une obtention des résultats voulu.
En effet, une luminosité plus faible pour une led n'est absolument pas garanti (car c'est une diode).
De même, le démarrage plus lent du moteur ou le contrôle de sa vitesse ne sont pas assurés non plus (car il a son inertie et ses conditions optimales de fonctionnement).

Le contrôle par longueur d'impulsion
Reprenons l'exemple de la led.
Imaginons maintenant qu'au lieu de l'allumer 100% du temps chaque 1/10 de secondes, nous décidions de l'allumer cette Led que 50% du temps.
Donc, chaque 1/10 de seconde, la led est éteinte 1/20 de seconde et totalement allumée l'autre 1/20 de seconde.  
A votre avis, que se passerait t'il?
Et bien, elle aurait l'air moins lumineuse... la persistance rétinienne nous empêchant de nous rendre compte qu'elle est en fait éteinte la moitié du temps.
Ainsi donc, si l'on allume la led 75% du temps chaque 1/10 de seconde, la led serait plus lumineuse mais cependant toujours moins que si elle était allumée 100% du temps.

Cela fonctionnerait à l'identique pour un moteur DC.

C'est le principe de "la modulation par largeur d'impulsion", appliquer la tension de sortie qu'une partie du temps... mais en faisant le contrôle/variation à une telle fréquence (tellement souvent sur une période d'une seconde) qu'il est impossible de s'en rendre à l'oeil nu.

Le graphique ci-dessous montre la modulation du signal de sortie (PWM) en fonction du pourcentage du cycle de service.

Source: PWM tutoriel on arduino.cc
Contrôle PWM avec Arduino
Activation du mode PWM
Il n'y a pas d'instruction particulière pour activer le mode PWM.
Par contre, il ne faut pas initialiser la pin comme Output avant d'utiliser l'instruction analogWrite().
Il faut bien entendu sélectionner une pin PWM (3,5,6, 9, 10, 11) au lieu d'une pin analogique (2,4,7,8,12,13).

Limite des pin 5,6 en PWM
Attention: suite à a une contrainte technique (voir cet article à section "know issues"), le contrôle PWM sur les pin 5 et 6 est inconstant pour les valeurs analogWrite de 0 à 10.
En conséquence, une valeur 0 sur les pin 5 et 6 n'assure pas forcement un output à LOW!

Note de calcul
La valeur passée à analogWrite indique quel est la proportion du cycle de service durant lequel la sortie est activée (voir graphique ci-dessus).
Comme la valeur de analogWrite ne peut varier que de 0 à 255.
Un cycle de service de 50% du temps se calcule comme suit:
    50% de 255, soit 255 * 0.5 = 127.5 (donc 127 pour l'instruction analogWrite).

Un cycle de service de 80% du temps se calcule comme suit:
    80% de 255, soit 255 * 0.8 = 204 (donc 204 pour l'instruction analogWrite).

Cycle de service
La fréquence du signal PWM est d'environ ~490Hertz (soit un cycle de service de +/- 2 millisecondes).

Plus d'informations