ESP32 PWM using Arduino IDE

Learn to generate and control the PWM signals on ESP32 pins. We will go through two methods: analogWrite( ) and ledcAttach( ).
We will learn how to control PWM Frequency, Duty Cycle, and Resolution of ESP32 using Arduino IDE.

What is PWM?

Imagine

ESP32 PWM

The PWM signal can be generated by two methods in on ESP32:
  1. analogWrite( ) function
  2. LEDC Driver library

Image(pin diagram),
specifications of PWM

Method 1: analogWrite()

void analogWrite(pin, dutyCycle),
analogWrite( ) function generates steady rectangular wave until next call to analogWrite( ) (or digitalWrite( ) ordigitalRead( ) digitalRead) on the same pin. analogWrite() function returns nothing.
Parameters
  • pin: GPIO Pin
  • dutyCycle: dutyCycle ranging from 0 (always OFF) to 255 (always ON)
Returns
    Nothing
Note:
  • The analogWrite( ) is a Arduino IDE function. For ESP32 library, it calls ledcAttach( ) and ledcWrite( ) function internally.
  • By default, sets frequency = 1000 Hz and Resolution = 8 bits
  • Please check ledcAttach() and ledcWrite() function here

Method 2: LEDC Driver

You can use the LEDC library to generate a PWM signal. ledcAttach( ) attaches the pin where as ledcWrite( )generates the PWM signal.

ledcAttach()

bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution);
ledcAttach( ) attaches a pin to the LEDC driver, with a given frequency, resolution and channel. The channel is selected automatically.
Parameters
  • pin: GPIO Pin
  • freq: frequency of PWM signal
  • resolution: resolution for LEDC pin
Returns
    configuration status : success ( true ) or, failure ( false ).

ledcWrite()

bool ledcWrite(uint8_t pin, uint32_t duty);
ledcWrite( ) sets the PWM duty cycle of the pin.

Parameters
  • pin: GPIO Pin
  • duty: duty cycle (0 to 2^resolution – 1)
Returns
    configuration status : true if duty cycle was successfully set, false otherwise.

Example 1: Fading LED – analogWrite()

We will increase and decrease the LED brightness over time. We will use the analogWrite() function to control the brightness of the LED.

Code

const int ledPin = 2;

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // Increasing LED brightness
  for(int val=0; val<=255; val++)
  {
    analogWrite(ledPin, val); 
    delay(1);
  }

  // Decreasing LED brightness
  for(int val=255; val>=0; val--)
  {
    analogWrite(ledPin, val);
    delay(1);
  }
}

Explanation

Start by defining the LED pin. In this example, we will be using an onboard LED attached to GPIO 2.

const int ledPin = 2;

Configure the LED pin as an OUTPUT pin.

pinMode(ledPin, OUTPUT);

Vary the duty cycle using a for loop. Notice how we use the first for loop to increase the duty cycle from 0 to 255 and then the second for loop to decrease the duty cycle from 255 to 0. You can change the delays to make the LED fade quickly or slowly.

// Increasing LED brightness
for(int val=0; val<=255; val++)
  {
    analogWrite(ledPin, val); 
    delay(1);
  }

// Decreasing LED brightness
  for(int val=255; val>=0; val--)
  {
    analogWrite(ledPin, val);
    delay(1);
  }

Use the analogWrite() function to set the duty cycle.

analogWrite(ledPin, val);

Output

Example 2: Fading LED – ledcWrite()

We will increase and decrease the LED brightness over time. We will use the ledcWrite() function to control the brightness of the LED.

Code

const int ledPin          = 2;
const uint32_t frequency  = 1000;
const uint8_t resolution  = 8;
uint32_t maxDutyCycle     = (1 << resolution) - 1;

void setup() {
  ledcAttach(ledPin, frequency, resolution);
}

void loop() {
  // Increasing LED brightness
  for (uint32_t duty = 0; duty <= maxDutyCycle; duty++) {
    ledcWrite(ledPin, duty);
    delay(1);
  }

  // Decreasing LED brightness
  for (int32_t duty = maxDutyCycle; duty >= 0; duty--) {
    ledcWrite(ledPin, duty);
    delay(1);
  }
}

Output

Explanation

Start by defining the LED pin, we will be using the built-in LED at GPIO. Set desired frequency and resolution.

const int ledPin          = 2;
const uint32_t frequency  = 1000;
const uint8_t resolution  = 8;

For iteration, calculate the maxDutyCycle by the following method. The code line performs the following action:
maxDutyCycle = 2reolution – 1

uint32_t maxDutyCycle = (1 << resolution) - 1;

Attach the LED pin to the LEDC driver, with a given frequency, resolution, and channel using the ledcAttach() function.

ledcAttach(ledPin, frequency, resolution);

Vary the duty cycle using a for loop. Notice how we use the first for loop to increase the duty cycle from 0 to maxDutyCycle (255) and then the second for loop to decrease the duty cycle from maxDutyCycle (255) to 0. You can change the delays to make the LED fade quickly or slowly.

// Increasing LED brightness
  for (uint32_t duty = 0; duty <= maxDutyCycle; duty++) {
    ledcWrite(ledPin, duty);
    delay(1);
  }

  // Decreasing LED brightness
  for (int32_t duty = maxDutyCycle; duty >= 0; duty--) {
    ledcWrite(ledPin, duty);
    delay(1);
  }

Use the ledcWrite() function to set the duty cycle.

ledcWrite(ledPin, duty);

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *