ESP32 PWM with example : dimming an LED

The ESP32 microcontroller offers a versatile and powerful feature set, making it ideal for numerous IoT applications. One of its standout features is the ability to generate PWM (Pulse Width Modulation) signals. PWM is commonly used for controlling motors, LEDs, displays, and other devices that require analog control through digital means. In this blog post, we will explore how to use PWM on the ESP32 to dim an LED.

Before you read this you also want to read the previous basic tutorials on how to use the ESP32 other features:

- ESP WROOM 32: LED Blink Tutorial

- ESP32 Tutorial on Controlling an LED with a Pushbutton 

What is PWM?

PWM stands for Pulse Width Modulation. It is a technique used to simulate an analog output using digital means. By rapidly switching a digital signal on and off, PWM can effectively create a range of output levels. The ratio of the "on" time to the "off" time is known as the duty cycle, expressed as a percentage.

  • 0% Duty Cycle: The signal is always off.
  • 50% Duty Cycle: The signal is on half the time and off half the time.
  • 100% Duty Cycle: The signal is always on.

By adjusting the duty cycle, we can control the brightness of an LED, the speed of a motor, or other analog properties of electronic devices. For examples of Fast PWM mode with Arduino see ATmega328P Fast PWM mode Programming Examples.

Setting Up PWM on ESP32

The ESP32 has 16 independent PWM channels, allowing you to control the duty cycle and frequency of the PWM signal. To dim an LED using PWM, follow these steps:

Components Needed:
  • ESP32 development board
  • LED
  • Resistor (220 ohms)
  • Breadboard and jumper wires
Circuit Diagram:

The following is the circuit diagram for applying PWM signal to the LED with ESP32 board.

esp32 PWM animation
  1. Connect the anode (long leg) of the LED to GPIO 4 on the ESP32.
  2. Connect the cathode (short leg) of the LED to one end of the 220-ohm resistor.
  3. Connect the other end of the resistor to the ground (GND) pin on the ESP32.

Code Example:

Here’s a simple code example to demonstrate how to use PWM to dim an LED with the ESP32 using the Arduino IDE:

// Constants for PWM
const int ledPin = 4;    // GPIO where the LED is connected
const int pwmChannel = 0;
const int freq = 5000;   // PWM frequency
const int resolution = 8; // 8-bit resolution (0-255)

// Variables to store duty cycle
int dutyCycle = 0;

void setup() {
  // Configure the PWM channel
  ledcAttachChannel(ledPin, freq, resolution, pwmChannel);
}

void loop() {
  // Gradually increase the brightness
  for(dutyCycle = 0; dutyCycle <= 255; dutyCycle++){
    ledcWrite(pwmChannel, dutyCycle);
    delay(15);
  }
  
  // Gradually decrease the brightness
  for(dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
    ledcWrite(pwmChannel, dutyCycle);
    delay(15);
  }
}

Code Explanation

// Constants for PWM const int ledPin = 4; // GPIO where the LED is connected const int pwmChannel = 0; const int freq = 5000; // PWM frequency const int resolution = 8; // 8-bit resolution (0-255) // Variables to store duty cycle int dutyCycle = 0;
 

Constants for PWM:

  • ledPin: This defines the GPIO pin number where the LED is connected. In this case, the LED is connected to GPIO 4.
  • pwmChannel: The ESP32 has 16 independent PWM channels. Here, we are using channel 0.
  • freq: This defines the frequency of the PWM signal. In this case, it's set to 5000 Hz (5 kHz).
  • resolution: This sets the resolution of the PWM signal. An 8-bit resolution means the duty cycle can have values between 0 and 255.

Variables to store duty cycle:

  • dutyCycle: This variable will store the duty cycle value, which determines the brightness of the LED.

setup() Function

void setup() {
  // Configure the PWM channel
  ledcSetup(pwmChannel, freq, resolution);
 
  // Attach the PWM channel to the GPIO pin
  ledcAttachPin(ledPin, pwmChannel);
}
 
  • ledcSetup(pwmChannel, freq, resolution);: This function configures the PWM channel. It sets the frequency (freq) and resolution (resolution) for the specified pwmChannel.
  • ledcAttachPin(ledPin, pwmChannel);: This function attaches the configured PWM channel to the specified GPIO pin (ledPin). This means GPIO 4 will output the PWM signal controlled by channel 0.

loop() Function

void loop() {
  // Gradually increase the brightness
  for(dutyCycle = 0; dutyCycle <= 255; dutyCycle++){
    ledcWrite(pwmChannel, dutyCycle);
    delay(15);
  }
 
  // Gradually decrease the brightness
  for(dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
    ledcWrite(pwmChannel, dutyCycle);
    delay(15);
  }
}
 

Increasing and Decreasing Brightness:

  • The loop() function contains two for loops that gradually increase and decrease the brightness of the LED by adjusting the duty cycle.
  1. Increasing Brightness:

    for(dutyCycle = 0; dutyCycle <= 255; dutyCycle++){
      ledcWrite(pwmChannel, dutyCycle);
      delay(15);
    }

    This loop starts with dutyCycle set to 0 and increments it by 1 until it reaches 255.

    • ledcWrite(pwmChannel, dutyCycle);: This function sets the duty cycle of the specified pwmChannel. The brightness of the LED increases as the duty cycle increases.
    • delay(15);: This introduces a delay of 15 milliseconds between each increment, creating a gradual increase in brightness.

     
  2.  Decreasing Brightness:
            for(dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
              ledcWrite(pwmChannel, dutyCycle);
              delay(15);
                }
            
  • This loop starts with dutyCycle set to 255 and decrements it by 1 until it reaches 0.
  • The ledcWrite(pwmChannel, dutyCycle); function again sets the duty cycle, but this time the brightness decreases as the duty cycle decreases.
  • The delay(15); function creates a gradual decrease in brightness by delaying each decrement by 15 milliseconds.
  • Program Code Summary

    • Setup: Configures PWM on GPIO 4 using channel 0 with a frequency of 5000 Hz and an 8-bit resolution.
    • Loop: Gradually increases and then decreases the brightness of an LED connected to GPIO 4 by adjusting the PWM duty cycle from 0 to 255 and back to 0.

    This code demonstrates how to control the brightness of an LED using PWM on an ESP32, providing a smooth dimming effect.

    Uploading and Testing the Code

    1. Connect your ESP32 to your computer and open the Arduino IDE.
    2. Select your ESP32 board and the correct COM port from the Tools menu.
    3. Click the upload button.
    4. Once the code is uploaded, observe the LED gradually dimming and brightening.

    See the following video which demonstrates the dimming of the LED animation in proteus professional electronics design software.

     


    Conclusion

    PWM on the ESP32 is a powerful feature that enables precise control over devices like LEDs. By using the built-in PWM functionality, you can create various effects and control mechanisms in your projects. The code example provided here demonstrates a simple yet effective way to dim an LED, but the same principles can be applied to many other applications in the world of IoT. NodeMCU is similar board to ES32 board and the tutorial NodeMCU ESP8266 PWM: LED brightness fading shows how to dim a LED which is similar to this project.

    1 Comments

    Previous Post Next Post