Créer des tensions variables sur l’ESP32 avec le PWM
(Mis à jour le 12/12/2022)
Le PWM (Pulse Witdh Modulation) ou MLI (Modulation de Largeur d’Impulsion) en français permet de « générer numériquement » une tension électrique variable comprise entre 0 et 3.3V. Le PWM sur l’ESP32 est beaucoup plus complet sur l’Arduino.
Rappel sur le PWM
Le PWM est une technique pour obtenir des signaux d’allure analogique avec des broches numériques. On crée un signal carré, un signal basculant entre un niveau HAUT et BAS, entre 0V et 3.3V. Cette succession de niveaux HAUT/BAS peut simuler une tension intermédiare entre les 2 niveaux en jouant sur la proportion du temps où le signal est HAUT et BAS. La durée du temps du niveau HAUT est appelé largeur d’impulsion, ou encore « duty cycle » en anglais. Pour obtenir une variation analogique, il suffit de changer ou de modifier cette largeur d’impulsion.

Note
La fréquence du signal est fixée et seule la largeur d’impulsion varie.
Utilisation
L’utilisation du PWM sur l’ESP32 est différente de celle sur l’Arduino. Il y a 16 canaux PWM indépendants qui peuvent être assignés à n’importe quels pins GPIO (sauf les pins GPIO36, GPIO39, GPIO34, GPIO35). La configuration du PWM est un peu plus complexe sur l’ESP32 mais est plus complète. Le module ledc s’occupe du PWM et 3 fonctions principales permettront de l’utiliser : ledcSetup()
, ledcAttachPin()
, ledcWrite()
Pour générer un signal PWM par exemple sur le pin GPIO23, il faut :
Choisir un canal PWM (0 - 15)
Choisir la fréquence du PWM
Choisir la résolution de la largeur d’impulsion entre 1 et 16 bits
Choisir le pin GPIO qui va générer le signal PWM
Attribuer la valeur de la tension que l’on veut en sortie
int pwmChannel = 0; //Choisit le canal 0
int frequence = 1000; //Fréquence PWM de 1 KHz
int resolution = 8; // Résolution de 8 bits, 256 valeurs possibles
int pwmPin = 23;
void setup(){
// Configuration du canal 0 avec la fréquence et la résolution choisie
ledcSetup(pwmChannel, frequence, resolution);
// Assigne le canal PWM au pin 23
ledcAttachPin(pwmPin, pwmChannel);
// Créer la tension en sortie choisi
ledcWrite(pwmChannel, 127); //1.65 V
}
void loop(){
}
Une fois que la configuration avec les fonctions ledcSetup()
et ledcAttachPin()
est faite, on utilise uniquement la fonction ledcWrite()
pour changer la tension.
Avertissement
La fonction analogWrite()
ne fonctionnera pas sur l’ESP32, il faut utiliser ledcWrite()
à la place.
Mini-Projet : Varier l’intensité de LEDs via le PWM.
Nous allons faire varier l’intensité de 3 leds avec un signal PWM.
Schéma électrique
Choisissez les couleurs de leds que vous voulez.


Avertissement
Ne pas oublier de mettre des résistances en série avec les LEDs pour éviter de les griller. Une valeur entre 220Ω et 330Ω fera amplement l’affaire.
Code pour contrôler la luminosité des LEDs
Solution
const int ledPin = 23;
const int ledPin2 = 22;
const int ledPin3 = 21;
// Paramètre du channel 0 du PWM
const int freq = 5000; // 5000 Hz
const int ledChannel = 0;
const int resolution = 8; // Résolution de 8 bits
void setup(){
// Configure le channel 0
ledcSetup(ledChannel, freq, resolution);
// Attache le channel 0 sur les 3 pins
ledcAttachPin(ledPin, ledChannel);
ledcAttachPin(ledPin2, ledChannel);
ledcAttachPin(ledPin3, ledChannel);
}
void loop(){
// Augmente la luminosité de la led
for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){
ledcWrite(ledChannel, dutyCycle);
delay(15);
}
}
Au lieu d’utiliser 3 canaux PWM différents pour chaque pin, on en utilise qu’un seul qu’on assigne aux 3 pins.
Résultats
