user87286: I am trying to change the frequency of the PWM output from an Arduino Uno R3 (Been using Pin 9) to 200 Hz with a duty cycle of 20%. This is for an ESC that is connected to a 12V motor, and I know the ESC works as if I input a 200 HZ wave from a waveform generator the motor runs. However, I have been finding it difficult to do the same thing with an Arduino Uno and I believe it is due to the frequency being a default of 490 Hz, so I need a way to change that frequency to 200 Hz. Are there any libraries or specific ways to do so?
Thanks!

user10794: If you are prepared to use Timer 2 (Pin D3) this code will do it:
void setup() 
 {
  pinMode (3, OUTPUT);

  TCCR2A = bit (WGM20) | bit (WGM21) | bit (COM2B1); // fast PWM, clear OC2B on compare
  TCCR2B = bit (WGM22) | bit (CS20) | bit (CS21) | bit (CS22); // prescaler of 1024
  OCR2A =  77;    // zero relative  
  OCR2B =  15;    // 20% duty cycle
  }  // end of setup

void loop()
  {
  // do other stuff here
  }

More information on the Atmega328P timers on my page about timers.
The figure 77 is obtained from:
16000000 / 1024 / 78 = 200.32

In other words, the prescaler of 1024 is divided into the clock of 16 MHz, and then we count up to 78, giving a result of just over 200. I actually use 77 because the timer is zero-relative (it counts from 0 to 77, giving 78 counts). This means the frequency is slightly out (it will be 200.32 Hz rather than 200 but that could be close enough).

You could also do it with Timer 1 (pin D10) to get slightly more accurate results, like this:
void setup() 
 {
  pinMode (10, OUTPUT);

  // mode 15
  TCCR1A = bit (WGM10) | bit (WGM11) | bit (COM1B1); // fast PWM, clear OC1B on compare
  TCCR1B = bit (WGM12) | bit (WGM13) | bit (CS11);   // fast PWM, prescaler of 8
  OCR1A = 10000 - 1;   // what to count to
  OCR1B = 2000 - 1;    // duty cycle
  }  // end of setup

void loop()
  {
  // do other stuff here
  }

In this case I have used a prescaler of 8 and a count-up value of 10000, as follows:
16000000 / 8 / 10000 = 200

In this case the answer is exactly 200, which will be more accurate than the 200.32 obtained from using Timer 2. That is because Timer 1 is a 16-bit timer and has higher resolution.

user70436: You can also use my newly-created AVR_PWM library to shield you from dealing with complex hardware registers
For example
#include "AVR_PWM.h"

#if ( PWM_USING_ATMEGA2560 )
  // Pins tested OK in Mega
  //#define pinToUse      12            // Timer1B on Mega
  //#define pinToUse      11            // Timer1A on Mega
  //#define pinToUse       9            // Timer2B on Mega
  //#define pinToUse       2            // Timer3B on Mega
  //#define pinToUse       3            // Timer3C on Mega
  //#define pinToUse       5            // Timer3A on Mega
  //#define pinToUse       6            // Timer4A on Mega
  //#define pinToUse       7            // Timer4B on Mega
  #define pinToUse       8            // Timer4C on Mega
  //#define pinToUse      46            // Timer5A on Mega
  //#define pinToUse      45            // Timer5B on Mega
  //#define pinToUse      44            // Timer5C on Mega

#elif ( PWM_USING_ATMEGA_32U4  )
  // Pins tested OK on 32u4
  //#define pinToUse      5            // Timer3A on 32u4
  #define pinToUse      9            // Timer1A on 32u4
  //#define pinToUse      10            // Timer1B on 32u4

#else

  // Pins tested OK on Nano / UNO
  #define pinToUse      9            // Timer1A on UNO, Nano, etc
  //#define pinToUse     10            // Timer1B on UNO, Nano, etc
  //#define pinToUse      5               // Timer0B on UNO, Nano, e
  //#define pinToUse       3            // Timer2B on UNO, Nano, etc
#endif

//creates pwm instance
AVR_PWM* PWM_Instance;

float frequency;
float dutyCycle;

void setup()
{
  Serial.print(F("\nStarting PWM_Basic on "));
  Serial.println(BOARD_NAME);
  Serial.println(AVR_PWM_VERSION);

  //assigns PWM frequency of 200 Hz and a duty cycle of 0%
  PWM_Instance = new AVR_PWM(pinToUse, 200, 0);
}

void loop()
{
  frequency = 200;
  dutyCycle = 20;

  PWM_Instance->setPWM(pinToUse, frequency, dutyCycle);

  delay(10000);
  dutyCycle = 90;

  PWM_Instance->setPWM(pinToUse, frequency, dutyCycle);

  delay(10000);
}


87286: <p>I am trying to change the frequency of the PWM output from an Arduino Uno R3 (Been using Pin 9) to 200 Hz with a duty cycle of 20%. This is for an ESC that is connected to a 12V motor, and I know the ESC works as if I input a 200 HZ wave from a waveform generator the motor runs. However, I have been finding it difficult to do the same thing with an Arduino Uno and I believe it is due to the frequency being a default of 490 Hz, so I need a way to change that frequency to 200 Hz. Are there any libraries or specific ways to do so?</p>
<p>Thanks!</p>
 10794: <p>If you are prepared to use Timer 2 (Pin D3) this code will do it:</p>
<pre><code>void setup() 
 {
  pinMode (3, OUTPUT);

  TCCR2A = bit (WGM20) | bit (WGM21) | bit (COM2B1); // fast PWM, clear OC2B on compare
  TCCR2B = bit (WGM22) | bit (CS20) | bit (CS21) | bit (CS22); // prescaler of 1024
  OCR2A =  77;    // zero relative  
  OCR2B =  15;    // 20% duty cycle
  }  // end of setup

void loop()
  {
  // do other stuff here
  }
</code></pre>
<p>More information on the Atmega328P timers on <a href="http://gammon.com.au/timers" rel="nofollow noreferrer">my page about timers</a>.</p>
<p>The figure 77 is obtained from:</p>
<pre><code>16000000 / 1024 / 78 = 200.32
</code></pre>
<p>In other words, the prescaler of 1024 is divided into the clock of 16 MHz, and then we count up to 78, giving a result of just over 200. I actually use 77 because the timer is zero-relative (it counts from 0 to 77, giving 78 counts). This means the frequency is slightly out (it will be 200.32 Hz rather than 200 but that could be close enough).</p>
<hr />
<p>You could also do it with Timer 1 (pin D10) to get slightly more accurate results, like this:</p>
<pre><code>void setup() 
 {
  pinMode (10, OUTPUT);

  // mode 15
  TCCR1A = bit (WGM10) | bit (WGM11) | bit (COM1B1); // fast PWM, clear OC1B on compare
  TCCR1B = bit (WGM12) | bit (WGM13) | bit (CS11);   // fast PWM, prescaler of 8
  OCR1A = 10000 - 1;   // what to count to
  OCR1B = 2000 - 1;    // duty cycle
  }  // end of setup

void loop()
  {
  // do other stuff here
  }
</code></pre>
<p>In this case I have used a prescaler of 8 and a count-up value of 10000, as follows:</p>
<pre><code>16000000 / 8 / 10000 = 200
</code></pre>
<p>In this case the answer is exactly 200, which will be more accurate than the 200.32 obtained from using Timer 2. That is because Timer 1 is a 16-bit timer and has higher resolution.</p>
 70436: <p>You can also use my newly-created <a href="https://github.com/khoih-prog/AVR_PWM" rel="nofollow noreferrer"><strong>AVR_PWM</strong></a> library to shield you from dealing with complex hardware registers</p>
<p>For example</p>
<pre class="lang-cpp prettyprint-override"><code>#include &quot;AVR_PWM.h&quot;

#if ( PWM_USING_ATMEGA2560 )
  // Pins tested OK in Mega
  //#define pinToUse      12            // Timer1B on Mega
  //#define pinToUse      11            // Timer1A on Mega
  //#define pinToUse       9            // Timer2B on Mega
  //#define pinToUse       2            // Timer3B on Mega
  //#define pinToUse       3            // Timer3C on Mega
  //#define pinToUse       5            // Timer3A on Mega
  //#define pinToUse       6            // Timer4A on Mega
  //#define pinToUse       7            // Timer4B on Mega
  #define pinToUse       8            // Timer4C on Mega
  //#define pinToUse      46            // Timer5A on Mega
  //#define pinToUse      45            // Timer5B on Mega
  //#define pinToUse      44            // Timer5C on Mega

#elif ( PWM_USING_ATMEGA_32U4  )
  // Pins tested OK on 32u4
  //#define pinToUse      5            // Timer3A on 32u4
  #define pinToUse      9            // Timer1A on 32u4
  //#define pinToUse      10            // Timer1B on 32u4

#else

  // Pins tested OK on Nano / UNO
  #define pinToUse      9            // Timer1A on UNO, Nano, etc
  //#define pinToUse     10            // Timer1B on UNO, Nano, etc
  //#define pinToUse      5               // Timer0B on UNO, Nano, e
  //#define pinToUse       3            // Timer2B on UNO, Nano, etc
#endif

//creates pwm instance
AVR_PWM* PWM_Instance;

float frequency;
float dutyCycle;

void setup()
{
  Serial.print(F(&quot;\nStarting PWM_Basic on &quot;));
  Serial.println(BOARD_NAME);
  Serial.println(AVR_PWM_VERSION);

  //assigns PWM frequency of 200 Hz and a duty cycle of 0%
  PWM_Instance = new AVR_PWM(pinToUse, 200, 0);
}

void loop()
{
  frequency = 200;
  dutyCycle = 20;

  PWM_Instance-&gt;setPWM(pinToUse, frequency, dutyCycle);

  delay(10000);
  dutyCycle = 90;

  PWM_Instance-&gt;setPWM(pinToUse, frequency, dutyCycle);

  delay(10000);
}
</code></pre>
