Changing the PWM frequency to 20kHz on a Mega

Hello there,

I'm powering a motor from my Arduino Mega through a Pololu driver. When I send the signal, the motor makes a high-pitch noise which is very annoying, probably due to a low frequency PWM.

The driver supports up to 20kHz, so I'd like to change the frequency to that value. My programming experience is limited, so any help/advice would be super appreciated.

Cheers,

Carlos

Which pins? There are three timers, one is used by millis(), micros() and delay().

The other ones you can speed up fairly easily by changing the prescaler, from memory.

I was using pins 8 & 9 on the Mega, which supply a PMW output. But I can obviously change them if they interfere with those functions (I'm using them).
Is there a way of knowing which timer control which pins?

How's the pre-scaler changed?

Thank you!

colabarris:
I was using pins 8 & 9 on the Mega, which supply a PMW output. But I can obviously change them if they interfere with those functions (I'm using them).
Is there a way of knowing which timer control which pins?

The Mega 2560 reference schematic, available from this site. In part:

You can see from that, that one is on timer 2 (OC2B) and one on timer 4 (OC4C).

How's the pre-scaler changed?

To simplify things, change to pins 9 and 10 which are both on timer 2 (OC2A and OC2B).

Then add a couple of lines of code to alter the prescaler:

void setup ()
  {
  TCCR2B &= ~ _BV (CS22); // cancel pre-scaler of 64
  TCCR2B |= _BV (CS21);   // use pre-scaler of 8
  analogWrite (9, 50);    // 19.6 % duty cycle
  analogWrite (10, 200);  // 78.4 % duty cycle
  }  // end of setup

void loop () { }

Results:

The predicted duty cycles show up, with a PWM frequency of 3.92 KHz.

Or you can use no pre-scaler, which gives a PWM frequency of 31.37 KHz:

void setup ()
  {
  TCCR2B &= ~ _BV (CS22); // cancel pre-scaler of 64
  TCCR2B |= _BV (CS20);   // no pre-scaler
  analogWrite (9, 50);    // 19.6 % duty cycle
  analogWrite (10, 200);  // 78.4 % duty cycle
  }  // end of setup

void loop () { }

Wow, thanks a lot, Nick. That was of great help and quite easy!

Just one last question: if I don't use any pre-scaler and the freq. is 31.7kHz, will it still work (given that the driver only supports 20kHz)?

Cheers!

I guess not, if it says not. I wasn't sure what you meant by "driver" in this context.

3.92 KHz should be a lot better (although audible, possibly).