Le signal PWM - Pulse Width Modulation
PWM Arduino - Pulse Width Modulation
Cette technique s'appelle la Modulation de Largeur d'Impulsion (MLI) – ou Pulse Width Modulation (PWM).
Le signal PWM est caractérisé par :
- sa fréquence (environ 500Hz par défaut pour un Arduino)
- son amplitude (+5V sur un port digital de l'Arduino)
Lorsque l'on souhaite varier la vitesse d'un moteur à courant continu ou modifier la luminosité d'une LED ou encore pour changer les couleurs d'une LED RGB, il est nécessaire d'avoir une variation de la tension.
Cette variation de la tension est réalisable avec certaines sorties digitales de l'Arduino afin de créer un pseudo signal analogique en utilisant la PWM.
Explication du signal PWM
Pour obtenir une modification de la valeur moyenne de la tension, le PWM fait faire varier le rapport cyclique.
Le récepteur (Moteur, led, etc …) ne percevra plus l’état LOW ou l’état HIGH, mais une multitude de tensions intermédiaires qui varient de 0v à +5v avec une résolution de 256 valeurs possibles (0 à 255).
Ce pseudo signal analogique est possible car la fréquence de commutation entre les niveaux HAUT et BAS est élevée : 500 Hz soit 500 fois par seconde.
Le changement d'état étant très rapide, le récepteur y est donc insensible, comme notre œil est insensible au clignotement des tubes fluorescents avec le signal alternatif 50Hz.
Pour déterminer la tension moyenne que l’on souhaite appliquer au récepteur (Moteur,led, etc ...) il faudra modifier le rapport cyclique, c'est-à-dire la durée du maintient au niveau HIGH (ou HAUT) du signal de sortie.
Ainsi, le rapport cyclique pourra varier de 0% (tension 0v) jusqu'à 100% (tension à +5v).
Pour l'Arduino, ce n'est pas une valeur comprise entre 0 et 100 qui sera appliquée, mais une valeur numérique comprise entre 0 et 255 (8 bits).
En faisant une règle de trois ou un produit en croix, il est possible de déterminer pour chaque valeur (PWM) compris entre 0 et 255 la valeur du rapport cyclique ou la tension moyenne en sortie de l'Arduino Uno.
(Tension +5v / 255) * La valeur du PWM = Tension de sortie
pour 10% (+5v / 255) * 33 = +0,65v (*) environ
pour 50% (+5v / 255) * 127 = +2,49v (*) environ
pour 90% (+5v / 255) * 230 = +4,5v (*) environ
Je vous conseille si possible, de mesurer la tension de sortie avec un multimètre afin d'avoir la valeur exacte.
Rapport cyclique / Valeur PWM / Tension de sortie
Rapport cyclique | Valeur PWM | Tension de sortie |
---|---|---|
0 % | 0 | 0v |
10 % | 33 | +0,6v |
50 % | 127 | +2,5v |
90 % | 230 | +4,5v |
100 % | 255 | +5v |
Broche PWM de l'Arduino
- D3, D5, D6, D9, D10 et D11
PWM - digitalWrite - analogWrite
Les broches PWM, peuvent,être contrôler de deux manières :
Avec digitalWrite ou analogWrite.
La commande digitalWrite va permettre d'allumer la broche à +5v ou l'éteindre à 0v,
alors que la commande analogWrite permet de faire varier la tension comme pour allumer une led à la moitié de sa puissance ou controler un moteur CC.
Pour le PWM, nous utiliserons les commandes:
- digitalWrite(pin,HIGH) pour mettre à l'état HAUT la pin
- digitalWrite(pin,LOW) pour mettre à l'état BAS la pin
- analogWrite(pin, valeur_PWM) pour faire varier la tension avec valeur_PWM
Le signal Digital et PWM
Avec le simulateur de Tinkercad, voici une comparaison entre le signal Digital et le signal PWM
Oscilloscope gauche - Signal PWM
L'oscilloscope de gauche affiche un signal PWM
Led Verte en pin 9 (PWM)
Le code allume la led en PWM
- analogWrite(led_PWM,50);
- analogWrite(led_PWM,100);
- analogWrite(led_PWM,150);
Oscilloscope droite - Signal Digital
L'oscilloscope de droite affiche un signal Digital carré
Led Rouge en pin 7
Le code allume et éteint la led
- digitalWrite(led,HIGH);
- digitalWrite(led,LOW);
int tempo = 100;
int led = 7; // pin digital - Led ROUGE
int led_PWM = 9; // pin digital PWM - Led VERTE
void setup()
{
pinMode(led, OUTPUT);
pinMode(led_PWM, OUTPUT);
}
void loop()
{
digitalWrite(led, HIGH); // Signal digital carré
delay(tempo);
digitalWrite(led, LOW);
delay(tempo);
analogWrite(led_PWM,50); // Signal PWM
delay(tempo);
analogWrite(led_PWM,100);
delay(tempo);
analogWrite(led_PWM,150);
delay(tempo);
}