ESP32 PWM with Arduino IDE

In this tutorial we’ll show you how to generate PWM signals with the ESP32 using Arduino IDE. As an example we’ll build a simple circuit that dims an LED using the LED PWM controller of the ESP32. We’ll also show you how you can get the same PWM signal on different GPIOs at the same time.

Before proceeding with this tutorial you should have the ESP32 add-on installed in your Arduino IDE. Follow one of the following tutorials to install the ESP32 on the Arduino IDE, if you haven’t already.

We also recommend taking a look at the following resources:

Watch the Video Tutorial

This tutorial is available in video format (watch below) and in written format (continue reading).

Parts Required

To follow this tutorial you need these parts:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

ESP32 LED PWM Controller

The ESP32 has a LED PWM controller with 16 independent channels that can be configured to generate PWM signals with different properties.

Here’s the steps you’ll have to follow to dim an LED with PWM using the Arduino IDE:

1. First, you need to choose a PWM channel. There are 16 channels from 0 to 15.

2. Then, you need to set the PWM signal frequency. For an LED, a frequency of 5000 Hz is fine to use.

3. You also need to set the signal’s duty cycle resolution: you have resolutions from 1 to 16 bits.  We’ll use 8-bit resolution, which means you can control the LED brightness using a value from 0 to 255.

4. Next, you need to specify to which GPIO or GPIOs the signal will appear upon. For that you’ll use the following function:

ledcAttachPin(GPIO, channel)

This function accepts two arguments. The first is the GPIO that will output the signal, and the second is the channel that will generate the signal.

5. Finally, to control the LED brightness using PWM, you use the following function:

ledcWrite(channel, dutycycle)

This function accepts as arguments the channel that is generating the PWM signal, and the duty cycle.

Dimming an LED

Let’s see a simple example to see how to use the ESP32 LED PWM controller using the Arduino IDE.

Schematic

Wire an LED to your ESP32 as in the following schematic diagram. The LED should be connected to GPIO 16.

esp32-pwm-dim-led

(This schematic uses the ESP32 DEVKIT V1 module version with 30 GPIOs – if you’re using another model, please check the pinout for the board you’re using.)

Note: you can use any pin you want, as long as it can act as an output. All pins that can act as outputs can be used as PWM pins. For more information about the ESP32 GPIOs, read: ESP32 Pinout Reference: Which GPIO pins should you use?

Code

Open your Arduino IDE and copy the following code.

// the number of the LED pin
const int ledPin = 16;  // 16 corresponds to GPIO16

// setting PWM properties
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
 
void setup(){
  // configure LED PWM functionalitites
  ledcSetup(ledChannel, freq, resolution);
  
  // attach the channel to the GPIO to be controlled
  ledcAttachPin(ledPin, ledChannel);
}
 
void loop(){
  // increase the LED brightness
  for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){   
    // changing the LED brightness with PWM
    ledcWrite(ledChannel, dutyCycle);
    delay(15);
  }

  // decrease the LED brightness
  for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
    // changing the LED brightness with PWM
    ledcWrite(ledChannel, dutyCycle);   
    delay(15);
  }
}

View raw code

You start by defining the pin the LED is attached to. In this case the LED is attached to GPIO 16.

const int ledPin = 16;  // 16 corresponds to GPIO16

Then, you set the PWM signal properties. You define a frequency of 5000 Hz, choose channel 0 to generate the signal, and set a resolution of 8 bits. You can choose other properties, different than these, to generate different PWM signals.

const int freq = 5000; 
const int ledChannel = 0; 
const int resolution = 8;

In the setup(), you need to configure LED PWM with the properties you’ve defined earlier by using the ledcSetup() function that accepts as arguments, the ledChannel, the frequency, and the resolution, as follows:

ledcSetup(ledChannel, freq, resolution);

Next, you need to choose the GPIO you’ll get the signal from. For that use the ledcAttachPin() function that accepts as arguments the GPIO where you want to get the signal, and the channel that is generating the signal. In this example, we’ll get the signal in the ledPin GPIO, that corresponds to GPIO 16. The channel that generates the signal is the ledChannel, that corresponds to channel 0.

ledcAttachPin(ledPin, ledChannel);

In the loop, you’ll vary the duty cycle between 0 and 255 to increase the LED brightness.

for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){
    // changing the LED brightness with PWM
    ledcWrite(ledChannel, dutyCycle);
    delay(15); 
}

And then, between 255 and 0 to decrease the brightness.

for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
    // changing the LED brightness with PWM
    ledcWrite(ledChannel, dutyCycle);
    delay(15);
 }

To set the brightness of the LED, you just need to use the ledcWrite() function that accepts as arguments the channel that is generating the signal, and the duty cycle.

ledcWrite(ledChannel, dutyCycle);

As we’re using 8-bit resolution, the duty cycle will be controlled using a value from 0 to 255.  Note that in the ledcWrite() function we use the channel that is generating the signal, and not the GPIO.

Testing the Example

Upload the code to your ESP32. Make sure you have the right board and COM port selected. Look at your circuit. You should have a dimmer LED that increases and decreases brightness.

exp32-pwm

Getting the Same Signal on Different GPIOs

You can get the same signal from the same channel in different GPIOs. To achieve that,  you just need to attach those GPIOs to the same channel on the setup().

Let’s modify the previous example to dim 3 LEDs using the same PWM signal from the same channel.

Schematic

Add two more LEDs to your circuit by following the next schematic diagram:

esp32-pwm-example

(This schematic uses the ESP32 DEVKIT V1 module version with 30 GPIOs – if you’re using another model, please check the pinout for the board you’re using.)

Code

Copy the following code to your Arduino IDE.

// the number of the LED pin
const int ledPin = 16;  // 16 corresponds to GPIO16
const int ledPin2 = 17; // 17 corresponds to GPIO17
const int ledPin3 = 5;  // 5 corresponds to GPIO5

// setting PWM properties
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
 
void setup(){
  // configure LED PWM functionalitites
  ledcSetup(ledChannel, freq, resolution);
  
  // attach the channel to the GPIO to be controlled
  ledcAttachPin(ledPin, ledChannel);
  ledcAttachPin(ledPin2, ledChannel);
  ledcAttachPin(ledPin3, ledChannel);
}
 
void loop(){
  // increase the LED brightness
  for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){   
    // changing the LED brightness with PWM
    ledcWrite(ledChannel, dutyCycle);
    delay(15);
  }

  // decrease the LED brightness
  for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
    // changing the LED brightness with PWM
    ledcWrite(ledChannel, dutyCycle);   
    delay(15);
  }
}

View raw code

This is the same code as the previous one but with some modifications. We’ve defined two more variables for two new LEDs, that refer to GPIO 17 and GPIO 5.

const int ledPin2 = 17; // 17 corresponds to GPIO17 
const int ledPin3 = 5;  // 5 corresponds to GPIO5

Then, in the setup(), we’ve added the following lines to assign both GPIOs to channel 0. This means that we’ll get the same signal, that is being generated on channel 0, on both GPIOs.

ledcAttachPin(ledPin2, ledChannel); 
ledcAttachPin(ledPin3, ledChannel);

Testing the Project

Upload the new sketch to your ESP32. Make sure you have the right board and COM port selected. Now, take a look at your circuit:

All GPIOs are outputting the same PWM signal. So, all three LEDs increase and decrease the brightness simultaneously, resulting in a synchronized effect.

Wrapping Up

In summary, in this post you’ve learned how to use the LED PWM controller of the ESP32 with the Arduino IDE to dim an LED. The concepts learned can be used to control other outputs with PWM by setting the right properties to the signal.

We have other tutorials related with ESP32 that you may also like:

This is an excerpt from our course: Learn ESP32 with Arduino IDE. If you like ESP32 and you want to learn more, we recommend enrolling in Learn ESP32 with Arduino IDE course.


Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »

Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »


Enjoyed this project? Stay updated by subscribing our weekly newsletter!

10 thoughts on “ESP32 PWM with Arduino IDE”

    • Hi.
      Thank you for sharing that library.
      I’ll give it a try, and update the article to include your solution.
      Regards,
      Sara 🙂

    • Hi dale.
      Those functions are part of the ESP32 core library for the Arduino IDE by default.
      So, once you have ESP32 installed on Arduino IDE, you don’t need to include anything else in your code to use those functions.
      Regards,
      Sara 🙂

  1. Hi Sara,
    “All GPIOs are outputting the same PWM signal. So, all three LEDs increase and decrease the brightness simultaneously, resulting in a synchronized effect.”

    Is itpossible to setup the different channels with different frequency and PWM in order to control the LED brightness separately?

Leave a Comment

Download our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.