Pulse-Width-Modulation and LED brightness

What is Pulse-Width-Modulation ?

Pulse-width-modulation (PWM) is probably the most common way to produce an average analog voltage in electrical circuits via fast switching. The idea is simple: if you switch the voltage of a circuit between ON (Vrefvolts) and OFF (0 volts) sufficiently fast, you will generate an average voltage in the circuit proportional to the ratio between the length of time the circuit was ON and the length of time the circuit was OFF.

Let’s consider a few examples. Take a PWM frequency of 10kHz; this means that the ON/OFF cycle repeats 10000 times a second).

  • A 50% duty cycle means that the circuit is ON for half of the cycle and OFF otherwise (first row in the image below). Thus, the generated averaged voltage is about 0.5Vref.
  • A 25% duty cycle means that the circuit is ON for a fourth of each cycle and and OFF otherwise (last row in the image below). The generated voltage is about 0.25 Vref.
Peltier cell

PWM. Source: Wikipedia

This technique is so popular that you can find a full page on Wikipedia (https://en.wikipedia.org/wiki/Pulse-width_modulation) dedicated to it and several tutorials available on internet like Arduino and Sparkfun. You may find this video useful:



The PWM library

The MbedOS PWM library simplifies the use PWM on the microcontroller.

First, you need to declare your PWM output

PwmOut pwmled(LED2);

The instruction above sets LED2 as pwm output. Any other digital output compatible with PWM would work. Check your microcontroller manual to know which pins are compatible with PWM.

Then, you need to set the PWM period

pwmled.period_us(1000);

The instruction above sets a ON/OFF cycle every 1000 microseconds, that is, 1000 cycles each second.

Finally, the duty cycle is defined by

pwmled.write(0.1f);

The argument of the write function must be a float between 0 and 1. The instruction above sets the duty cycle at 10%.

You can also read the current PWM duty cycle through the instruction

pwmled.read();

which returns a floating-point value. For more details, please refer to the PwmOut API.

LED brightness through PWM

By now the following code should be quite readable.

#include "mbed.h"

PwmOut pwmled(LED2);

int main() {

        pwmled.period_us(1000);
        pwmled.write(0.1f);
        printf("pwm set to %.2f %%\n", pwmled.read());
}

The code switches ON and OFF the LED 10000 times a second. Within each cycle the LED is ON only for 10% of the time. Your eyes cannot see such fast frequencies and you will perceive the overal switching pattern as low brightness.

Try different duty cycles to adjust the brightness of the LED. Do you see a linear relation between duty cycle and brightness?

Tasks

  • Modify the code to change brightness levels by pressing the button.
  • Modify the code to make brightness slowly pulsating from low brightness to high brightness and back.