ESP32 Arduino: LED PWM fading

The objective of this post is to explain how to fade a LED with the ESP32, using the LED PWM functionalities.


Introduction

The objective of this post is to explain how to fade a LED with the ESP32, using the LED PWM functionalities of the microcontroller. I will be using DFRobot’s FireBeetle ESP32 board to perform the tests. Since the board as a built in LED, no external hardware will be needed.

Note that at the time of writing, the commonly used analogWrite Arduino function was not yet available for the ESP32 Arduino environment support [1]. Thus, we will need to go to lower level functions in this tutorial. Nevertheless, we will also have more control and flexibility in the PWM functionality, which is good.

In terms of hardware, the LED PWM of the ESP32 is composed of 16 independent channels, with configurable duty cycles and wave periods [2]. The accuracy of the duty cycle can be configured until 16 bits of resolution [2][3].


The setup

In the first portion of the code, we will specify some global configuration constants. The first one will be the frequency of the PWM signal generated to control the LED. We will use a value of 5000 Hz. Note however that the maximum values for the frequency are not yet very clear and in the header file of the functionality we are going to use is stated that the maximum frequency depends on the resolution chosen.

We are algo going to specify the LED PWM channel and the resolution of the PWM duty cycle, in bits. Also from the header file, we can see that we can choose a channel from 0 to 15 and a resolution between 1 and 16 bits, which is coherent with the values mentioned on the introductory section. We will use channel 0 and a resolution of 8 bits.

int freq = 5000;
int ledChannel = 0;
int resolution = 8;

Now, in the setup function, we will configure the LED PWM functionalities. First, we need to setup the channel, frequency and resolution we specified. To do so, we call the ledcSetup function, which receives as input the 3 previously mentioned parameters, in the same order.

ledcSetup(ledChannel, freq, resolution);

Note however that the channel is not the pin where we will control the LED. So, we will need to attach channel 0 (which was the one we defined) to the digital pin where we want the PWM signal to be generated.

In our case, we want it to be generated on the pin that is connected to the on board LED. As we’ve seen in this previous tutorial, we can use the LED_BUILTIN constant to get the number of the pin connected to the LED on our FireBeetle ESP32 board.

To attach the pin to the PWM channel, we call the ledcAttachPin function, passing as arguments the number of the GPIO pin and the PWM channel previously defined.

ledcAttachPin(LED_BUILTIN, ledChannel);

The full setup function is shown bellow, along with the constants definition.

int freq = 5000;
int ledChannel = 0;
int resolution = 8;

void setup() {

  ledcSetup(ledChannel, freq, resolution);
  ledcAttachPin(LED_BUILTIN, ledChannel);

}


Main loop

We will write the code to control the duty cycle values of the signal in our Arduino main loop. But the most important function will be the one that allows us to specify the duty cycle value. This is the ledcWrite function, which receives as first input the PWM channel (not the number of the GPIO) and as second input the value for the duty cycle.

Since we defined a 8 bits resolution, we can specify a duty cycle value between 0 and 255 (2^8 -1). So, we will iterate between these values in two loops, one ascending and other descending. You can check bellow the full source code, which already includes the call for the ledcWrite function and these two loops.

int freq = 5000;
int ledChannel = 0;
int resolution = 8;

void setup() {

  ledcSetup(ledChannel, freq, resolution);
  ledcAttachPin(LED_BUILTIN, ledChannel);

}

void loop() {

  for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){
ledcWrite(ledChannel, dutyCycle);
delay(7);
}

for (int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
     ledcWrite(ledChannel, dutyCycle);
     delay(7);
  }

}


Testing the code

To test the code, just upload it with the Arduino IDE. Then, you should see the on board LED fading. Check the video bellow for the expected result.

 

Related content


References

[1] https://github.com/espressif/arduino-esp32#development-status

[2] https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf

[3] https://github.com/espressif/arduino-esp32/blob/a4305284d085caeddd1190d141710fb6f1c6cbe1/cores/esp32/esp32-hal-ledc.h

Advertisements
This entry was posted in ESP32 and tagged , , , , , , . Bookmark the permalink.

5 Responses to ESP32 Arduino: LED PWM fading

  1. Pingback: ESP32 Arduino: Controlling a buzzer with PWM | techtutorialsx

  2. Pingback: GADGET CORPORATION | IOT Made Simple: Playing With the ESP32 on Arduino IDE

  3. Pingback: “IOT feito fácil”: Brincando com o ESP32 no Arduino IDE «

  4. Eidu says:

    Is it possible to control a Servo motor to go from 0-180 then stop?

    Liked by 1 person

    • antepher says:

      Hi! I’ve not been working with servos for a long time, but I think it should be possible as long as your servo allows to control the position on those angles.

      For the regular Arduino Boards, there are plenty of libraries to control servos,

      I haven’t yet tested any for the ESP32, but from a quick search I’ve found this:
      https://github.com/jkb-git/ESP32Servo

      You can also implement the servo control yourself.

      Hope this helps getting you in the right track.

      Best regards,
      Nuno Santos

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s