The ESP32 PWM example shown here are different from that of an Arduino. Arduinos have their own built-in command, while ESP32s use the ‘ledc’ commands instead. Nonetheless, PWM on an ESP32 still requires few lines of code. We’ll start this beginner-friendly PWM example with a paltry 3 lines of code!

ESP32 PWM Tutorial

This tutorial uses the Arduino IDE, not the ESP32 IDF.

Start by placing the following code inside your ‘setup()’ function in Arduino IDE:

ledcSetup(0, 5000, 8);
ledcAttachPin(2, 0);
ledcWrite(0, 127);

Line 1 selects the PWM channel you’re going to use (0), the desired PWM frequency (5000hz), and the PWM resolution (8 bits). You can use any channel you want (from 0 to 16), but different devices require different PWM frequencies.

Line 2 connects the pin through which you intend to output a PWM signal to (pin 2 on the ESP32 in this example) the PWM channel we’re using in this PWM example, which is channel 0. There are 16 channels available.

Line 3 sets the duty cycle of the PWM (set to 127 in this example), and which channel we’re setting the duty cycle for (channel 0 in this example). This defines how long the pin stays on relative to how long it is off. It corresponds to LED brightness or motor speed if that’s what you’re controlling with it. A higher duty cycle corresponds to a longer ‘on’ time or higher brightness/motor speed. I explain how this works and why it matters in my PWM tutorial. A brief summary of what we’re doing here is controlling the width of an electric pulse. The width is how long the pulse stays on before the power is switched back off. PWM switches the power on and off many times per second (high frequency) so it looks like the LED you’re controlling is dimming, but it won’t flicker due to the high frequency.

On line 3, we set the duty cycle to approximately 50%, because 127 is half of 255. 255 is the maximum setting for 8-bit PWM, and it translates to a 100% duty cycle. 0 is the lowest, and it translates to a 0% duty cycle. This means that an LED connected to this PWM pin (pin 2) would theoretically operate at 50% brightness at 127. If it was a fan, it would run at approximately half of its maximum speed. For example: a 3,000 RPM fan would run at about 1,500 rpm. In reality it may not be exactly 50%, but it is a useful guideline.

Connect a small, discrete LED to pin 2 of your ESP32 board to test this PWM example. ‘Discrete’ refers to an LED that draws little current. In other words, not a power LED, which is used to light a room, flashlight, or anything that requires a significant amount of power. Try to find one that draws less than or equal to 20 mA to avoid damaging your ESP32. Select your ESP32 model under Tools > Board in the IDE. Click the upload button in Arduino IDE to load this program onto your ESP32.

You can also use the ESP32’s low-level API (ESP32 IDF) for PWM control as well. It helps to provide a deeper understanding of how things work, and may provide the ability to write more resource-efficient code for your ESP32.