Utiliser le PWM

Le PWM (Pulse With Modulation) ou MLI (Modulation de Largeur d’Impulsion) 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’ESP32 que 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, 0V et 3.3V. Cette succession de niveaux HAUT/BAS peut simuler des tensions entre le niveau HAUT (5 Volts) et le niveau BAS (0 Volts) en faisant varier la proportion du temps où le signal est HAUT sur la proportion de temps où le signal est 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.

../../_images/pwm0.png

Principe du PWM

Note

La fréquence du signal est fixée et seulement la largeur d’impulsion varie.

Utilisation

L’utilisation du PWM sur l’ESP32 est différente que 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 en sortie que l’on veut

int pwmChannel = 0; //Choisi 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

Nous allons faire varier l’intensité de 3 leds avec un signal PWM.

Schéma électrique

Choisisser les couleurs de leds que vous voulez.

../../_images/projet2_circuit.png

Circuit électrique

Essayer d’écrire le programme par vous même

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 au 3 pins.