Arduino Tutorial - Pulsweitenmodulation (PWM)

PWM stands for pulse width modulation and Arduino uses this powerful PWM technique to control analog circuits with its digital outputs. The digital control is only turned on (full 5 V) or off (0 V) in binary format, and this on/off pattern can produce a square wave signal. For example, if you want a half-bright LED, you can either cut the current across the LED in half or use the more flexible PWM technique by sending a square wave signal to the LED at 50%.

PWM has many applications such as controlling servos and speed controllers or LEDs.

Basic principle of PWM

Pulse width modulation is basically a square wave with a varying high and low time. A basic PWM signal is shown in the figure below.

There are several terms associated with PWM:

  • On-Time - time signal is high.
  • Off-Time - time signal is low.
  • Period - Sum of the on-time and off-time of the PWM signal.
  • Duty Cycle - percentage of the time signal that remains on for the duration of the PWM signal.


As shown in the sketch, Tone denotes the on time and Toff denotes the off time of the signal. The period is the sum of the on and off times and is calculated as in the equation below:

Duty Cycle

The duty cycle is calculated as the on-time of the period. Using the period calculated above, the Duty Cycle is determined as follows:

analogWrite () function

The analogWrite () function writes an analog value (PWM wave) to a pin. It can be used to illuminate an LED with different brightness or to drive a motor with different speeds. After a call to the analogWrite () function, the pin generates a continuous square wave signal of the specified duty cycle until the next call to analogWrite () or a call to digitalRead () or digitalWrite () on the same pin. The frequency of the PWM signal at most pins is about 490 Hz. On the Uno and similar boards, pins 5 and 6 have a frequency of about 980 Hz. Pins 3 and 11 on the Leonardo also run at 980 Hz.

On most Arduino boards (ATmega168 or ATmega328) this function works on pins 3, 5, 6, 9, 10 and 11. On the Arduino Mega it works on pins 2 - 13 and 44 - 46. Older Arduino boards with an ATmega8 only support analogWrite () on pins 9, 10 and 11.

The Arduino Due supports analogWrite () on pins 2 - 13 and pins DAC0 and DAC1. Unlike the PWM pins, DAC0 and DAC1 are digital-to-analog converters and act as true analog outputs.

You do not need to call pinMode () to set the pin as an output before calling analogWrite ().

The analogWrite() function syntax looks like this:

analogWrite ( pin , value ) ;

Value is the duty cycle between 0 (always off) and 255 (always on).

Arduino PWM Example

This Arduino tutorial shows how to dim an LED using PWM technology. In this example, digital pin 3 is used as the PWM output. However, you can also use another pin that is marked PWM. On the Arduino UNO, these are PIN 3, 5, 6, 9, 10, and 11.

Arduino code:

int inputPin = A0; // set input pin for the potentiometer int inputValue = 0; // potentiometer input variable int ledPin = 3; // set output pin for the LED void setup() { // declare the ledPin as an OUTPUT: pinMode(ledPin, OUTPUT); } void loop() { // read the value from the potentiometer: inputValue = analogRead(inputPin); // send the square wave signal to the LED: analogWrite(ledPin, inputValue/4); }

analogRead () always returns the range between 0 and 1023 from the analog device (in this case from the potentiometer). The analogWrite () function only supports the range from 0 to 255, e.g. analogWrite (127) always sends a 50% duty cycle to the LED and analogWrite (255) is 100% and therefore full brightness. By turning the potentiometer, the brightness of the LED will change in the example.

Fritzing Schematics