PWM Tutorial for Arduino, ESP8266 and ESP32

PWM Tutorial for Arduino, ESP8266 and ESP32

In this tutorial we focus on Pulse Width Modulation (PWM) for the Arduino, ESP8266 and ESP32 microcontroller.

PWM is an important part to control different devices with your microcontroller.

For example you can control the brightness of an LED or the speed of a motor by changing the PWM.

PWM thumbnail

Table of Contents

How does PWM work?

The digital inputs / outputs on your microcontroller have a constant voltage of 3.3V (for ESP8266 and ESP32 boards) or 5V (for Arduino boards). But in some cases you want to control the voltage to a specific value between 0V and the maximum voltage.

In case of PWM, a signal is pulsing between HIGH (3.3V or 5V) and LOW (0V). How often the signal is changing between HIGH and LOW is defined by the PWM frequency. The PWM frequency on Arduino pins are 976 cycles per seconds (Herz), for the ESP8266 up to 1 kHz and for the ESP32 up to 40 MHz.

To generate a PWM signal you use the function analogWrite(pin, value). This function create a square wave PWM signal. You can control the shape of the PWM signal with the duty cycle of (value/255). A 0% to 100% duty cycle corresponds to a value between 0 and 255. The following table shows broadly the relation between the duty cycle and the average output voltage if the maximum voltage is 5V.

I used my oscilloscope to measure the duty cycles of the table above. Therefore I connected digital pin 11 of the Arduino Uno to my PicoScope and set up a measurement for the duty cycle. You can do the exactly same measurement for the ESP8266 or the ESP32

The code for the quick measurement is the following. For each measurement I changed the value for the analogWrite function.

Duty Cycle 0%
Note that the 0% duty cycle is measured as 100% because there is no square wave at 0% and also at 100%. Therefor be careful how the duty cycle is measured. In my case I have to see if the voltage is 0 at 100% duty cycle.

Duty Cycle 25%

Duty Cycle 50%

Duty Cycle 75%

Duty Cycle 100%

Create PWM Examples

The following table gives you an overview of all components and parts that I used for this tutorial. If you want to support my work, you can buy something from the following links and I will earn a small commission. This does not affect the price you pay for the products.

If you are interested in components and parts that I used in other tutorials, visit the components and parts page.

 Arduino UnoAmazonBanggoodAliExpress
ORESP8266 NodeMCUAmazonBanggoodAliExpress
ORESP32 NodeMCUAmazonBanggoodAliExpress
ANDResistor and LED in PackageAmazonBanggoodAliExpress
ANDDC MotorAmazonBanggoodAliExpress
ANDL298N Motor Driver ModuleAmazonBanggoodAliExpress

Change the brightness of an LED by PWM

In the following example we want to change the brightness of an LED by changing the duty cycle of the regarding PWM signal.
The following fritzing sketch shows the circuit done with an Arduino Uno. We have to make sure that the LED is connected to an Arduino pin which has PWM ability.

The program code is pretty straight forward. We have to define the pins and some variables for the time and the height to increment the brightness of the LED. If you want to know how to change the color for multicolor LEDs, using different PWM signals, you find this in my LED tutorial.

int LEDpin = 11;   // define the pin of the LED
int bright = 0;    // initial value of LED brightness
int incremt = 5;   // incremental change in PWM frequency
int time = 100;    // time period the PWM frequency is changing

void setup()
    pinMode(LEDpin, OUTPUT);  // define the LEDpin as output pin

void loop()
    analogWrite(LEDpin, bright);  // set LED brightness as PWM signal
    delay(time);                  // wait for a time period
    bright = bright + incremt;    // increment LED brightness
    // if the brightness is out of range, reduce brightness
    if (bright <=0 || bright >=255) incremt = - incremt;

Control the speed of an DC motor by PWM

The second example shows how we can change the speed of an DC motor with the help of a PWM signal. We use the L298N motor driver module to connect the Arduino to the DC motor. Also it is recommend to power the DC motor with an external power supply. Therefore I use 4 AA batteries, each with 1.5V so in total 6V.
I want to focus on the PWM signal in this example. Therefor I do not further describe the DC motor example. But if you are interested in DC motors, I wrote an extra article about DC motors, that explains everything in detail.

For the program code we want to increase the motor speed each second. At the start, the voltage provided through the PWM signal is to low to start the motor. This is why it takes some intervals in the for loop until the motor is turning.

// L298N to Arduino Uno connection
int enA = 10;
int in1 = 9;
int in2 = 8;

int motor_speed = 0; 

void setup()
  // set all the motor control pins to outputs
  pinMode(enA, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);

void loop()
  // run the motor between 0 and 250 in increments of 10
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  for(motor_speed = 0; motor_speed < 250; motor_speed += 10)
    analogWrite(enA, motor_speed); // PWM output


I hope you enjoined this article about the PWM signal. The PWM signal is a very handy tool which is used a lot in practical examples. It is recommended to know how PWM is working. Therefore if you have any further questions, use the comment section below to ask.

Leave A Comment