No announcement yet.

Change / Adjust PWM frequency

  • Filter
  • Time
  • Show
Clear All
new posts

  • Change / Adjust PWM frequency


    I didn't think I'd be the first to ask, but I'm not finding the topic here - my apologies if this has been covered already...

    I'm looking to change the PWM frequency. I'm running on a Mega2560, and it seems all pins that can be assigned to PWM run about 60Hz.

    From what I gather reading other sources, the defaults are usually higher, depending on the pin and the associated arduino timer.

    I was reverse engineering the IDE and see that it calls SoftPWM.h - which I think sets the timers prescalers via SoftPWM_timer.h ... however, it looks to me like that would still be a higher frequency than 60Hz.

    Any guidance is greatly appreciated!

    I was referring to this author's post on the Arduino forum:

    1) Arduino 2560 has 12 pins supporting PWM. They are from 2 to 13 included.
    2) the PWM default frequency is 490 Hz for all pins, with the exception of pin 13 and 4,
    whose frequency is 980 Hz (I checked with an oscilloscope).
    3) In order to change frequency on pin 'A', we have to change some value in the timer 
    (or register), controlling pin 'A'. This is the list of timers in Arduino Mega 2560:
    timer 0 (controls pin 13, 4);
    timer 1 (controls pin 12, 11);
    timer 2 (controls pin 10, 9);
    timer 3 (controls pin 5, 3, 2);
    timer 4 (controls pin 8, 7, 6);
    As you can see, a given timer controls more than one pin (every change about a timer will affect all pins depending on it!).
    4) You can access a timer simply changing in your code (tipically in the setup()), the value of variable TCCRnB, where 'n' is the number of register. So, if we want  to change the PWM frequency of pins 10 and 9,  we will have to act on TCCR2B .
    5) The TCCRnB is a 8 bit number.  The first three bits (from right to left!) are called CS02, CS01, CS00, and they are the bits we have to change.
    Those bits in fact represent an integer number (from 0 to 7) called 'prescaler' , that Arduino uses to generate the frequency for PWM.
    6) First of all, we have to clear these three bits, i.e they must be all set to 0:
    int myEraser = 7;             // this is 111 in binary and is used as an eraser
    TCCR2B &= ~myEraser;   // this operation (AND plus NOT),  set the three bits in TCCR2B to 0
    7) now that CS02, CS01, CS00  are clear, we write on them a new value:
    int myPrescaler = 3;         // this could be a number in [1 , 6]. In this case, 3 corresponds in binary to 011.   
    TCCR2B |= myPrescaler;  //this operation (OR), replaces the last three bits in TCCR2B with our new value 011
    8) now we have a new PWM frequency on pin 9 and 10!
    I registered those values on all PWM pins, changing the value of prescaler (the only exception are pins 13 and 14, see later):
    prescaler = 1 ---> PWM frequency is 31000 Hz
    prescaler = 2 ---> PWM frequency is 4000 Hz
    prescaler = 3 ---> PWM frequency is 490 Hz (default value)
    prescaler = 4 ---> PWM frequency is 120 Hz
    prescaler = 5 ---> PWM frequency is 30 Hz
    prescaler = 6 ---> PWM frequency is <20 Hz
    (prescalers equal t 0  or 7 are useless). 
    Those prescaler values are good for all timers (TCCR1B, TCCR2B, TCCR3B, TCCR4B) except for timer 0 (TCCR0B). In this case the values are:
    prescaler = 1 ---> PWM frequency is 62000 Hz
    prescaler = 2 ---> PWM frequency is 7800 Hz
    prescaler = 3 ---> PWM frequency is 980 Hz (default value)
    prescaler = 4 ---> PWM frequency is 250 Hz
    prescaler = 5 ---> PWM frequency is 60 Hz
    prescaler = 6 ---> PWM frequency is <20 Hz

  • #2
    Greig can give me your perspective when you have a chance?



    • #3
      This is not an option in the plugin because of the Libraries I am using. I would suggest using the API.ino if you wish to modify the code or create your own.

      This might help but I can not support it.

      Zwave = Z-Stick, 3xHSM100� 7xACT ZDM230, 1xEverspring SM103, 2xACT HomePro ZRP210.
      X10 = CM12U, 2xAM12, 1xAW10, 1 x TM13U, 1xMS13, 2xHR10, 2xSS13
      Other Hardware = ADI Ocelot + secu16, Global Cache GC100, RFXtrx433, 3 x Foscams.
      Plugings = RFXcom, ActiveBackup, Applied Digital Ocelot, BLDeviceMatrix, BLGarbage, BLLAN, Current Cost, Global Cache GC100,HSTouch Android, HSTouch Server, HSTouch Server Unlimited, NetCAM, PowerTrigger, SageWebcamXP, SqueezeBox, X10 CM11A/CM12U.
      Scripts =


      • #4
        Thanks for the gentle nudge Greig!

        Ultimately, I will make a custom API, but for now I've made an unofficial adjustment to the SoftPWM library to give me 120Hz instead of 60.

        I see the affect on how this has caused an inverse square relation to "time" (aka 4000ms fade time is now effectively 1000 units), but for my purposes that works for now.

        Much appreciated!