Logo

Control LED Brightness using PWM with ESP32

What is PWM (Pulse Width Modulation)?

PWM stands for Pulse Width Modulation. It's a technique used to simulate analog output using digital signals. By rapidly toggling a pin HIGH and LOW with variable duty cycles, PWM can control devices like LEDs, motors, and more. In the case of an LED, varying the duty cycle controls its brightness.

Working Principle of PWM for LED Dimming

PWM signals generate a square wave with a fixed frequency but variable duty cycle. When the duty cycle increases, the LED appears brighter, and when it decreases, the LED dims. The LED does not flicker because the frequency is high enough that our eyes perceive an average brightness.

  • Configure a PWM-capable pin on ESP32.
  • Set frequency and resolution (typically 5000Hz, 8-bit).
  • Attach a channel to the GPIO pin.
  • Change duty cycle to vary brightness.

Formula: Brightness ∝ Duty Cycle (%) = (PWM Value / Max Value) × 100

Components Required

  • ESP32 board
  • LED
  • 220Ω Resistor
  • Breadboard
  • Jumper wires

Pin Configuration

  • GPIO 16: PWM output to LED
  • GND: Common ground

Ensure the resistor is connected in series with the LED to limit current. The ESP32 can output PWM on most GPIOs except GPIOs 6–11 (used for flash).

Wiring LED to ESP32 (PWM)

  • LED Anode (+) -> GPIO 16 (through 220Ω resistor)
  • LED Cathode (−) -> GND

Arduino Code for LED Brightness Control using PWM

1#define LED_PIN 16
2#define PWM_CHANNEL 0
3#define PWM_FREQ 5000
4#define PWM_RESOLUTION 8
5
6void setup() {
7  ledcSetup(PWM_CHANNEL, PWM_FREQ, PWM_RESOLUTION);
8  ledcAttachPin(LED_PIN, PWM_CHANNEL);
9}
10
11void loop() {
12  for (int duty = 0; duty <= 255; duty++) {
13    ledcWrite(PWM_CHANNEL, duty);
14    delay(10);
15  }
16  for (int duty = 255; duty >= 0; duty--) {
17    ledcWrite(PWM_CHANNEL, duty);
18    delay(10);
19  }
20}

Code Explanation (Line-by-Line)

  • #define LED_PIN 16: Defines GPIO 16 as the output pin for the LED.
  • #define PWM_CHANNEL 0: Selects PWM channel 0 (ESP32 supports multiple channels).
  • ledcSetup(PWM_CHANNEL, PWM_FREQ, PWM_RESOLUTION);: Initializes the PWM channel with a frequency of 5000 Hz and 8-bit resolution.
  • ledcAttachPin(LED_PIN, PWM_CHANNEL);: Binds the LED pin to the specified PWM channel.
  • for (int duty = 0; duty <= 255; duty++): Increases brightness by incrementing duty cycle.
  • ledcWrite(PWM_CHANNEL, duty);: Sets the current PWM duty cycle (0–255).
  • delay(10);: Creates a smooth fading effect by adding a short delay.
  • for (int duty = 255; duty >= 0; duty--): Decreases brightness gradually to create a fading-out effect.

Applications

  • LED Dimming in Smart Lighting Systems
  • Controlling Motor Speed
  • Analog Signal Simulation
  • Power Control Systems
  • Sound and Tone Generation

Conclusion

Using PWM on ESP32 to control LED brightness is a simple and powerful concept. It helps simulate analog output using digital pins and is useful for many real-world applications including lighting, motor control, and automation. With just a few lines of code and basic components, you can smoothly dim or brighten an LED using software.