Learn ESP32 PWM with this tutorial: 16 essential troubleshooting tips for LEDs, fans, audio, and more. Master PWM pins, frequency, and output easily.
Welcome to the world of ESP32 PWM! If you’re new to embedded systems or microcontrollers, PWM—or Pulse Width Modulation—might sound complicated. But think of it as simply turning a device on and off so fast that your eyes, ears, or motors perceive a continuous effect. Over this 5-part series, we’ll break down everything about ESP32 PWM, step by step, so it’s beginner-friendly, practical, and easy to understand.
What is PWM?
PWM, or Pulse Width Modulation, is a method to control the amount of power delivered to electronic devices without using analog voltages. Imagine a light dimmer: PWM allows you to adjust brightness digitally by changing the duty cycle—the ratio of ON time to OFF time in a repeating signal.
This technique is widely used to control:
- LEDs (brightness control)
- DC motors (speed control)
- Fans (RPM control)
- Buzzers and audio devices
With ESP32, PWM becomes extremely powerful due to its flexible timers and multiple channels.
Why ESP32 PWM?
ESP32 is one of the most popular microcontrollers today. Its PWM pins allow precise control over devices with minimal hardware. Unlike other boards, ESP32 supports multiple independent PWM channels, higher frequencies, and up to 16-bit resolution, giving you smooth control over motors, LEDs, and audio devices.
Some benefits of using ESP32 PWM include:
- Efficient power management
- Precise control over brightness, speed, or audio frequency
- Flexibility with frequency and resolution
- Integration with Arduino IDE using Arduino ESP32 PWM library
ESP32 PWM Pins
You might be wondering: Does ESP32 have PWM pins? Yes, almost all GPIO pins on ESP32 can output PWM. However, some pins are better suited for PWM tasks depending on your project.
- Common PWM pins: GPIO 2, 4, 5, 12, 13, 14, 15, 16, 17
- Number of PWM pins: ESP32 supports 16 independent PWM channels
- Default PWM frequency: 5 kHz (can be changed)
By understanding your ESP32 PWM pins, you can optimize your project for LEDs, motors, or audio applications.
PWM Frequency Explained
ESP32 PWM frequency is how fast the PWM signal toggles between high and low states. Frequency determines the smoothness and efficiency of control:
- LEDs: 500 Hz to 1 kHz is ideal to avoid flickering
- Fans and motors: 1 kHz to 25 kHz for smooth operation
- Audio: 20 kHz+ to eliminate audible noise
You can easily change frequency using the PWM API or Arduino library.
Duty Cycle and Output
Duty cycle represents the proportion of ON time in a PWM period:
- 0% = always OFF
- 50% = half ON, half OFF
- 100% = always ON
For example, an LED at 50% duty cycle appears half-bright, while a motor at 75% duty cycle runs faster than at 50%. ESP32 allows you to control duty cycle with high accuracy, especially when using higher resolution settings.
ESP32 PWM Resolution
PWM resolution determines how finely you can adjust the duty cycle:
- 8-bit PWM: 0-255 duty levels
- 10-bit PWM: 0-1023 duty levels
- 16-bit PWM: 0-65535 duty levels (ESP32 PWM 16 bit)
Higher resolution = smoother control over devices.
ESP32 PWM Output
The ESP32 PWM output allows you to control the effective voltage on a GPIO pin. By changing the duty cycle of the PWM signal, you can vary brightness, motor speed, or buzzer volume without using analog signals. This is especially efficient in embedded systems.
- Duty cycle = (ON time / Total period) * 100%
- PWM resolution affects how smooth your output is (8-bit, 10-bit, 16-bit)
- Frequency should match the device requirements (LEDs, motors, audio)
Example: A motor controlled with 50% duty cycle runs at half speed, while an LED at 50% duty cycle appears half-bright.
ESP32 analogWrite
Unlike Arduino, ESP32 does not have a built-in analogWrite() function. Instead, you use the ESP32 PWM API:
ledcSetup(channel, freq, resolution)– sets up PWM channelledcAttachPin(pin, channel)– attaches GPIO to channelledcWrite(channel, duty)– sets the duty cycle (like analogWrite)
This method is compatible with LEDs, motors, fans, and buzzers.
ESP32 LED PWM Example
Controlling LEDs is one of the simplest ways to learn PWM.
#include
const int ledPin = 2;
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
void setup() {
ledcSetup(ledChannel, freq, resolution);
ledcAttachPin(ledPin, ledChannel);
}
void loop() {
for(int duty = 0; duty <= 255; duty++) {
ledcWrite(ledChannel, duty);
delay(10);
}
for(int duty = 255; duty >= 0; duty--) {
ledcWrite(ledChannel, duty);
delay(10);
}
}
This code gradually brightens and dims the LED using ESP32 PWM analogWrite.
ESP32 PWM Fan Controller
Fans require high-frequency PWM to avoid noise and provide smooth speed control. Using ESP32 PWM, you can create a fan controller easily.
#include
const int fanPin = 4;
const int fanChannel = 1;
const int freq = 25000; // 25 kHz to avoid noise
const int resolution = 8;
void setup() {
ledcSetup(fanChannel, freq, resolution);
ledcAttachPin(fanPin, fanChannel);
}
void loop() {
ledcWrite(fanChannel, 128); // 50% speed
delay(5000);
ledcWrite(fanChannel, 255); // 100% speed
delay(5000);
}
This is a practical ESP32 PWM fan controller example.
ESP32 PWM Buzzer and Audio Output
PWM can also generate audio signals for buzzers or speakers. You can adjust frequency and duty cycle to create different tones.
const int buzzerPin = 15;
const int freq = 2000;
const int channel = 2;
const int resolution = 8;
void setup() {
ledcSetup(channel, freq, resolution);
ledcAttachPin(buzzerPin, channel);
}
void loop() {
ledcWriteTone(channel, 1000); // 1 kHz tone
delay(500);
ledcWriteTone(channel, 2000); // 2 kHz tone
delay(500);
}
This simple ESP32 PWM audio output project demonstrates PWM for sound.
Tips for Smooth PWM Output
- Use proper frequency: Match PWM frequency to device type.
- Select resolution carefully: Higher resolution = smoother control.
- Avoid overloading pins: Monitor ESP32 PWM current.
- Use proper wiring: Include resistors for LEDs, and transistors or MOSFETs for motors.
ESP32 PWM Example Projects
Here are some beginner projects you can try:
- LED dimmer: Use PWM to gradually increase/decrease LED brightness.
- Fan speed controller: Control speed with duty cycle changes.
- Simple buzzer melodies: Play tones using PWM audio output.
- RGB LED control: Use multiple PWM channels to mix colors.
ESP32 PWM Timers and Channel Allocation
ESP32 has 16 independent PWM channels and 4 timers. Each channel can be assigned to any GPIO pin.
- PWM channel: Each channel controls one signal and its duty cycle.
- Timer: Determines the frequency and resolution for channels linked to it.
- ESP32 PWM allocate timer: Allocate timers efficiently to manage multiple channels without conflicts.
Example:
const int ledPin1 = 2;
const int ledPin2 = 4;
const int channel1 = 0;
const int channel2 = 1;
const int freq = 5000;
const int resolution = 8;
void setup() {
// Allocate channels and timers
ledcSetup(channel1, freq, resolution);
ledcSetup(channel2, freq, resolution);
ledcAttachPin(ledPin1, channel1);
ledcAttachPin(ledPin2, channel2);
}
void loop() {
ledcWrite(channel1, 128); // 50% duty
ledcWrite(channel2, 64); // 25% duty
delay(1000);
}
This approach is ideal for controlling multiple LEDs, fans, or motors simultaneously.
Dynamic Frequency Changes
Sometimes, you need to change PWM frequency dynamically for specific devices. For instance, motors may need higher frequencies for speed control, while audio outputs require precise tone generation.
Example:
const int fanPin = 5;
const int fanChannel = 2;
const int resolution = 8;
void setup() {
ledcSetup(fanChannel, 5000, resolution);
ledcAttachPin(fanPin, fanChannel);
}
void loop() {
for(int freq = 5000; freq <= 25000; freq += 5000){
ledcSetup(fanChannel, freq, resolution);
ledcWrite(fanChannel, 128);
delay(2000);
}
}
This code gradually increases PWM frequency while maintaining a 50% duty cycle.
ESP32 PWM Capture
PWM capture allows ESP32 to read the characteristics of an incoming PWM signal, such as duty cycle or frequency. This is useful for sensors that output PWM signals, such as flow sensors or distance sensors.
Key points:
- Capture PWM using interrupts or dedicated hardware timers
- Measure high and low pulse durations to calculate duty cycle
- Integrate with applications like motor RPM measurement
ESP32 PWM Current Monitoring
Monitoring ESP32 PWM current is crucial for motors and fans. Excessive current can damage ESP32 pins or peripherals.
Tips:
- Use MOSFETs or transistors for high-current loads
- Measure current with a current sensor and integrate with ESP32
- Protect devices with fuses or overcurrent circuits
ESP32 S3 PWM Examples
ESP32 S3 offers additional capabilities like more PWM channels and higher precision. Here’s a simple example:
const int ledPin = 10;
const int channel = 0;
const int freq = 10000;
const int resolution = 10;
void setup() {
ledcSetup(channel, freq, resolution);
ledcAttachPin(ledPin, channel);
}
void loop() {
for(int duty = 0; duty <= 1023; duty++) {
ledcWrite(channel, duty);
delay(5);
}
}
This uses ESP32 S3 PWM example to gradually increase LED brightness with 10-bit resolution.
Best Practices for Advanced PWM
- Plan your PWM channel allocation to avoid conflicts.
- Use timers efficiently, especially with multiple devices.
- Dynamically adjust frequency based on device needs.
- Monitor current for safety.
- Use higher resolution for smoother control in sensitive applications.
ESP32 PWM Circuits
A PWM circuit connects your ESP32 to the device you want to control. Here’s what you need to know:
- LEDs: Connect the anode to the PWM pin and the cathode to GND. Always use a current-limiting resistor (typically 220–330Ω) to prevent burning out the LED.
- Motors and Fans: Use a transistor or MOSFET between ESP32 PWM pin and the device. The ESP32 alone cannot supply enough current. Don’t forget a flyback diode to protect the circuit.
- Buzzers and Audio Devices: Connect directly to the PWM pin for small piezo buzzers, but for speakers, use an amplifier or resistor network to prevent overcurrent.
ESP32 PWM circuit diagram example:
- ESP32 GPIO -> Gate of MOSFET
- Source -> GND
- Drain -> Negative terminal of fan/motor
- Positive terminal -> 5V or supply voltage
- Flyback diode across the motor/fan terminals
This ensures safe and efficient PWM control for various devices.
ESP32 PWM Calculators
Calculating duty cycle manually can be tedious. A PWM calculator simplifies this by converting voltage or percentage to duty cycle value.
Formula:
Duty Cycle Value = (Desired Voltage / Supply Voltage) * Max Count
- For an 8-bit PWM (0–255), 3.3V output from 5V supply:
(3.3/5) * 255 ≈ 168 - For a 10-bit PWM (0–1023), use the same formula with 1023 as max count
Tips:
- Always consider PWM resolution in calculations
- Adjust frequency according to the device type
- Online ESP32 PWM calculators can automate this for multiple channels
Practical Projects
Here are some hands-on projects to strengthen your understanding:
1. RGB LED Control
Use three PWM channels to mix colors.
const int redPin = 16;
const int greenPin = 17;
const int bluePin = 18;
void setup() {
ledcSetup(0, 5000, 8);
ledcSetup(1, 5000, 8);
ledcSetup(2, 5000, 8);
ledcAttachPin(redPin, 0);
ledcAttachPin(greenPin, 1);
ledcAttachPin(bluePin, 2);
}
void loop() {
for(int i = 0; i <= 255; i++) {
ledcWrite(0, i);
ledcWrite(1, 255-i);
ledcWrite(2, i/2);
delay(10);
}
}
This creates smooth color transitions using ESP32 PWM output.
2. Temperature-Controlled Fan
Use a temperature sensor to adjust fan speed dynamically.
int tempSensorPin = 34;
int fanPin = 4;
const int fanChannel = 1;
const int freq = 25000;
const int resolution = 8;
void setup() {
ledcSetup(fanChannel, freq, resolution);
ledcAttachPin(fanPin, fanChannel);
}
void loop() {
int temp = analogRead(tempSensorPin);
int duty = map(temp, 0, 4095, 0, 255);
ledcWrite(fanChannel, duty);
delay(1000);
}
This demonstrates ESP32 PWM fan controller in action based on real sensor input.
3. Audio Tone Generator
Create simple melodies using PWM for buzzers.
const int buzzerPin = 15;
const int channel = 2;
void setup() {
ledcSetup(channel, 2000, 8);
ledcAttachPin(buzzerPin, channel);
}
void loop() {
ledcWriteTone(channel, 440); // A4 note
delay(500);
ledcWriteTone(channel, 494); // B4 note
delay(500);
ledcWriteTone(channel, 523); // C5 note
delay(500);
}
This is a beginner-friendly ESP32 PWM audio output project.
Best Practices for Projects
- Use proper ESP32 PWM pins for each device.
- Always check the ESP32 PWM current limits.
- Use adequate resistors or MOSFETs depending on load.
- Plan PWM channels carefully for multi-device projects.
- Test with simple examples before integrating into larger projects.
Practical Advice for Projects
- Start small: Begin with one device to understand PWM before scaling up.
- Plan channels and timers: Allocate wisely when using multiple devices.
- Monitor current: Protect your ESP32 and devices from overcurrent.
- Use proper wiring: MOSFETs for motors, resistors for LEDs, and amplifiers for audio.
- Test frequencies: Adjust PWM frequency for optimal performance for each device.
- Document your projects: Keep notes on pin assignments, frequencies, duty cycles, and resolutions.
Summary and Final Thoughts
Congratulations! You’ve completed the full ESP32 PWM tutorial series. Here’s what you’ve learned:
- Basics of PWM and why it’s essential for LEDs, motors, fans, and audio
- ESP32 PWM pins, frequency, duty cycle, and resolution
- AnalogWrite-style PWM control using ledcWrite()
- Practical examples with LEDs, fans, buzzers, RGB LEDs, and audio
- Advanced techniques: timers, channel allocation, dynamic frequency, PWM capture
- Circuits, calculators, and real-world project implementations
- Troubleshooting tips and answers to common FAQs
With this knowledge, you can confidently build PWM-based projects on ESP32.
Want to take your ESP32 skills further? Check out our ESP32 DAC Tutorials to learn how to generate high-quality audio using the ESP32 DAC.32, experiment with new ideas, and optimize your designs for smooth and reliable operation. PWM opens up endless possibilities for embedded systems, and mastering it is a significant step toward professional-level projects.
Ultimate ESP32 PWM Troubleshooting Guide: Q&A Edition
If you’ve been working with ESP32 PWM, you know it can be a little tricky sometimes. From setting the frequency to controlling fans or audio output, issues pop up even for experienced developers. Don’t worry — we’ve got you covered with practical answers to the most common problems.
What is ESP32 PWM, and why should I use it?
ESP32 PWM (Pulse Width Modulation) allows you to control devices like LEDs, motors, and fans by adjusting the duty cycle of a digital signal. Think of it like dimming your lights or controlling fan speed, but digitally. It’s versatile, precise, and essential for embedded projects.
- Primary keyword: ESP32 PWM
- Secondary keywords naturally included: ESP32 PWM pins, ESP32 PWM frequency, ESP32 PWM output
How many PWM pins does ESP32 have?
ESP32 has almost all its GPIO pins capable of PWM. Specifically, there are 16 independent channels spread across multiple pins. You can configure each channel with its own frequency and resolution.
- Tip: Not all pins are equal for PWM if you’re using advanced features like ESP32 PWM audio output. Always check your board’s datasheet.
Secondary keyword usage: does ESP32 have PWM pins, how many PWM pins does ESP32 have
ESP32 PWM isn’t working — what should I check first?
Before panicking:
- Check the pin: Not all pins can handle the PWM output for certain features like ESP32 PWM buzzer or ESP32 PWM fan controller.
- Verify frequency: Using too high or too low a ESP32 PWM frequency can make devices behave unpredictably.
- Duty cycle limits: For LEDs, 0–255 is common, but fans might need 0–1023 for proper control.
How do I change the ESP32 PWM frequency?
Changing the frequency is simple with the ESP32 PWM API:
ledcSetup(channel, freq, resolution);
channel= PWM channelfreq= PWM frequencyresolution= bits of resolution (8–16 bits)- Secondary keywords: ESP32 PWM change frequency, ESP32 PWM allocate timer, ESP32 PWM bit
Why is my ESP32 LED flickering during PWM?
Flickering usually comes from:
- Wrong frequency: Some LEDs require frequencies above 500 Hz.
- Timer conflicts: Multiple PWM outputs sharing the same timer can cause glitches.
- Incorrect duty cycle: Check your ESP32 LED PWM example code to ensure values match the resolution.
Pro tip: Using ESP32 PWM 16-bit resolution reduces flicker significantly.
Can ESP32 PWM control fans?
Absolutely! You can use PWM to vary fan speed. Example:
ledcWrite(channel, dutyCycle); // dutyCycle 0-1023
Make sure your fan supports PWM input. ESP32 PWM fan controller circuits often include a transistor or MOSFET to handle higher current.
- Secondary keywords: ESP32 PWM current, ESP32 PWM circuit
How do I generate audio with ESP32 PWM?
Yes, PWM can be used for sound! By changing the duty cycle rapidly, you can output audio signals:
- Use a low-pass filter to smooth the PWM output into analog audio.
- For ESP32 PWM audio output, try
ledcWriteTone(channel, frequency)with varying duty cycles. - Secondary keywords: ESP32 PWM audio, ESP32 PWM analogwrite
ESP32 PWM analogWrite is not behaving as expected — why?
Unlike Arduino Uno, ESP32’s analogWrite is implemented using LED control PWM channels. Some points to remember:
analogWrite(pin, value)is a wrapper overledcWrite().- Make sure you set up the channel and frequency with
ledcSetup()before callinganalogWrite(). - Duty cycle resolution affects accuracy; for example, using 8-bit vs ESP32 PWM 16 bit changes the output granularity.
How accurate is ESP32 PWM?
ESP32 PWM is highly accurate, especially for audio and motor control. However:
- Accuracy depends on PWM frequency, timer resolution, and clock sources.
- For high-precision applications like ESP32 PWM capture, you may want to use hardware timers.
- Secondary keywords: ESP32 PWM accuracy
My ESP32 PWM code works on one board but not another — why?
Different ESP32 boards (ESP32, ESP32-S3, ESP32-C3) have slight variations in:
- Maximum PWM frequency
- Supported pins for PWM output
- Timer allocation
Always check the ESP32 PWM board datasheet. For example, ESP32 S3 PWM example code may differ slightly from standard ESP32.
ESP32 PWM calculator — what is it?
An ESP32 PWM calculator helps you compute:
- Frequency
- Duty cycle percentage
- Resolution in bits
This is handy when you’re designing circuits like ESP32 PWM circuit for LED dimming or fan control.
- Secondary keywords: ESP32 PWM calculator
Why does PWM output current matter?
If your load draws too much current, you can damage the ESP32 pin. For example, ESP32 PWM buzzer can work directly, but motors and fans usually require an external driver.
- Secondary keywords: ESP32 PWM current
ESP32 PWM example code for LED
Here’s a clean example:
const int ledPin = 18; // ESP32 PWM pins
const int channel = 0;
const int freq = 5000;
const int resolution = 8;
void setup() {
ledcSetup(channel, freq, resolution);
ledcAttachPin(ledPin, channel);
}
void loop() {
for(int duty = 0; duty <= 255; duty++){
ledcWrite(channel, duty);
delay(10);
}
for(int duty = 255; duty >= 0; duty--){
ledcWrite(channel, duty);
delay(10);
}
}Common ESP32 PWM issues and fixes
| Issue | Cause | Fix |
|---|---|---|
| LED flickering | Low PWM frequency | Increase frequency, e.g., 1 kHz+ |
| Fan not responding | Incorrect duty cycle | Adjust PWM values; use MOSFET for high current |
| PWM audio distorted | Missing low-pass filter | Add RC filter |
| Multiple PWM outputs interfere | Sharing timer | Allocate different timers with ESP32 PWM allocate timer |
FAQ section for ESP32 PWM
1. Does ESP32 have PWM pins?
Yes, ESP32 has multiple PWM-capable GPIOs. Almost all pins can be configured for ESP32 PWM output, making it flexible for LEDs, motors, fans, and buzzers.
2. How many PWM pins does ESP32 have?
ESP32 supports 16 independent PWM channels, allowing simultaneous control of multiple devices using the ESP32 PWM API or Arduino ESP32 PWM library.
3. What is the default PWM frequency on ESP32?
The ESP32 default PWM frequency is typically 5 kHz, suitable for LEDs. It can be changed dynamically depending on your application, such as ESP32 PWM fan controller or ESP32 PWM audio output.
4. What is ESP32 PWM frequency and why is it important?
ESP32 PWM frequency determines how fast the signal toggles. Low frequencies may cause flickering in LEDs, while higher frequencies (20–25 kHz) are ideal for motors and audio, avoiding audible noise.
5. How do I use ESP32 PWM analogWrite?
ESP32 doesn’t have a native analogWrite() like Arduino. Instead, use ledcSetup(), ledcAttachPin(), and ledcWrite() functions to set frequency, resolution, and duty cycle for your ESP32 PWM output.
6. How accurate is ESP32 PWM?
ESP32 PWM accuracy depends on timer resolution. Higher resolutions (10–16 bit) provide finer control over duty cycle, which is critical for smooth LED dimming, motor speed, or precise audio signals.
7. What is ESP32 PWM 16 bit?
ESP32 PWM 16 bit allows duty cycles from 0–65535, giving very smooth control for sensitive devices like RGB LEDs or audio output. Use ESP32 PWM allocate timer to manage multiple high-resolution channels efficiently.
8. Can ESP32 PWM control a fan?
Yes, using a ESP32 PWM fan controller setup. Set PWM frequency around 25 kHz to prevent noise, and vary duty cycle to adjust speed. Use a transistor or MOSFET for higher current fans.
9. How do I change ESP32 PWM frequency dynamically?
You can use ledcSetup(channel, newFrequency, resolution) to adjust the ESP32 PWM frequency on the fly. This is useful for audio applications (ESP32 PWM audio) or changing motor speed.
10. What is ESP32 PWM bit?
ESP32 PWM bit refers to resolution, e.g., 8-bit, 10-bit, 16-bit. Higher bit PWM provides smoother output. Choose resolution based on your device’s sensitivity, such as LEDs, buzzers, or motors.
11. How to capture PWM signals on ESP32?
ESP32 PWM capture allows reading incoming PWM signals to measure duty cycle and frequency, useful for sensors and feedback loops in embedded systems.
12. Can ESP32 PWM be used for audio output?
Yes, ESP32 PWM audio output can drive piezo buzzers or speakers. Adjust frequency and duty cycle for different tones. For higher-quality audio, use external DACs or amplifiers.
13. How to calculate duty cycle for ESP32 PWM?
Use a ESP32 PWM calculator: (Desired Voltage / Supply Voltage) * Max Duty Count. For 8-bit PWM, max count = 255; for 16-bit, max count = 65535.
14. What is the best way to wire ESP32 PWM circuits?
For LEDs, use resistors; for motors or fans, use MOSFETs and flyback diodes; for buzzers, connect directly or use an amplifier. Correct wiring ensures safety and prevents damage.
15. Which library is recommended for ESP32 PWM?
The Arduino ESP32 PWM library or the built-in ESP32 PWM API is recommended for beginners. They provide easy functions like ledcSetup(), ledcAttachPin(), and ledcWrite() for controlling duty cycle and frequency
Mr. Raj Kumar is a highly experienced Technical Content Engineer with 7 years of dedicated expertise in the intricate field of embedded systems. At Embedded Prep, Raj is at the forefront of creating and curating high-quality technical content designed to educate and empower aspiring and seasoned professionals in the embedded domain.
Throughout his career, Raj has honed a unique skill set that bridges the gap between deep technical understanding and effective communication. His work encompasses a wide range of educational materials, including in-depth tutorials, practical guides, course modules, and insightful articles focused on embedded hardware and software solutions. He possesses a strong grasp of embedded architectures, microcontrollers, real-time operating systems (RTOS), firmware development, and various communication protocols relevant to the embedded industry.
Raj is adept at collaborating closely with subject matter experts, engineers, and instructional designers to ensure the accuracy, completeness, and pedagogical effectiveness of the content. His meticulous attention to detail and commitment to clarity are instrumental in transforming complex embedded concepts into easily digestible and engaging learning experiences. At Embedded Prep, he plays a crucial role in building a robust knowledge base that helps learners master the complexities of embedded technologies.













