# What are the possible PWM frequencies? And how to set them.

**URL:** <https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098>\
**Category:** Due\
**Created:** [July 25, 2014, 11:52am UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098 "2014-07-25T11:52:48Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jantje](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/jantje/32/213734_2.png) [@Jantje](https://forum.arduino.cc/u/Jantje)\
**Post date:** [July 25, 2014, 11:52am UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/1 "2014-07-25T11:52:48Z")

</div>

I have been looking for a simple answer on my simple question: "What are the possible PWM frequencies on DUE?"; but I start to fear there is no simple answer.  
The datasheet contains some PWM calculation formula's but my current knowledge is insufficient to even make out I'm looking at the right spot.  
The playground contains a PWM cheat sheet [Arduino Playground - HomePage](http://playground.arduino.cc/Main/TimerPWMCheatsheet) unfortunately there is no due section.

I'm considering to move my project from a mega to a due. As 500Hz is to slow for me I'm looking for a simple table like the one below of the cheat sheet. (I expect 2 due to millis() and timer 0)

> Pins 5 and 6: controlled by Timer 0 in fast PWM mode (cycle length = 256)
> 
> Setting Divisor Frequency  
> 0x01 1 62500  
> 0x02 8 7812.5  
> 0x03 64 976.5625 \<--DEFAULT  
> 0x04 256 244.140625  
> 0x05 1024 61.03515625

Is this info available somewhere?

Best regards  
Jantje

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [July 31, 2014, 1:55pm UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/2 "2014-07-31T13:55:28Z")

</div>

Bump up to the top!

Sorry, no answer but looking into some very similar things myself too, and examples or pointing in the right direction would save some time!

---

<div class="post-metadata">

**Author:** ![pbrouwer](https://avatars.discourse-cdn.com/v4/letter/p/dbc845/32.png) [@pbrouwer](https://forum.arduino.cc/u/pbrouwer)\
**Post date:** [July 31, 2014, 2:12pm UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/3 "2014-07-31T14:12:05Z")

</div>

The default frequency is 1000 Hz, I beleive.

See this thread for more info on changing frequency:

[http://forum.arduino.cc/index.php/topic,131323.0.html](http://forum.arduino.cc/index.php/topic,131323.0.html)

---

<div class="post-metadata">

**Author:** ![Jantje](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/jantje/32/213734_2.png) [@Jantje](https://forum.arduino.cc/u/Jantje)\
**Post date:** [July 31, 2014, 3:00pm UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/4 "2014-07-31T15:00:08Z")

</div>

@pbrouwer  
I had read the thread. Didn't find the info I needed.  
I reread the thread. I still don't understand it enough to find out what frequencies are possible on which pin and how to do it.

Best regards  
Jantje

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [July 31, 2014, 3:10pm UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/5 "2014-07-31T15:10:33Z")

</div>

Looks like some useful information here too:

[http://forum.arduino.cc/index.php?topic=131323.15](http://forum.arduino.cc/index.php?topic=131323.15)

Default of 1000Hz would make sense as I saw that on my multi meter when I was checking the output voltage from the motor shield.

---

<div class="post-metadata">

**Author:** ![pbrouwer](https://avatars.discourse-cdn.com/v4/letter/p/dbc845/32.png) [@pbrouwer](https://forum.arduino.cc/u/pbrouwer)\
**Post date:** [July 31, 2014, 4:15pm UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/6 "2014-07-31T16:15:50Z")

</div>

From what i understand of the controllers datasheet, PWM on the due is pretty configurable, much more so than the chip used on the uno or mega.  
The chip can have different frequencies for different pins, and because of the variable dividers, available frequencies are only limited by the master clock (they cannot be higher than that). So you should be able to set pretty much any frequency, or at least one very close the the one you like.

This thread has a library that can set two desired frequencies:

[http://forum.arduino.cc/index.php/topic,146947.msg1115263.html#msg1115263](http://forum.arduino.cc/index.php/topic,146947.msg1115263.html#msg1115263)

Another option (may not be the best option), is to modify variants.h for the DUE and set the pwm frequency to another value.

---

<div class="post-metadata">

**Author:** ![MarkT](https://avatars.discourse-cdn.com/v4/letter/m/c89c15/32.png) [@MarkT](https://forum.arduino.cc/u/MarkT)\
**Post date:** [July 31, 2014, 5:50pm UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/7 "2014-07-31T17:50:52Z")

</div>

What is needed is for one of the developers add a variable to replace the #define  
in variant.h - or better still to add a pwm frequency variable per-pin.

Note that the exact frequency will be close to, but may not be identical to the  
PWM\_FREQUENCY value, since there is only an 8-bit resolution divider in  
the PWM generators

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [August 1, 2014, 7:52am UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/8 "2014-08-01T07:52:09Z")

</div>

Nearly any frequency from microhertz (one cycle per 3 days, or so) to 42 MHz is possible, with millions of options in between, so there's no point in printing a table. Figure out what you want, and then figure out how best to do it 🙂

---

<div class="post-metadata">

**Author:** ![Jantje](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/jantje/32/213734_2.png) [@Jantje](https://forum.arduino.cc/u/Jantje)\
**Post date:** [August 1, 2014, 5:12pm UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/9 "2014-08-01T17:12:22Z")

</div>

> hobbified:  
> Nearly any frequency from microhertz (one cycle per 3 days, or so) to 42 MHz is possible, with millions of options in between,

@hobbified  
This is very interesting information to me (and I guess many others)

So I have now  
Default PWM frequency =1000 Hz (the same for all pwm pins)  
frequency range microhertz (one cycle per 3 days) to 42 MHz  
PWM Pins D2-D13 (as to [Due pinout diagram - Arduino Due - Arduino Forum](http://forum.arduino.cc/index.php?topic=132130.0) also pins D38 to D44

> hobbified:  
> Figure out what you want, and then figure out how best to do it 🙂

This is still missing. I'd like to have a easy way to get from I want this pwm frequency to: "how to do it". That is what I'd like to add to the "cheat sheet" .

This code for maple (not sure how due relates to it) has been linked to a couple of times in this thread [DUE PWM Frequency - Arduino Due - Arduino Forum](http://forum.arduino.cc/index.php?topic=131323.15)  
Supposing I can use code as below to control the PWM frequency for all these pins of the due: (I don't think I can but then I'd like to know the code)

```arduino
    timer.pause();
    timer.setPrescaleFactor(3);
    timer.setOverflow(4000);
    timer.refresh();
    timer.resume();

```

How do I get from my wanted PWM frequency (say 42 MHz as example) to the PrescaleFacor and to the Overflow value?  
And how do I get from my pin number to the timer?

There are 11 (or 18) pwm pins. It can't be that hard to list the resources needed to set the pwm frequency for those pins?

Best regards  
Jantje

---

<div class="post-metadata">

**Author:** ![bobcousins](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/bobcousins/32/221530_2.png) [@bobcousins](https://forum.arduino.cc/u/bobcousins)\
**Post date:** [August 1, 2014, 7:10pm UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/10 "2014-08-01T19:10:40Z")

</div>

> Jantje:  
> There are 11 (or 18) pwm pins. It can't be that hard to list the resources needed to set the pwm frequency for those pins?

It's not too hard, but it's long : it's all in the SAM3X datasheet, 1455 pages. Creating a short summary of all that info is hard though. The datasheet does contain the quote "The large number of source clocks can make selection difficult." 🙂 But often you don't need to worry too much about the details in the datasheet, just use the library functions Atmel provide.

Really, I usually find reading the library source code is the best way to figure out how to do things. For example, to set the PWM clock, just call PWMC\_ConfigureClocks(uint32\_t clka, uint32\_t clkb, uint32\_t mck) and let the function work out what all the registers should be. There is an example in analogWrite, which was referenced in the other thread.

It's complicated slightly because the Arduino library presents pins as "PWM enabled", but under the hood does things differently depending on the hardware.

A 42MHz PWM is probably a little ambitious, for a typical 8 bit PWM, the max freq would be 84MHz/256.

Here is a simple example I just tried for a real PWM pin, to generate 10kHz, 50% duty cycle, using default 8 bit resolution:

```arduino
void setup() {
  // put your setup code here, to run once:

  pinMode (6, OUTPUT);
    
  analogWrite (6, 128);
  // must be called after first analogWrite
  PWMC_ConfigureClocks (256 * 10000, 0, VARIANT_MCK);
}

void loop() {
  // put your main code here, to run repeatedly:

}

```

And here is what you get on the scope:

![](https://europe1.discourse-cdn.com/arduino/original/4X/8/0/3/803ebacde2d4619356648fadd056343f0fb3467b.png)

---

<div class="post-metadata">

**Author:** ![Jantje](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/jantje/32/213734_2.png) [@Jantje](https://forum.arduino.cc/u/Jantje)\
**Post date:** [August 1, 2014, 8:54pm UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/11 "2014-08-01T20:54:42Z")

</div>

I feel I'm getting somewhere. Thanks for that. But I'm not there ... please keep providing input.

**I have now**  
Default PWM frequency =1000 Hz (the same for all pwm pins)  
theoretic frequency range microhertz (one cycle per 3 days) to 42 MHz  
practical frequency range microhertz (one cycle per 3 days) to 328 KHz  
PWM Pins D2-D13 (as to [Due pinout diagram - Arduino Due - Arduino Forum](http://forum.arduino.cc/index.php?topic=132130.0) also pins D38 to D44

The code to set pin 6 to 10kHz, 50% duty cycle is

```plaintext
  analogWrite (6, 128);
  // must be called after first analogWrite
  PWMC_ConfigureClocks (256 * 10000, 0, VARIANT_MCK);

```

**But ....**  
The PWMC\_ConfigureClocks method is defined in [arduino IDE location]/hardware/arduino/sam/system/libsam/include/pwmc.h.  
So it is a amtel delivered method implemented in compiled code (so it is "proprietary code")  
I however fail to find any documentation on PWMC\_ConfigureClocks.  
pwmc.h full documentation on the method is:

```plaintext
 *    -# Configures PWM clocks A & B to run at the given frequencies using
 *      \ref PWMC_ConfigureClocks().

```

The definition is

```plaintext
void PWMC_ConfigureClocks(uint32_t clka, uint32_t clkb, uint32_t mck ) ;

```

I found nothing in pwmc.h that something should be set before calling this method. The arduino code does state you should call analogwrite before the call. So maybe the code is setting the pwm frequency for all pwm pins? Can I call this multiple times with different frequencies? how do I set PWM pin 2 to 10KHz and pin 13 to 44Khz  
Anyone knows a pointer to documentation of PWMC\_ConfigureClocks?

I found no information on amtel nor on arduino reference page on this method.

Best regards  
Jantje

---

<div class="post-metadata">

**Author:** ![randomvibe](https://avatars.discourse-cdn.com/v4/letter/r/ecae2f/32.png) [@randomvibe](https://forum.arduino.cc/u/randomvibe)\
**Post date:** [August 1, 2014, 9:08pm UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/12 "2014-08-01T21:08:38Z")

</div>

This library has worked for me and several others. You can setup up to two unique frequencies on several pins. Just make sure you read the notes. Give it a try. Good luck.

[http://forum.arduino.cc/index.php?topic=144446.msg1149044#msg1149044](http://forum.arduino.cc/index.php?topic=144446.msg1149044#msg1149044)

---

<div class="post-metadata">

**Author:** ![bobcousins](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/bobcousins/32/221530_2.png) [@bobcousins](https://forum.arduino.cc/u/bobcousins)\
**Post date:** [August 2, 2014, 9:48am UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/13 "2014-08-02T09:48:57Z")

</div>

> Jantje:  
> **But ....**  
> The PWMC\_ConfigureClocks method is defined in [arduino IDE location]/hardware/arduino/sam/system/libsam/include/pwmc.h.  
> So it is a amtel delivered method implemented in compiled code (so it is "proprietary code")  
> I however fail to find any documentation on PWMC\_ConfigureClocks.

It's code provided by Atmel as part of their ASF (Atmel Software Framework). It has a BSD style license, so there is no problem to include with open source code. [http://asf.atmel.com/docs/latest/](http://asf.atmel.com/docs/latest/)  
There is no deeper level of documentation than the doxygen comments in the code, apart from example progams. Atmel have the documentation online [http://asf.atmel.com/docs/latest/sam3x/html/group\_\_sam\_\_drivers\_\_pwm\_\_group.html](http://asf.atmel.com/docs/latest/sam3x/html/group __sam__ drivers __pwm__ group.html), but note the Atmel code used by Arduino is now out of date with respect to the latest ASF.

> pwmc.h full documentation on the method is:
> 
> ```arduino
> *    -# Configures PWM clocks A & B to run at the given frequencies using
> 
> ```

\*&nbsp; &nbsp; &nbsp; &nbsp;\ref PWMC\_ConfigureClocks().

> ```arduino
> 
> The definition is
> 
> ```
> 
> void PWMC\_ConfigureClocks(uint32\_t clka, uint32\_t clkb, uint32\_t mck ) ;
> 
> ```arduino
> 
> I found nothing in pwmc.h that something should be set before calling this method. The arduino code does state you should call analogwrite before the call.
> 
> ```

The great thing about software is that a complete specification for what the software does is the software itself 🙂 The compiler must be able to compile without reference to further documentation. It really is an essential skill for anyone writing code to be able to read code as well.

If you are not sure what the registers and values mean, then reading the SAM3X datasheet is a complete and accurate specification. There is no point me copying and pasting the SAM3X datasheet, you can read it for yourself!

In this case, it is obvious from reading the code that analogWrite calls PWMC\_ConfigureClocks the first time it is called, which would overwrite any previous initialisation. I wouldn't expect that to be documented anywhere, it's just simple programming logic.

> So maybe the code is setting the pwm frequency for all pwm pins? Can I call this multiple times with different frequencies?

Each channel can select from a number of clock sources, the way Arduino sets up is to use the same source for all channels (clka). PWMC\_ConfigureClocks() can set clka and clkb, so that gives you two programmable clock sources. The other clock sources are divisors of the main clock, as described in the SAM3X datasheet (p1058)

> CPRE: Channel Pre-scaler  
> Value Name Description  
> 0b0000 MCK Master clock  
> 0b0001 MCK\_DIV\_2 Master clock/2  
> 0b0010 MCK\_DIV\_4 Master clock/4  
> 0b0011 MCK\_DIV\_8 Master clock/8  
> 0b0100 MCK\_DIV\_16 Master clock/16  
> 0b0101 MCK\_DIV\_32 Master clock/32  
> 0b0110 MCK\_DIV\_64 Master clock/64  
> 0b0111 MCK\_DIV\_128 Master clock/128  
> 0b1000 MCK\_DIV\_256 Master clock/256  
> 0b1001 MCK\_DIV\_512 Master clock/512  
> 0b1010 MCK\_DIV\_1024 Master clock/1024  
> 0b1011 CLKA Clock A  
> 0b1100 CLKB Clock B

> Anyone knows a pointer to documentation of PWMC\_ConfigureClocks?

You have already found it!

> how do I set PWM pin 2 to 10KHz and pin 13 to 44Khz

So far I have been describing the hardware PWM channels, and these are available on pins 6,7,8,9. There are other hwPWM channels, but they are not mapped in Arduino. You would either need to change variant.cpp, or copy the PWM code from analogWrite.

If you look at the Due pinout diagram, if the SAM pin name is "PWMxx" then it's a hardware PWM channel. There are 8 channels, each with a "high" and "low" output. Therefore there are PWML0, PWMH0, etc up to PWML7, PWMH7. Each channel can have a different clock source, which will affect both high and low outputs.

The other pins marked "PWM" in the Due pinout i.e. 2-5 and 9-13, are implemented using timer channels. The timer channels are also capable of producing PWM waveforms, without some of the more advanced PWM features, but can produce more accurate timing.

I will have a look at those and put an example in another post.

---

<div class="post-metadata">

**Author:** ![bobcousins](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/bobcousins/32/221530_2.png) [@bobcousins](https://forum.arduino.cc/u/bobcousins)\
**Post date:** [August 2, 2014, 10:31am UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/14 "2014-08-02T10:31:11Z")

</div>

Here is a demo sketch:

```plaintext
// --------------------------------------------
//
// Hardware PWM with different frequencies demo
//
// Bob Cousins, August 2014
// --------------------------------------------

void setup() {
  // put your setup code here, to run once:

  pinMode (6, OUTPUT); // PWML7
  pinMode (7, OUTPUT); // PWML6
  pinMode (8, OUTPUT); // PWML5
    
  // call analogWrite first to allow Arduino to initialise  
  analogWrite (6, 128);
  analogWrite (7, 128);
  analogWrite (8, 128);
  
  // set clka to 10KHz, clkb to 5kHz
  PWMC_ConfigureClocks (255 * 10000, 255 * 5000, VARIANT_MCK);
  
  // set channel 6 to use clkb
  PWMC_ConfigureChannel (PWM, 6, PWM_CMR_CPRE_CLKB, 0, 0);
  // Note: need to re-enable channel after doing Configure
  PWMC_EnableChannel (PWM, 6);
  
  // set channel 5 to use MCK/16 (actual freq = 84MHz/255/16 = 20588 Hz)
  PWMC_ConfigureChannel (PWM, 5, PWM_CMR_CPRE_MCK_DIV_16, 0, 0);
  PWMC_EnableChannel (PWM, 5);
}

void loop() {
  // put your main code here, to run repeatedly:

}

```

And scope trace

[![](https://europe1.discourse-cdn.com/arduino/original/4X/f/b/e/fbe1a447dec55263abffbb82706f2778ae237cd4.png)](https://flic.kr/p/oh4DUQ)[demo\_pwm](https://flic.kr/p/oh4DUQ) by [donotdespisethesnake](https://www.flickr.com/people//), on Flickr

---

<div class="post-metadata">

**Author:** ![bobcousins](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/bobcousins/32/221530_2.png) [@bobcousins](https://forum.arduino.cc/u/bobcousins)\
**Post date:** [August 2, 2014, 6:23pm UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/15 "2014-08-02T18:23:49Z")

</div>

As promised here is a sketch using timers for PWM, with different frequencies. You can have 4 different frequencies, because there are 4 timer channels used. Each timer channel can have two outputs, A and B, each with their own duty cycles.

There are a total of 9 timer channels, so in theory you could have 9 different frequencies, but not all the output pins may be mapped in convenient locations, or at all. You would also need to do all the setup code yourself, as they are not handled by analogWrite, or possibly edit variant.cpp.

```plaintext
// --------------------------------------------
//
// PWM with timers demo
//
// Bob Cousins, August 2014
// --------------------------------------------

typedef struct {
    Tc *pTC; // TC0, TC1, or TC2
    byte channel; // 0-2
    byte output; // 0 = A, 1 = B
} tTimerInfo;

tTimerInfo timerLookup [] =
{
  {NULL,0,0}, // 0
  {NULL,0,0},
  {TC0,0,0}, // pin 2 = TIOA0
  {TC2,1,0}, // pin 3 = TIOA7
  {TC2,0,1}, // pin 4 = TIOB6
  {TC2,0,0}, // pin 5 = TIOA6
  {NULL,0,0},
  {NULL,0,0},
  {NULL,0,0},
  {NULL,0,0},
  {TC2,1,1}, // pin 10 = TIOB7
  {TC2,2,0}, // pin 11 = TIOA8
  {TC2,2,1}, // pin 12 = TIOB8
  {TC0,0,1} // pin 13 = TIOB0
};

/**
 * \brief set a pin for PWM using a timer channel
 * \param pin pin to use (0-13 only!)
 * \param frequency the frequency
 * \param dutyCyle duty cycle 0-255
 * \return this function returns a count, which is the effective PWM resolution. Returns 0 if pin is not valid
 */

uint32_t setupTimerPwm (byte pin, uint32_t frequency, unsigned dutyCycle)
{
  uint32_t count = VARIANT_MCK/2/frequency;
  tTimerInfo *pTimer = &timerLookup[pin];
  
  if (pTimer != NULL)
  {
    TC_SetRC (pTimer->pTC, pTimer->channel, count);
    if (pTimer->output == 0)
       TC_SetRA (pTimer->pTC, pTimer->channel, count * dutyCycle / 256);
    else
       TC_SetRB (pTimer->pTC, pTimer->channel, count * dutyCycle / 256);
  
    return count;
  }
  else
    return 0;
}

void setup() {
  // put your setup code here, to run once:

  // use the Arduino lib to do initial setup
  analogWrite (2, 128);
  analogWrite (13, 128);
  
  analogWrite (5, 128);
  analogWrite (4, 128);

  analogWrite (3, 128);
  analogWrite (10, 128);

  analogWrite (11, 128);
  analogWrite (12, 128);
 
  // pins 2 and 3 share the same timer so must have same frequency
  setupTimerPwm (2, 2000, 128); 
  setupTimerPwm (13, 2000, 64); 
  
  // pins 5 and 4 share the same timer
  setupTimerPwm (5, 3000, 128); 
  setupTimerPwm (4, 3000, 64); 

  // pins 3 and 10 share the same timer
  setupTimerPwm (3, 4000, 128); 
  setupTimerPwm (10, 4000, 64); 

  // pins 11 and 12 share the same timer
  setupTimerPwm (11, 5000, 128); 
  setupTimerPwm (12, 5000, 64); 

}

void loop() {
  // put your main code here, to run repeatedly:

}

```

Scope traces, showing pins 2, 5, 3 and 11 respectively (these are the 'A' outputs) :

[![](https://europe1.discourse-cdn.com/arduino/original/4X/4/9/6/496865c3b7f095b92e758f949f2a736f7bd21036.png)](https://flic.kr/p/owM6rm)[demo2](https://flic.kr/p/owM6rm) by [donotdespisethesnake](https://www.flickr.com/people//), on Flickr

If you find the advice "read the source code" offensive, I'm sorry, but please don't send me PMs to complain. It really is Good Advice [Learn to Read the Source, Luke!](http://blog.codinghorror.com/learn-to-read-the-source-luke/). If you don't want to read source code, consider a different hobby/profession!

And if you are using Arduino, you already have it's source code on your computer, so don't say you don't have it. It is really worth studying if you want to learn how it works.

---

<div class="post-metadata">

**Author:** ![iyahdub](https://avatars.discourse-cdn.com/v4/letter/i/d2c977/32.png) [@iyahdub](https://forum.arduino.cc/u/iyahdub)\
**Post date:** [August 4, 2014, 8:11pm UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/16 "2014-08-04T20:11:58Z")

</div>

Highly instructive 🙂

---

<div class="post-metadata">

**Author:** ![Punthoofd07](https://avatars.discourse-cdn.com/v4/letter/p/b3f665/32.png) [@Punthoofd07](https://forum.arduino.cc/u/Punthoofd07)\
**Post date:** [September 4, 2015, 2:57pm UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/17 "2015-09-04T14:57:50Z")

</div>

> bobcousins:  
> As promised here is a sketch using timers for PWM, with different frequencies. You can have 4 different frequencies, because there are 4 timer channels used. Each timer channel can have two outputs, A and B, each with their own duty cycles.
> 
> There are a total of 9 timer channels, so in theory you could have 9 different frequencies, but not all the output pins may be mapped in convenient locations, or at all. You would also need to do all the setup code yourself, as they are not handled by analogWrite, or possibly edit variant.cpp.
> 
> ```arduino
> // --------------------------------------------
> 
> ```

//  
// PWM with timers demo  
//  
// Bob Cousins, August 2014  
// --------------------------------------------

typedef struct {  
&nbsp; &nbsp; Tc \*pTC;&nbsp; &nbsp; &nbsp; &nbsp; // TC0, TC1, or TC2  
&nbsp; &nbsp; byte channel;&nbsp; // 0-2  
&nbsp; &nbsp; byte output;&nbsp; &nbsp; // 0 = A, 1 = B  
}&nbsp; tTimerInfo;

tTimerInfo timerLookup [] =  
{  
&nbsp; {NULL,0,0}, // 0  
&nbsp; {NULL,0,0},  
&nbsp; {TC0,0,0},&nbsp; // pin 2 = TIOA0  
&nbsp; {TC2,1,0},&nbsp; // pin 3 = TIOA7  
&nbsp; {TC2,0,1},&nbsp; // pin 4 = TIOB6  
&nbsp; {TC2,0,0},&nbsp; // pin 5 = TIOA6  
&nbsp; {NULL,0,0},  
&nbsp; {NULL,0,0},  
&nbsp; {NULL,0,0},  
&nbsp; {NULL,0,0},  
&nbsp; {TC2,1,1},&nbsp; // pin 10 = TIOB7  
&nbsp; {TC2,2,0},&nbsp; // pin 11 = TIOA8  
&nbsp; {TC2,2,1},&nbsp; // pin 12 = TIOB8  
&nbsp; {TC0,0,1}&nbsp; // pin 13 = TIOB0  
};

/\*\*

- \brief set a pin for PWM using a timer channel
- \param pin&nbsp; &nbsp; &nbsp; pin to use (0-13 only!)
- \param frequency the frequency
- \param dutyCyle&nbsp; duty cycle 0-255
- \return&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this function returns a count, which is the effective PWM resolution. Returns 0 if pin is not valid  
\*/

uint32\_t setupTimerPwm (byte pin, uint32\_t frequency, unsigned dutyCycle)  
{  
&nbsp; uint32\_t count = VARIANT\_MCK/2/frequency;  
&nbsp; tTimerInfo \*pTimer = &timerLookup[pin];  
&nbsp;  
&nbsp; if (pTimer != NULL)  
&nbsp; {  
&nbsp; &nbsp; TC\_SetRC (pTimer-\>pTC, pTimer-\>channel, count);  
&nbsp; &nbsp; if (pTimer-\>output == 0)  
&nbsp; &nbsp; &nbsp; TC\_SetRA (pTimer-\>pTC, pTimer-\>channel, count \* dutyCycle / 256);  
&nbsp; &nbsp; else  
&nbsp; &nbsp; &nbsp; TC\_SetRB (pTimer-\>pTC, pTimer-\>channel, count \* dutyCycle / 256);  
&nbsp;  
&nbsp; &nbsp; return count;  
&nbsp; }  
&nbsp; else  
&nbsp; &nbsp; return 0;  
}

void setup() {  
&nbsp; // put your setup code here, to run once:

// use the Arduino lib to do initial setup  
&nbsp; analogWrite (2, 128);  
&nbsp; analogWrite (13, 128);  
&nbsp;  
&nbsp; analogWrite (5, 128);  
&nbsp; analogWrite (4, 128);

analogWrite (3, 128);  
&nbsp; analogWrite (10, 128);

analogWrite (11, 128);  
&nbsp; analogWrite (12, 128);

// pins 2 and 3 share the same timer so must have same frequency  
&nbsp; setupTimerPwm (2, 2000, 128);  
&nbsp; setupTimerPwm (13, 2000, 64);  
&nbsp;  
&nbsp; // pins 5 and 4 share the same timer  
&nbsp; setupTimerPwm (5, 3000, 128);  
&nbsp; setupTimerPwm (4, 3000, 64);

// pins 3 and 10 share the same timer  
&nbsp; setupTimerPwm (3, 4000, 128);  
&nbsp; setupTimerPwm (10, 4000, 64);

// pins 11 and 12 share the same timer  
&nbsp; setupTimerPwm (11, 5000, 128);  
&nbsp; setupTimerPwm (12, 5000, 64);

}

void loop() {  
&nbsp; // put your main code here, to run repeatedly:

}

> ```arduino
> 
> Scope traces, showing pins 2, 5, 3 and 11 respectively (these are the 'A' outputs) :
> 
> [![](https://farm4.staticflickr.com/3880/14788142106_55111f50f7_o.png)](https://flic.kr/p/owM6rm)[demo2](https://flic.kr/p/owM6rm) by [donotdespisethesnake](https://www.flickr.com/people//), on Flickr
> 
> If you find the advice "read the source code" offensive, I'm sorry, but please don't send me PMs to complain. It really is Good Advice [Learn to Read the Source, Luke!](http://blog.codinghorror.com/learn-to-read-the-source-luke/). If you don't want to read source code, consider a different hobby/profession!
> 
> And if you are using Arduino, you already have it's source code on your computer, so don't say you don't have it. It is really worth studying if you want to learn how it works.
> 
> ```

Especially made an account to thank you! 🙂

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [May 6, 2021, 5:38pm UTC](https://forum.arduino.cc/t/what-are-the-possible-pwm-frequencies-and-how-to-set-them/248098/18 "2021-05-06T17:38:45Z")

</div>

Closed on May 6, 2021, 5:38pm UTC


