Logo

Tutorial: Pulse width modulation

Step 1: Changing Arduino PWM

Title

I mentioned that the PWM frequency could be changed on the Arduino, but I didn't show you how. There is a page on the Arduino Playground that shows the correct usage of the timers on the Arduino that control the PWM outputs.

http://playground.arduino.cc/Main/TimerPWMCheatsheet

I will also copy the tables here to explain:

 

Pins 5 and 6: controlled by Timer 0

Setting 	Divisor 	Frequency
0x01 	 	1 	 	62500
0x02  		8 	 	7812.5
0x03  		64 	 	976.5625
0x04 	 	256 	 	244.140625
0x05 	 	1024 	 	61.03515625

TCCR0B = TCCR0B & 0b11111000 | ;

Pins 9 and 10: controlled by timer 1

Setting 	Divisor 	Frequency
0x01 	 	1 	 	31250
0x02 	 	8 	 	3906.25
0x03  		64 	 	488.28125
0x04  		256 	 	122.0703125
0x05 	 	1024 	 	30.517578125

TCCR1B = TCCR1B & 0b11111000 | ;

Pins 11 and 3: controlled by timer 2

Setting 	Divisor 	Frequency
0x01 	 	1  		31250
0x02 	 	8 	 	3906.25
0x03  		32  		976.5625
0x04 	 	64 	 	488.28125
0x05 	 	128  		244.140625
0x06  		256  		122.0703125
0x07 	 	1024  		30.517578125

TCCR2B = TCCR2B & 0b11111000 | ;

All frequencies are in Hz and assume a 16000000 Hz system clock.

 

So you can see the possible frequencies available to use and on what pins. Notice that each set of pins has different frequencies available and each set is also controlled by a different Arduino system timer. There are 3 timers that run based on the main 16MHz oscillator chip - you can change the scaler value to make each one run at a different speed. You should be careful though when changing the timer on system timer 0 which controls the PWM on pins 5 and 6, because it is also what the Arduino depends on to calculate several core functions like delay(), millis(), micros(), pulseIn(), and might mess with other things like interrupts.

As far as I can tell, you can change the PWM frequency on timers 1 and 2 all day long and it doesn't seem to mess with anything else - so I usually stick to pins 3, 9, 10, and 11 if I need to change the frequency for some reason. Pins 5 and 6 can just stay at 1000Hz to keep everyone happy.

In order to change the frequency, you need to put the correct code in the correct place.

For example, if you wanted to change the frequency of the PWM on pins 3 and 11 to run at 32kHz, you would place the following line in your setup() function:

void setup(){
  TCCR2B = TCCR2B & 0b11111000 | 0x01;
}

 

The TCCR2B means that it is changing timer 2 for pins 3 and 11, not sure what the 8bit code does, but then you add the pipe character and the setting for the speed you want to use. If you refer back to the last table I pasted above, you will notice that for a frequency of 31250 Hz you must use a divisor of 1 which requires the setting "0x01".  I often use this setting on these pins, because 32kHz is above the audible frequency range for humans, so you can operate your motors at this frequency without any whining noises. You might recall me saying that pins 3 and 11 have a default PWM frequency of 500 Hz - well it is actually 488 Hz and according to the chart is a divisor of 64 and uses the setting "0x04". You can also change multiple timers in the setup() function without problems.

 

Back