XV. Projet 7 : PWM, variation en douceur d'une LED▲
Le plus simple moyen de faire varier la luminosité d'une LED, c'est de faire varier le courant qui la traverse. Mais lorsqu'elle est branchée sur la broche d'un Arduino, ce n'est pas possible : les broches 1 à 13 sont en effet numériques. C'est-à-dire qu'elles n'ont que deux états : 0 ou 1 ; allumé ou éteint. Alors pour faire varier la luminosité d'une LED, on va utiliser une fonction appelée PWM : Pulse Width Modulation, soit modulation de largeur d'impulsions. Il s'agit de faire varier les périodes hautes (allumé) et basses (éteint) des broches à grande fréquence. Ainsi, lors d'un cycle de 25 % en position haute et 75 % en position basse, la LED sera moins brillante que pour un cycle à 50 %/50 %.
En d'autres termes, cela signifie qu'on va faire clignoter très vite les LED ; tellement vite que l'œil ne percevra qu'une lumière continue. Mais plus on augmentera la durée des périodes où la LED est éteinte, moins il y aura de lumière émise ; et donc moins la LED semblera brillante.
Les broches capables de supporter du PWM sont identifiées par un « ~ ». Il s'agit des broches 3, 5, 6, 9, 10,11.
Par distinction, au lieu d'utiliser l'instruction digitalWrite
, pour utiliser le PWM, on utilise analogWrite
.
La valeur du PWM s'étend sur 256 paliers, de 0
(=0 %) à 255
(=100 %). On peut ainsi définir la valeur PWM souhaitée avec la formule suivante :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
/*
Code 7 - Edurobot.ch, destiné à l'Arduino
Objectif : faire varier la luminosité d'une LED sur la broche 10 en modifiant la valeur PWM
*/
//***** EN-TÊTE DÉCLARATIF *****
int
ledPin =
10
; // On renomme la broche 10 en "ledPin"
int
timer =
100
; // On définit une durée de 0, 1 seconde pour la variable timer
//***** SETUP *****
void
setup() {
pinMode
(ledPin, OUTPUT
);
}
//***** LOOP *****
void
loop() {
// LED à 0 %.
analogWrite
(ledPin, 0
);
delay
(timer);
// LED à 19.6 %.
analogWrite
(ledPin, 50
);
delay
(timer);
// LED à 39.2 %.
analogWrite
(ledPin, 100
);
delay
(timer);
// LED à 58.8 %.
analogWrite
(ledPin, 150
);
delay
(timer);
// LED à 78.4 %.
analogWrite
(ledPin, 200
);
delay
(timer);
// LED à 100 %.
analogWrite
(ledPin, 255
);
delay
(timer);
}
Analyse du code
Pas de surprise pour ce code, si ce n'est l'utilisation d'analogWrite en lieu et place de digitalWrite. La luminosité de la LED progresse par paliers de 50. Si on veut lisser la progression de la luminosité, il faut augmenter le nombre de paliers, ce qui va vite fortement alourdir le code. C'est la raison pour laquelle il est préférable d'utiliser une boucle for
, comme nous le verrons dans le code suivant :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
/*
Code 8 - Edurobot.ch, destiné à l'Arduino
Objectif : faire varier la luminosité d'une LED sur la broche 10
Adapté de David A. Mellis et Tom Igoe
*/
//***** EN-TÊTE DÉCLARATIF *****
int
ledPin =
10
; //On renomme la broche 10 en "ledPin"
//***** SETUP *****
void
setup() {
}
//***** LOOP *****
void
loop() {
// Variation du min au max par addition de 5 jusqu'à 256
for
(int
fadeValue =
0
; fadeValue <=
255
; fadeValue +=
5
)
{
// Définition de la valeur de luminosité (de 0 à 255)
analogWrite
(ledPin, fadeValue);
// Attente de 30 millisecondes entre chaque palier pour voir l'effet.
delay
(30
);
}
// Variation du max au min par soustraction de 5 depuis 256
for
(int
fadeValue =
255
; fadeValue >=
0
; fadeValue -=
5
)
{
// Définition de la valeur de luminosité (de 0 à 255)
analogWrite
(ledPin, fadeValue);
// Attente de 30 millisecondes entre chaque palier pour voir l'effet.
delay
(30
);
}
}
Analyse du code
La boucle for
, on commence à bien la connaître. Sinon, voici un petit rappel :
Dans notre code, nous commençons avec un for
(int
fadeValue =
0
; fadeValue <=
255
; fadeValue +=
5
).
On crée donc une variable fadeValue de type int
, qui stocke le chiffre 0. Le test de la condition plus petit ou égal à 255 (fadeValue <=
255
) permet une sortie de la fonction dès qu'on atteint le nombre 256. Enfin, et c'est la nouveauté, on ne fait pas une incrémentation (++
), mais on additionne 5 à fadeValue avec la formule +=
5
.
La commande analogWrite
(ledPin, fadeValue); permet ainsi d'envoyer la valeur de fadeValue à la LED ledPin. Comme fadeValue augmente à chaque fois de +5, la luminosité de la LED augmente petit à petit. Enfin, le delay
permet de configurer la vitesse d'augmentation de la luminosité. Chaque palier de 5 prend 30 millisecondes. Il faut 51 paliers de 5 pour passer de 0 à 255. Ainsi, il faudra 51 x 30 = 1530 millisecondes pour passer de la LED éteinte à la LED à sa luminosité maximum, soit environ une seconde et demie.
Ensuite, une fois la LED à sa luminosité maximum, il s'agit de baisser sa luminosité jusqu'à l'éteindre, grâce au code for
(int
fadeValue =
255
; fadeValue >=
0
; fadeValue -=
5
). Le +=
5
est remplacé par un -=
5
, afin de soustraire à chaque fois 5 à la variable fadeValue.
Avec le code 8, nous avons fait varier la luminosité d'une LED de 0 à 255 par paliers de 5. On peut tout aussi bien utiliser un incrément ++
pour arriver au même résultat. Voilà ce que cela donne :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
/*
Code 9 - Edurobot.ch, destiné à l'Arduino
Objectif : faire varier la luminosité d'une LED sur la broche 10
*/
//***** EN-TÊTE DÉCLARATIF *****
int
ledPin =
10
; // On renomme la broche 10 en "ledPin"
//***** SETUP *****
void
setup()
{
}
//***** LOOP *****
void
loop()
{
// Variation du min au max par incrément
for
(int
fadeValue =
0
; fadeValue <=
255
; fadeValue ++
){
analogWrite
(ledPin, fadeValue);
delay
(10
);
}
// Variation du max au min par décrément
for
(int
fadeValue =
255
; fadeValue >=
0
; fadeValue --
){
analogWrite
(ledPin, fadeValue);
delay
(10
);
}
}