how to setup the pwm frequency of ATmega16U2

any one have a short Sketch to do it?

The reference library does not indicate any way to control the PWM frequency via Arduino code. It appears to be fixed at 490 Hz (980 Hz for pins 5 and 6 on the UNO). I only see a way to adjust the duty factor with the analogWrite(x,n) function. See analogWrite() - Arduino Reference for details.

Could you accomplish your goal using the tone function? It allows you to change frequency?
(Duty factor fixed at 50%)
See : tone() - Arduino Reference

What core are you using for the 16u2? I didn't realize there was an Arduino core for the 16u2, despite that many arduino boards use it programmed to act as a USB<->Serial bridge.

But as with most Arduino boards, to change the PWM frequency, you have to take over one of the timers and manually set the prescaler (and maybe TOP value) - see the datasheet section on the timers, and know that timer0 is generally used for millis() (but check the docs for your core)

Hmm. Found this! Might be useful!

I found this:

https://playground.arduino.cc/Code/PwmFrequency

can setup the PWM frequency by a divisor, and the note that this function will have side effects on anything else that uses timers.

My question is can the board recover from this change if I used it for another program?
Thanks

I mean I want to load this sketch into my Arduino uno for test, and I will use my uno for another sketch after, if it's ok?

Yes.

Thank you MorganS。

Is it possible to make the code available for Arduino UNO?

void setPwmFrequency(int pin, int divisor) {
byte mode;
if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
switch(divisor) {
case 1: mode = 0x01; break;
case 8: mode = 0x02; break;
case 64: mode = 0x03; break;
case 256: mode = 0x04; break;
case 1024: mode = 0x05; break;
default: return;
}
if(pin == 5 || pin == 6) {
TCCR0B = TCCR0B & 0b11111000 | mode;
} else {
TCCR1B = TCCR1B & 0b11111000 | mode;
}
} else if(pin == 3 || pin == 11) {
switch(divisor) {
case 1: mode = 0x01; break;
case 8: mode = 0x02; break;
case 32: mode = 0x03; break;
case 64: mode = 0x04; break;
case 128: mode = 0x05; break;
case 256: mode = 0x06; break;
case 1024: mode = 0x07; break;
default: return;
}
TCCR2B = TCCR2B & 0b11111000 | mode;
}
}

Hi,
any one can help me to make this code from: Arduino Playground - PwmFrequency

works on arduino uno?

Here are some usage examples of the function: 

// Set pin 9's PWM frequency to 3906 Hz (31250/8 = 3906)
// Note that the base frequency for pins 3, 9, 10, and 11 is 31250 Hz
setPwmFrequency(9, 8);

// Set pin 6's PWM frequency to 62500 Hz (62500/1 = 62500)
// Note that the base frequency for pins 5 and 6 is 62500 Hz
setPwmFrequency(6, 1);

/**
 * Divides a given PWM pin frequency by a divisor.
 * 
 * The resulting frequency is equal to the base frequency divided by
 * the given divisor:
 *   - Base frequencies:
 *      o The base frequency for pins 3, 9, 10, and 11 is 31250 Hz.
 *      o The base frequency for pins 5 and 6 is 62500 Hz.
 *   - Divisors:
 *      o The divisors available on pins 5, 6, 9 and 10 are: 1, 8, 64,
 *        256, and 1024.
 *      o The divisors available on pins 3 and 11 are: 1, 8, 32, 64,
 *        128, 256, and 1024.
 * 
 * PWM frequencies are tied together in pairs of pins. If one in a
 * pair is changed, the other is also changed to match:
 *   - Pins 5 and 6 are paired on timer0
 *   - Pins 9 and 10 are paired on timer1
 *   - Pins 3 and 11 are paired on timer2
 * 
 * Note that this function will have side effects on anything else
 * that uses timers:
 *   - Changes on pins 3, 5, 6, or 11 may cause the delay() and
 *     millis() functions to stop working. Other timing-related
 *     functions may also be affected.
 *   - Changes on pins 9 or 10 will cause the Servo library to function
 *     incorrectly.
 * 
 * Thanks to macegr of the Arduino forums for his documentation of the
 * PWM frequency divisors. His post can be viewed at:
 *   http://forum.arduino.cc/index.php?topic=16612#msg121031
 */
void setPwmFrequency(int pin, int divisor) {
  byte mode;
  if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 64: mode = 0x03; break;
      case 256: mode = 0x04; break;
      case 1024: mode = 0x05; break;
      default: return;
    }
    if(pin == 5 || pin == 6) {
      TCCR0B = TCCR0B & 0b11111000 | mode;
    } else {
      TCCR1B = TCCR1B & 0b11111000 | mode;
    }
  } else if(pin == 3 || pin == 11) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 32: mode = 0x03; break;
      case 64: mode = 0x04; break;
      case 128: mode = 0x05; break;
      case 256: mode = 0x06; break;
      case 1024: mode = 0x07; break;
      default: return;
    }
    TCCR2B = TCCR2B & 0b11111000 | mode;
  }
}

Anyone attempting to answer this is likely to need the function setPwmFrequency defined at

http://playground.arduino.cc/Code/PwmFrequency

Thank you vaj4088.
Sorry that I missed the main code and done supplement.

I followed the thread of PWM frequency library and tested the following code, I really can't feel the LED's brightness change when I changed the frequency from 5 to 20000. I just wonder what I did wrong?
I download [Arduino PWM Frequency Library v_05], unzip and put into Libraries.

#include <PWM.h>

//use pin 11 on the Mega instead, otherwise there is a frequency cap at 31 Hz
int led = 7;                // the pin that the LED is attached to
int brightness = 0;         // how bright the LED is
int fadeAmount = 5;         // how many points to fade the LED by
int32_t frequency = 20000; //frequency (in Hz)

void setup()
{
  //initialize all timers except for 0, to save time keeping functions
  InitTimersSafe(); 

  //sets the frequency for the specified pin
  bool success = SetPinFrequencySafe(led, frequency);
  
  //if the pin frequency was set successfully, pin 13 turn on
  if(success) {
    pinMode(13, OUTPUT);
    digitalWrite(13, HIGH);    
  }
}

void loop()
{
  //use this functions instead of analogWrite on 'initialized' pins
  pwmWrite(led, brightness);

  brightness = brightness + fadeAmount;

  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ; 
  }     
  
  delay(30);      
}

Brightness is not controlled by frequency. Brightness is controlled by duty cycle.

Thank you pert,
can you kindly add some code to make it be able to control the brightness of LED?

Which board are you using?

Pin 7 on e.g. an Uno is not a PWM pin, so that might be one of your problems. It will (probably) work if the library supports software PWM; for you to figure that out as I'm not familiar with the library.

@laoadam, please stop cross-posting. Multiple threads merged.

This appears to be the actual goal...

laoadam:
Thank you pert,
can you kindly add some code to make it be able to control the brightness of LED?

Which board are you using?
This is a critical detail which you seem allergic to posting, because since PWM frequency is not exposed to the user via the Arduino abstractions, you need to use a library or adjust the registers directly. And not all libraries for this support all boards, nor is the code the same for all boards.

You originally asked about the 16u2, which is not used as the main microcontroller in any official boards and which I was unaware of any Arduino support for programming it via the IDE - the only boards that use it use it as a usb-serial adapter for another microcontroller. Which led to my earlier questions (which you never answered).

Of course, if you just want to change the brightness of an LED connected to a PWM pin, you don't need to change the frequency, just the duty cycle - for that you can just use analogWrite() - though it's unclear whether there's some other reason you also need to change the frequency.

DrAzzy:
I was unaware of any Arduino support for programming it via the IDE

I only know of one 3rd party hardware package for it:

But I agree that laoadam needs to take a minute to provide the information needed to help them. If they had used their time to do that instead of cross posting, likely this would have been resolved days ago

If the pulse duration is held constant somehow, then changing the frequency would change the duty cycle. PWM would then be the wrong name for what is happening.

I am using Arduino UNO, I need to setup PWM frequency as 15K.

My question is if I use such as "analogWrite(ledPin, val / 4)" to control the motor speed, will the PWM frequenct keep same as set or change back the original。

If I understand from the previous thread, PWM.h is part of some library. Is that correct? If so, post a link to where you downloaded it from. Please use the chain links icon on the toolbar to make the link clickable.

Previous thread:
http://forum.arduino.cc/index.php?topic=588402