ESP8266 PWM with Arduino IDE – Dim LED

This tutorial shows how to generate PWM signals with ESP8266 using Arduino IDE. As an example, we’ll dim the LED brightness by changing the duty cycle over time.

ESP8266 Pulse-Width Modulation (PWM) pins with Arduino IDE

PWM signals on ESP8266 have 10-bit resolution. To generate a PWM signal on the ESP8266 pins with Arduino IDE, use analogWrite(pin, value). The value is an integer between 0 and 1023.

You might also like reading other guides about PWM:

Before proceeding with this tutorial you should have the ESP8266 add-on installed in your Arduino IDE. Follow the next tutorial to Install ESP8266 in Arduino IDE.

ESP8266 PWM (Pulse-Width Modulation)

The ESP8266 GPIOs can be set either to output 0V or 3.3V, but they can’t output any voltages in between. However, you can output “fake” mid-level voltages using pulse‑width modulation (PWM), which is how you’ll produce varying levels of LED brightness for this project.

If you alternate an LED’s voltage between HIGH and LOW very fast, your eyes can’t keep up with the speed at which the LED switches on and off; you’ll simply see some gradations in brightness.

ESP8266 Fade LED with Pulse-Width Modulation (PWM) using analogWrite function

That’s basically how PWM works — by producing an output that changes between HIGH and LOW at a very high frequency.

The duty cycle is the fraction of time period at which LED is set to HIGH. The following figure illustrates how PWM works.

How Pulse-Width Modulation (PWM) works on ESP8266 to Fade an LED

A duty cycle of 50 percent results in 50 percent LED brightness, a duty cycle of 0 means the LED is fully off, and a duty cycle of 100 means the LED is fully on. Changing the duty cycle is how you produce different levels of brightness.

analogWrite()

To produce a PWM signal on a given pin you use the following function:

analogWrite(pin, value);
  • pin: PWM may be used on pins 0 to 16
  • value: should be in range from 0 to PWMRANGE, which is 1023 by default. When value is 0, PWM is disable on that pin. A value of 1023 corresponds to 100% duty cycle

You can change the PWM range by calling:

analogWriteRange(new_range);

By default, ESP8266 PWM frequency is 1kHz. You can change PWM frequency with:

analogWriteFreq(new_frequency);

ESP8266 Dim LED with PWM

In this section, we’ll build a simple example that dims an LED so that you see how to use PWM in your projects. You’ll need the following parts:

If you’re using an ESP-01, you need an FTDI programmer or a Serial Adapter to upload code.

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Schematic

After uploading the code, wire an LED to your ESP8266 as shown in the following schematic diagram.

ESP8266 LED Connected to GPIO 2 Wiring Schematic Diagram

If you’re using an ESP-01, you can check the board pinout here.

ESP8266 PWM Code

Copy the code to your Arduino IDE and upload it to your ESP8266.

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

const int ledPin = 2; 

void setup() {
  
}

void loop() {
  // increase the LED brightness
  for(int dutyCycle = 0; dutyCycle < 1023; dutyCycle++){   
    // changing the LED brightness with PWM
    analogWrite(ledPin, dutyCycle);
    delay(1);
  }

  // decrease the LED brightness
  for(int dutyCycle = 1023; dutyCycle > 0; dutyCycle--){
    // changing the LED brightness with PWM
    analogWrite(ledPin, dutyCycle);
    delay(1);
  }
}

View raw code

How the code works

Continue reading this section to learn how the code works, or skip to the next section.

Start by defining the pin LED is attached to. In this case, LED is attached to GPIO 2 (D4).

const int ledPin = 2;

In the loop(), you vary the duty cycle between 0 and 1023 to increase the LED brightness.

for(int dutyCycle = 0; dutyCycle < 1023; dutyCycle++){ 
  // changing the LED brightness with PWM
  analogWrite(ledPin, dutyCycle);
  delay(1);
}

And then, between 1023 and 0 to decrease brightness.

for(int dutyCycle = 1023; dutyCycle > 0; dutyCycle--){
  // changing the LED brightness with PWM
  analogWrite(ledPin, dutyCycle);
  delay(1);
}

To set the LED brightness, you need to use analogWrite() function that accepts as arguments GPIO where you want to get the PWM signal and a value between 0 and 1023 to set the duty cycle.

Upload the Code

In your Arduino IDE, go to Tools > Board and select your ESP8266 model (If you’re using an ESP-01, select “Generic ESP8266 Module”) .

Go to Tools > Port and select COM port the ESP8266 is connected to.

If you’re using an ESP-01, you need an FTDI programmer or Serial Adapter to upload code. Here’s the connections you need to make:

ESP8266 ESP-01 connected to FTDI programmer to upload new Arduino Sketch
ESP-01FTDI Programmer
RXTX
TXRX
CH_PD3.3V
GPIO 0GND
VCC3.3V
GNDGND

Demonstration

After uploading your sketch, the LED connected to GPIO 2 should increase and decrease its brightness over time.

ESP8266 Fading LED PWM Circuit Wiring Schematic diagram

You can connect GPIO 2 to an oscilloscope to see how the PWM signal changes over time.

ESP8266 Fading LED PWM Circuit Wiring Schematic diagram oscilloscope demonstration

Read our buying guide: Best Oscilloscopes for Beginners and Electronics Hobbyists.

Wrapping Up

We hope you’ve found this guide about the ESP8266 PWM usage interesting. Besides controlling the LED brightness, PWM can also be used to control the DC motors speed.

You may also like trying our other projects:

If you like ESP8266 make sure you take a look at our resources:

Thanks for reading.


Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »

Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »


Enjoyed this project? Stay updated by subscribing our weekly newsletter!

Leave a Comment

Download our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.