How can I change the pwm frequency to 20kHz?

I want to change a pin (let's say pin 7) to 20Khz on my mega 2560.

because the default frequency made my 12V fan produce some strange veeeeee sound.

what should i do? I looked at a lot of tutorial but they are so complicated.

I looked at a lot of tutorial but they are so complicated.

If you are expecting a two line code change, forget it. Just follow one of the tutorials.

i know it will be complicated. but i hope someone can guide me from the begining. the basic tutorial.

I think you can achieve it by changing the prescaler for the appropriate timer. I think that was asked not that long ago. Try a search.

thank mate!

This changes the PWM frequency for pin 3.

/* Code to pulse pin 3 with a modulated signal
* Can be used to drive an IR LED to keep a TSOP IR reciever happy
* This allows you to use a modulated reciever and a continious beam detector
* By Mike Cook Nov 2011 - Released under the Open Source licence
*/
 volatile byte pulse = 0;

ISR(TIMER2_COMPB_vect){  // Interrupt service routine to pulse the modulated pin 3
    pulse++;
  if(pulse >= 8) { // change number for number of modulation cycles in a pulse
    pulse =0;
    TCCR2A ^= _BV(COM2B1); // toggle pin 3 enable, turning the pin on and off
  }
}

void setIrModOutput(){  // sets pin 3 going at the IR modulation rate
  pinMode(3, OUTPUT);
  TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); // Just enable output on Pin 3 and disable it on Pin 11
  TCCR2B = _BV(WGM22) | _BV(CS22);
  OCR2A = 51; // defines the frequency 51 = 38.4 KHz, 54 = 36.2 KHz, 58 = 34 KHz, 62 = 32 KHz
  OCR2B = 26;  // deines the duty cycle - Half the OCR2A value for 50%
  TCCR2B = TCCR2B & 0b00111000 | 0x2; // select a prescale value of 8:1 of the system clock
}

void setup(){
  setIrModOutput();
  TIMSK2 = _BV(OCIE2B); // Output Compare Match B Interrupt Enable
}

void loop(){
// do something here
}

thank you ! still complicate for me as a newbie. but i would like to give in a try

Maybe you could use the PWM library:
http://arduino.cc/forum/index.php/topic,117425.0.html

Erni: Maybe you could use the PWM library: http://arduino.cc/forum/index.php/topic,117425.0.html

this one look easier for me. thank you

void setIrModOutput(){ // sets pin 3 going at the IR modulation rate pinMode(3, OUTPUT); TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); // Just enable output on Pin 3 and disable it on Pin 11 TCCR2B = _BV(WGM22) | _BV(CS22); OCR2A = 51; // defines the frequency 51 = 38.4 KHz, 54 = 36.2 KHz, 58 = 34 KHz, 62 = 32 KHz OCR2B = 26; // deines the duty cycle - Half the OCR2A value for 50% TCCR2B = TCCR2B & 0b00111000 | 0x2; // select a prescale value of 8:1 of the system clock }

Am I right in thinking that the line TCCR2B = TCCR2B & 0b00111000 | 0x2; could be deleted if the previous line TCCR2B = _BV(WGM22) | _BV(CS22); was changed to TCCR2B = _BV(WGM22) | _BV(CS21); ?

Or is there some other magic going on here that I am not seeing? I am trying to port this code over to the ATTiny85 and so I am going through each line to figure out what it does... a good way to learn I am finding. :cold_sweat:

You can do it all in one line, yes. I haven't checked the bit patterns, but that is the right idea.

Hopefully this is useful to somebody then.. I am not too familiar with open source code so I have left the credits in, is that right? I didn't do much anyway. Big thanks to Mike for this code.

/* Code to pulse pin 1 with a modulated signal
* Can be used to drive an IR LED to keep a TSOP IR reciever happy
* This allows you to use a modulated reciever and a continious beam detector
* By Mike Cook Nov 2011 - Released under the Open Source licence
* Ported to ATTiny85, Jon Stoski Oct 2012
*/
 volatile byte pulse = 0;

ISR(TIMER0_COMPB_vect){  // Interrupt service routine to pulse the modulated pin 1
    pulse++;
  if(pulse >= 8) { // change number for number of modulation cycles in a pulse
    pulse =0;
    TCCR0A ^= _BV(COM0B1); // toggle pin 1 enable, turning the pin on and off
  }
}

void setIrModOutput(){  // sets pin 1 going at the IR modulation rate
  pinMode(1, OUTPUT);
  TCCR0A = _BV(COM0B1) | _BV(WGM01) | _BV(WGM00); // Enable output on Pin 1, waveform generation to fast PWM
  TCCR0B = _BV(WGM02) | _BV(CS01); //Sets clock prescaler to 8
  OCR0A = 51; // defines the frequency 51 = 38.4 KHz, 54 = 36.2 KHz, 58 = 34 KHz, 62 = 32 KHz
  OCR0B = 26;  // deines the duty cycle - Half the OCR2A value for 50%
}

void setup(){
  setIrModOutput();
  TIMSK = _BV(OCIE0B); // Output Compare Match B Interrupt Enable
}

void loop(){
// do something here
}

Dear Sir 50 of 20 khz you Durly I cycle Send the program what?