Project

General

Profile

PWM (Pulse Width Modulation)

Introduction

PWM or Pulse Width Modulation means toggling a pin on and off rapidly, and using the difference between the on-time and off-time to transmit information.

Take a LED for example. You can supply a continuous "1" to it, and have it light up, or supply a "0" and have it turn off completely.
To achieve varying levels of intensity (rather than simply on or off), it seems obvious we need to modify the amount of power we feed to it.
One way to do this would be to use a variable resistor or trimpot. We can make this controllable via our microcontroller using a digipot (digital trimpot).
However, this technique requires some added complexity. PWM offers an alternative: by switching on and off our LED fast enough, we can actually modulate how much power we supply to it by changing the ratio between the on-times and off-times.

What's really nice about PWM is that many microcontrollers include hardware wave generators, meaning the processor doesn't need to do anything but set the desired ratio.

Usages

PWM has many applications. Let's explore the basics.

As we've just seen above, PWM can be used to control the intensity of a LED. This has very practical implications: RGB LEDs can be used to produce any color by modulating the power given to each channel (red, green, blue).

Another important application is in motor control. PWM is a very nice way of delivering specific amounts of power to a motor, allowing precise speed control.

Also related to motor control, servos are usually controlled using PWM.

Example

The ioNode has 8 PWM outputs, however one of them is connected to the onboard activity LED, and two more are sharing SPI bus lines.
Here is the mapping:
  • PWM0 -> D4
  • PWM1 -> D5
  • PWM2 -> D6
  • PWM3 -> D7
  • PWM4 -> B3
  • PWM5 -> B7 (SPI MISO)
  • PWM6 -> B6 (SPI SCK)
  • PWM7 -> B4 (onboard activity LED)

For this example we will be using PWM4 (pin B3).

The pwm library (available in the SDK) provides a very simple way of controlling PWM outputs.
Before we can use it in our code, we need to include it as a dependency in the dfe.conf file of our application.

# Firmware Element Configuration
# ...
deps:
  - pwm

Now, let's use the void pwm(uint8_t pin, uint8_t v) method to set the LED to 50%.
The v argument defines the ratio, from 0 to 255.

void pwm(uint8_t pin, uint8_t v)
Arguments:

  • pin -> PWM output pin
  • v -> On-time ratio (0-255)

#include <pwm/pwm.h>

void main()
{
    // Set 50% ratio on PWM4
    pwm(4, 128);

    // Loop forever
    for(;;);
}