Arduino Mega 2560 20khz PWM on four pins

Hello, I’m trying to control four dc motors with 20khz PWM. The PWM pins i’m using are 5,6,9,11
I’m following this guy’s post

I’m currently changing PWM in timer 1,2,3,4 to 4Khz (or at least that’s what i think i’m doing)

``````  int erase = 7;  // this is 111 in binary and is used as an eraser
TCCR1B &= ~erase;
TCCR2B &= ~erase;   // this operation (AND plus NOT),  set the three bits in TCCR2B to 0
TCCR3B &= ~erase;
TCCR4B &= ~erase;

int prescaler = 2;         // this could be a number in [1 , 6]. In this case, 3 corresponds in binary to 011.
TCCR1B |= prescaler;
TCCR2B |= prescaler;  //this operation (OR), replaces the last three bits in TCCR2B with our new value 011
TCCR3B |= prescaler;
TCCR4B |= prescaler;
``````

The prescaler values that he mentioned are

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

but the problem is prescaler 2 that i’m using is too little 4khz and prescaler 1 is too much 31Khz my controller supports up to 25khz

So what should I do to get 20Khz to 25Khz ?
I also noticed that when changing the frequency the scale from 0 to 255 in analogWrite gives a different speed is that behavior normal ?

Every Mega timer supports up to 3 PWM outputs, i.e. 2 timers are sufficient for 4 PWM outputs.

Depending on the waveform generation mode, a timer counts up from BOTTOM (zero) to TOP, then either resets to BOTTOM or counts down to BOTTOM again. I.e. the prescaler allows for a coarse frequency setting, the mode allows for another 1:2 factor, and the TOP setting allows to fine tune the PWM frequency. See the ATmega data sheet Table 17-2 Waveform Generation Mode Bit Description. The TOP value can be one of the predefined constants 0x00FF, 0x01FF or 0x03FF, or any value can be configured in ICRn or OCRnA. I'd suggest to use ICR for the frequency adjustment, so that also OCRnA is available for adjusting the duty cycle of channel A on OCnA.

With prescaler=2 the 16MHz clock is divided by 8, for 2MHz. For a 20kHz PWM frequency the TOP value has to be set to 2M/20k=100, or 50 depending on the PWM mode, resulting in 100 or 500 duty cycle steps. For 25kHz the TOP value should be 2M/25k=80 (or 40).
With prescaler=1 the full 16MHz clock speed is used, with TOP values of 16M/20k=800 (or 400), or 16M/25k=640 (or 320).

Since the duty cycle setting depends on the TOP value, the analogWrite() function may not work properly (dunno), at least the parameter value has to fall between 0 and the selected TOP value for the full 0 to 100% range.