Arduino PWM frequency, measured on every pin
Or see every lesson.
- 455parts on the bench
- 43boards running now
- 1.00xreal time, on every board
analogWrite() on an Uno switches the pin on and off at a fixed rate: about 490 Hz on pins 3, 9, 10 and 11, and about 980 Hz on pins 5 and 6. analogWrite() only sets the duty, the share of each cycle the pin is high. To change the frequency you change the timer behind the pin, one line of setup().
The circuit above is an LED on pin 9 with a frequency counter clipped to the same pin. Press Run. The LED steps through eight brightnesses and the serial monitor prints each one, such as "duty 128 of 255 = 50 percent". The counter reads 490.2 Hz the whole time: the brightness changes, the frequency does not. At duty 0 and 255 it shows no frequency at all, because the pin stops switching.
Below is the frequency on each pin, how to change it, a 25 kHz signal for a PC fan, the one timer you must not touch, and why it does not matter whether you set the timer before or after analogWrite().
Want the step-by-step version? The lesson "Brightness from a digital pin" walks through this with checkpoints.
Open the lessonThe frequency on each pin
Each pair of PWM pins shares one of the Uno’s three timers. Timer 0 runs pins 5 and 6, timer 1 runs 9 and 10, and timer 2 runs 3 and 11. We ran the sketch below on each pin with the counter on it. Pins 3, 9, 10 and 11 read 490.20 Hz, and pins 5 and 6 read 976.56 Hz.
The two numbers come from the same 16 MHz clock divided by 64. Timer 0 counts up to 255 and starts again, 976.56 times a second. The other two count up and back down, which takes twice as long, so 490.20. Timer 0 runs the faster way because it also keeps time for millis().
Pins without a timer, such as 7 or 13, have no PWM at all: analogWrite(7, 128) just turns the pin on, and the counter read no frequency.
void setup() {
pinMode(9, OUTPUT);
analogWrite(9, 128);
}
void loop() {
}Changing the frequency
The lowest three bits of each timer’s control register B pick how much the 16 MHz clock is divided. Clear them and set a new value, and the frequency changes on both of that timer’s pins. The sketch below sets timer 1 to divide by 1 instead of 64, and pin 9 read 31372.55 Hz, well above hearing, which is what you want for a motor that whines.
For timer 1 (pins 9 and 10), the values 1 to 5 gave 31372.55, 3921.57, 490.20, 122.55 and 30.64 Hz. Timer 2 (pins 3 and 11) has more steps: 1 to 7 gave 31372.55, 3921.57, 980.39, 490.20, 245.10, 122.55 and 30.64 Hz. The duty from analogWrite() still works at every one.
void setup() {
pinMode(9, OUTPUT);
analogWrite(9, 128);
// Timer 1 runs pins 9 and 10. Prescaler 1 instead of 64:
TCCR1B = (TCCR1B & 0b11111000) | 0x01;
}
void loop() {
}Before or after analogWrite(), it stays
The Uno sets up all three timers once, before setup() runs, and analogWrite() never touches them again. It only connects the pin to its timer and sets the duty. So you can change the prescaler first and call analogWrite() later, as often as you like, and the new frequency stays. The sketch below sets timer 1 to divide by 1 in setup() and then calls analogWrite(9, 128) every 100 ms, and pin 9 read 31372.55 Hz the whole time.
Writing the compare register directly does the same job as analogWrite() on a PWM pin that is already running: OCR1A = 64; sets pin 9 to a quarter duty and kept 31372.55 Hz too.
void setup() {
pinMode(9, OUTPUT);
// The timer first: prescaler 1 instead of 64.
TCCR1B = (TCCR1B & 0b11111000) | 0x01;
}
void loop() {
analogWrite(9, 128); // only the duty: the 31 kHz stays
delay(100);
}25 kHz for a PC fan
Four-pin PC fans want a 25 kHz PWM signal, which no prescaler gives. Timer 1 can count to a top of your choosing, set in ICR1. With no prescaler and a top of 320, it counts up and down 25000 times a second, and the counter on pin 9 read exactly 25000 Hz. OCR1A sets the duty, from 0 to 320; 160 is half.
void setup() {
pinMode(9, OUTPUT);
// Timer 1, phase correct PWM with ICR1 as the top, no prescaler:
// 16 MHz / (2 x 320) = 25 kHz.
TCCR1A = _BV(COM1A1) | _BV(WGM11);
TCCR1B = _BV(WGM13) | _BV(CS10);
ICR1 = 320;
OCR1A = 160; // half of 320: a 50 percent duty
}
void loop() {
}Do not speed up timer 0
Timer 0 runs pins 5 and 6 and also millis(), delay() and micros(). Divide it by 1 instead of 64 and pin 6 read 62500 Hz, but the clock runs 64 times too fast with it. The sketch below prints millis() once a second with delay(1000). In one real second it printed 63 lines, ending at 63140.
Use timer 1 or timer 2 for a fast PWM, and leave timer 0 alone.
void setup() {
Serial.begin(9600);
pinMode(6, OUTPUT);
analogWrite(6, 128);
TCCR0B = (TCCR0B & 0b11111000) | 0x01; // do not do this
}
void loop() {
Serial.println(millis());
delay(1000);
}Common mistakes
Expecting analogWrite() to set the frequency. It sets only the duty. 128 is half on, half off, at 490 Hz on pin 9 whatever you write.
Using tone() and PWM on pin 3 or 11 together. tone() takes over timer 2: with tone(8, 440) playing, pin 3’s PWM stopped and the counter read no frequency on it. Pin 9 kept its 490.20 Hz.
Changing timer 0. millis() and delay() run 64 times too fast.
Forgetting that the two pins of a timer change together. Speeding up pin 9 speeds up pin 10 too.
Expecting 255 to be PWM. analogWrite(pin, 255) and analogWrite(pin, 0) just turn the pin fully on or off; 254 and 1 are the last real PWM steps.
Questions
What is the PWM frequency of an Arduino Uno?
About 490 Hz on pins 3, 9, 10 and 11, and about 980 Hz on pins 5 and 6: 490.20 Hz and 976.56 Hz, measured with a frequency counter here.
How do I change the PWM frequency on an Arduino?
Change the prescaler of the timer behind the pin, for example TCCR1B = (TCCR1B & 0b11111000) | 0x01; for 31 kHz on pins 9 and 10. Use timer 1 or 2, never timer 0.
Can Arduino make a 25 kHz PWM signal?
Yes, on pin 9 or 10 with timer 1 in phase correct mode with ICR1 = 320 and no prescaler. It read exactly 25000 Hz here.
Does analogWrite change the frequency?
No. analogWrite() only sets the duty cycle, from 0 to 255. The frequency is set by the timer and stays the same at every duty.
Keep going
Where the facts on this page come from
Build this for real
Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.