ESP32 PWM Pins: How to Use PWM with ESP32

Esp32 Pwm Pins How To Use Pwm With Esp32

Pulse Width Modulation, or PWM, is a cornerstone of microcontroller applicationsโ€”whether you’re dimming an LED, controlling a motor, or generating tones. The ESP32 takes PWM to the next level with flexible, high-resolution outputs and tons of configurable pins.

In this tutorial, weโ€™ll walk through how PWM works on the ESP32, which pins support it, how to configure it in code (using the Arduino IDE), and some tips for advanced usage. ๐Ÿง ๐Ÿ”Œ


๐Ÿงฉ What Is PWM?

PWM simulates analog output using a digital signal that turns on and off rapidly.

  • Duty cycle: Percentage of time the signal is HIGH in one cycle (0โ€“100%)
  • Frequency: How fast each cycle happens (measured in Hz)

Example:

  • 0% duty = always off
  • 100% duty = always on
  • 50% duty = on half the time โ†’ perceived as half brightness or half speed

โš™๏ธ ESP32 PWM Features

Feature Value
Number of PWM channels 16 independent channels
Resolution Up to 16 bits (0โ€“65535 steps)
Frequency range 1 Hz to 40 MHz (hardware dependent)
Output pins Almost all GPIOs except reserved pins

ESP32 PWM is handled by LEDC (LED Control) hardware, which is highly flexible.


๐Ÿ“ PWM-Capable Pins on ESP32

The beauty of the ESP32? Almost any GPIO can be used for PWM.

However, avoid these reserved pins:
GPIO6โ€“11: Used for flash memory
GPIO34โ€“39: Input only (no output/PWM)

โœ… Best PWM Output Pins:

GPIOs: 2, 4, 5, 12โ€“19, 21โ€“23, 25โ€“27, 32, 33

These are safe for both PWM and general I/O.


๐Ÿ› ๏ธ Setting Up PWM in Arduino IDE

Youโ€™ll use the built-in ledcSetup() and ledcWrite() functions.

๐Ÿงช Basic Example: Dimming an LED on GPIO 5

int pwmChannel = 0;       // Channel 0โ€“15
int freq = 5000;          // 5 kHz PWM
int resolution = 8;       // 8-bit resolution (0โ€“255)
int ledPin = 5;           // LED connected to GPIO 5

void setup() {
  ledcSetup(pwmChannel, freq, resolution);  // configure channel
  ledcAttachPin(ledPin, pwmChannel);        // bind GPIO to channel
}

void loop() {
  for (int duty = 0; duty <= 255; duty++) {
    ledcWrite(pwmChannel, duty);
    delay(10);
  }
  for (int duty = 255; duty >= 0; duty--) {
    ledcWrite(pwmChannel, duty);
    delay(10);
  }
}

๐Ÿ“Š PWM Channel vs. GPIO: How It Works

Each GPIO gets assigned a PWM channel. You can have multiple pins sharing the same frequency/resolution but using different channels.

Channel Pin (GPIO) Function
0 5 LED dimming
1 18 Motor speed
2 19 RGB LED blue

๐Ÿง  Use a new channel for each independent PWM output.


๐ŸŽ›๏ธ Controlling Frequency and Resolution

ESP32 supports up to 16-bit resolution, but higher resolution = lower frequency.

Resolution Max Frequency (approx.)
8-bit ~312.5 kHz
10-bit ~78 kHz
12-bit ~20 kHz
16-bit ~1.2 kHz

Pick based on your application. For LED dimming, 5โ€“10 kHz is ideal.


๐Ÿ” PWM for Servos, Motors, LEDs

๐Ÿ”ง Servo (via PWM libraries):

Use a library like ESP32Servo.h to manage timing

๐Ÿ”ง Motor control (DC/Brushless):

  • Use 2โ€“3 PWM channels for H-Bridge or ESC
  • Consider 20 kHz+ frequency to eliminate audible whine

๐Ÿ”ง LED (Dimming or RGB):

  • Assign each color to a different PWM channel
  • Adjust duty cycle for brightness/color control

๐Ÿšซ Common Issues and Fixes

Problem Likely Cause Fix
PWM not working on pin GPIO not PWM capable Use a different GPIO
No LED brightness change Wrong channel/duty value Check resolution & channel setup
Pin outputs fixed value Conflict with another peripheral Free up pin from other use
Flickering at low duty Resolution too low Use higher resolution (e.g. 10-bit)

๐Ÿงพ Summary Cheat Sheet

Task Function
Setup PWM channel ledcSetup(channel, freq, bits)
Attach GPIO to channel ledcAttachPin(pin, channel)
Write duty cycle ledcWrite(channel, value)
Detach GPIO ledcDetachPin(pin)

โœ… Final Thoughts

The ESP32โ€™s PWM capabilities are incredibly robustโ€”16 channels, high frequency support, and nearly any GPIO as an output. Whether you’re controlling LEDs, fans, motors, or sound devices, PWM on the ESP32 gives you total control.

With just a few lines of code, you can achieve smooth dimming, precise motor control, and advanced embedded interaction. ๐Ÿ’กโš™๏ธ