PWM pins on Arduino Uno

Building something you want to control using PWM signals? The Arduino Uno has 6 pins available, but they are not all the same.

Pin numbers

The Arduino Uno, and any clone that has the ATmega328(P) on board, has 6 pins that can output PWM signals by default. Unfortunately, they are not all the same. There are 2 groups:

  1. Pins 3, 9, 10, 11 have a 490Hz PWM (2040µs)
  2. Pins 5, 6 have a 980Hz PWM (1020µs)
PWM Arduino Uno (490Hz)
PWM Arduino Uno (490Hz)
PWM Arduino Uno (980Hz)
PWM Arduino Uno (980Hz)

Controlling the frequency is not possible with the basic commands. Controlling the duty cycle can be done with analogWrite(<pin>, <duty_cycle>)
The only issue here, is that the duty cycle is not specified in %, but in a byte value (0-255). A simple calculation can fix this.

pwm = byte( float(DutyCycle) / 100 * 255 );

Below is a sample code that controls all 6 PWM pins of the Arduino Uno with a sweep from 0-100%

PWM Arduino Uno duty cycle sweep
PWM Arduino Uno duty cycle sweep
byte DutyCycle = 0;    // Duty Cycle (%)
byte pwm;              // PWM pin value (0-255)
bool countUp = true;   // Sweep direction

/****************************************************************
      SETUP
****************************************************************/
void setup()
{
  ;
}


/****************************************************************
      LOOP
****************************************************************/
void loop()
{
  // Sweep pwm signal
  if (countUp) {
    DutyCycle++;
  }
  else {
    DutyCycle--;
  }

  // Change sweep direction at 0% and 100%
  if (DutyCycle == 100) {
    countUp = false;
  }
  else if (DutyCycle == 0) {
    countUp = true;
  }

  // Convert duty cycle (%) to PWM (0-255)
  pwm = byte( float(DutyCycle) / 100 * 255 );

  Serial.println(pwm);

  // Write PWM
  analogWrite(3, pwm);   // 490Hz ; 2040µs
  analogWrite(5, pwm);   // 980Hz ; 1020µs - (976Hz ; 1024µs)
  analogWrite(6, pwm);   // 980Hz ; 1020µs - (976Hz ; 1024µs)
  analogWrite(9, pwm);   // 490Hz ; 2040µs
  analogWrite(10, pwm);  // 490Hz ; 2040µs
  analogWrite(11, pwm);  // 490Hz ; 2040µs
}
//END

Changing the frequency

As with most (if not all) microcontrollers, the frequency of the PWM signal can be changed. However, doing so requires the use of clock dividers, and in many cases (depending on the timer affected) this will also affect the timing when functions like millis() and micros() are used, so use this with caution.

Changing the frequency is not explained in this tutorial, but you can find some detailed documentation on Secrets of Arduino PWM.

PWM pins on other Arduino boards

Arduino has many other boards besides the Uno. So how about those PWM pins?

ATmega328(P)

The Arduino Uno has a ATmega328(P) microchip. The Arduino Nano has the same microchip, but in a slightly different housing, as well as the Uno SMD. All PWM pins are the same as the Arduino Uno.

ATmega32U4

The Arduino Micro has a different microchip: the ATmega32U4. Therefore, it also has different PWM pins. Several documents, datasheets and forum seem to have conflicting information. Even the schematics on the Arduino website seem to be different from my experience. Therefore, I’ve put all pins on a logic analyser and figured out which pins really output PWM signals (with default settings).

PinFreq (Hz)PortBit
3980HzPD0Not in datahseet
5490HzPC6OK
6490HzPD7OK
9490HzPB5OK
10490HzPB6OK
11980HzPB7OK
12??PD6In datasheet but no signal
13490HzPC7OK

According to the microchip datasheet, PD6 (pin 12) should have a PWM signal as well, but I didn’t measure anything there. PD0 (pin 3) has a PWM signal, but it’s not specified in the datasheet.