I'm trying to run a Nema 17 motor with a l298N motor Driver for a school project. The issue is that I am running the motor with PWM to avoid overheating of the driver, however the resulting noise at the default frequency is extremely aggravating.

How can I change the frequency for pins 9 & 10 to 20-25 KHz? Any tips tricks and code examples would be highly appreciated (emphasis on code examples).

1 Answer 1


Fortunately, the timer for PWM on both pins 9 and 10 on the Arduino Mega (but not necessarily other boards) is timer 2, so changing the PWM frequency of one will change the PWM frequency of the other.

You should also check that changing the the timer frequency does not effect any other libraries (eg Servo, from memory typically uses timer 2).

The frequency for the timer is set by the TCCR2B register (bits CS22, CS21 and CS20) see p 185 of the datasheet for the Mega2560 IC http://ww1.microchip.com/downloads/en/devicedoc/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561_datasheet.pdf

As far as code goes, try the following (just tested with a small speaker, appears to change to pitch as expected, but I don't have a motor to try it on:

Each line sets the frequency for timer2 (PWM 9 and 10), should be ok to do during setup, and settings will remain. Note that the first line is equivalent to normal default values:

  TCCR2B=(TCCR2B&248)|4;    //prescaler=64, f=977Hz

  TCCR2B=(TCCR2B&248)|3;    //prescaler=32, 1953Hz

  TCCR2B=(TCCR2B&248)|2;    //prescaler=8, 7812Hz

  TCCR2B=(TCCR2B&248)|1;    //prescaler=1 62500Hz

Also check that your motor driver can handle the frequency.

  • Thanks. That helps a bit but I really need to get to 20-25 kHz. That is the only frequency I've had luck using with this motor and not getting any audible artifacts. Any ideas? Oct 23, 2018 at 4:46
  • Those dividers and frequencies are based on a 16MHz clock and 256 step PWM range. If you can change the basic processor frequency, that would help, but will probably break a lot of other things. Changing the number of PWM steps is possible, but not something I've tried. You would need to change the value at which the PWM counter wraps around back to zero. This is normally 255, but if you used prescaler=8 and got the wrap around to occur at 85, you should get 23.4kHz, but your useful PWM range would be 0-84 instead of 0-255 steps.
    – user85471
    Oct 23, 2018 at 5:14
  • That helps some but I am still having a lot of difficulty understanding why getting a PWM range at the correct frequency is such a battle. I'm getting ready to look at hardware solutions. Is there really no effective procedure for making these kinds of changes? One that doesn't break other things or restrict functionality? Oct 23, 2018 at 19:08
  • 1
    The short answer to why it's so hard is that 'Arduino isn't designed to do that', and for the most part, it seems most people don't need it. And for pretty much any other language apart from Arduino, you're going to have to deal with tweaking the registers at this level (even to set up PWM to work at all, let alone customise it).
    – user85471
    Oct 24, 2018 at 0:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.