Skip to content

uPesy only delivers currently in France.

Contents Menu Expand Light mode Dark mode Auto light/dark mode

Create analog voltage on ESP32 with PWM

The PWM (Pulse With Modulation) allows “digitally produce” a variable voltage between 0 and 3.3V. The PWM on the ESP32 is much more complete than on the Arduino.

Reminder on the PWM

PWM is a method for obtaining analog-looking signals on digital pins. We create a square wave, a signal switching between a HIGH and LOW level, between 0V and 3.3V. This succession of HIGH / LOW levels can simulate an intermediate voltage between the 2 levels by playing on the balance when the signal is HIGH and LOW. The duration of the HIGH level is called the “duty cycle.” To obtain an analog variation, you just need to change or modify this pulse width.


Principle of PWM


The signal frequency is fixed and only the pulse width varies.


Using PWM on the ESP32 is different from using the Arduino. 16 independent PWM channels can be assigned to any GPIO pins (except GPIO36, GPIO39, GPIO34, GPIO35 pins). The PWM configuration is a bit more complex on the ESP32 but is more powerful. The ledc module takes care of the PWM and 3 main functions will allow it to be used: ledcSetup() , ledcAttachPin() , ledcWrite()

To generate a PWM signal, for example on pin GPIO23, you must:
  • Choose a PWM channel (0 - 15)

  • Choose the PWM frequency

  • Choose the resolution of the pulse width between 1 and 16 bits.

  • Choose the GPIO pin which will generate the PWM signal

  • Assign the value of the voltage you want at the output

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(){

Once the configuration with the ledcSetup() and``ledcAttachPin()`` functions is done, we only use the `` ledcWrite()`` function to change the voltage.


Once the configuration with the ledcSetup() and``ledcAttachPin()`` functions is done, we only use the `` ledcWrite()`` function to change the voltage.


We will vary the intensity of 3 LEDs with a PWM signal.


Choose the colors of the LEDs you want.





Try to write the program by yourself!


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);

Instead of using 3 different PWM channels for each pin, we use only one assigned to the 3 pins.

We use cookies to make your visit to the site as pleasant as possible. Privacy Policy