What am I missing here?

Hello,

I am trying to generate a 30 KHz pulse using the following code...

/* 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;                                     // Re-set Pulse value to zero
    TCCR2A ^= _BV(COM2B1);                         // toggle pin 3 enable, turning the pin on and off. TCCR2A register ^= Bitwise-shift (Compare Output Mode B, (Bit 5)) 
  }
}

void setIrModOutput(){                             // sets pin 3 going at the IR modulation rate
  //pinMode(3, OUTPUT);                              // Just enable output on Pin 3 and disable it on Pin 11
  TCCR2A = _BV(COM2A1) | _BV(WGM21) | _BV(WGM20);  
  TCCR2B = _BV(WGM22) | _BV(CS22);
  OCR2A = 66;                                      // defines the frequency 51 = 38.4 KHz, 54 = 36.2 KHz, 58 = 34 KHz, 62 = 32 KHz, 66 = 30KHz
  OCR2B = 33;                                      // 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()
{
pinMode(03, OUTPUT);                                // Just enable output on Pin 3 and disable it on Pin 11
}

But when I check the frequency with a scope I get 15000 Hz (see attached photo).

By my count there are three complete cycles ever .2 ms and this works out to 15 KHz. Can anyone explain what I am missing?

-Zeus

It may just be me but it looks like the pinmode() command is in the wrong place...
L

pinMode(03, OUTPUT);OT:
It isn't your problem here, but it is fairly unusual and potentially risky to specify pin numbers in octal.

By using TCCR2A ^= _BV(COM2B1) you toggle the output each interrupt which which generates a square wave at half the interrupt frequency.

Thanks Guys,

I believe that I am going to have to end up moving the pinMode statement to the TImer ISR, but for now I just wanted to get my LED pulsing at the correct frequency so that I can start to build the detection loop that will run in the background.

I don't see how the pinMode placement could be cutting my frequency in half?

-Z

Thanks Stowite,

So what is the fix, do I compensate by adjusting my OCR2A & OCR2B values to account for this, or is this bad form?

  • Z

In order to generate a 30KHz square wave, you need to toggle the output state at 60KHz.

Why not just use the existing IR libraries IRLib or IRremote.

Altenatively, use the TIMER1 (TIMERONE) library which makes PWM easy.....unless you need to use Timer2.

This Thread may be of interest.

...R