How to create a 38 Khz pulse with arduino using timer or PWM?

Will the above code interfere with these?

No.

since you code uses interrupt which interrupt I can't utilize in further coding?

As the code uses pin 3 you can't use that pin as an interrupt, but if that is a problem just change it to use pin 11 instead of pin 3.

Also I understand pin 3 and pin 11 cannot be use for any other purpose

If that is what you understand then you are wrong.

This code fires off an ISR every cycle but there is no need to do this:-

What do you mean by that?

P.s. I am no pro in assembly programming with avr. Though I know assembly with 8085 and 8051.

Grumpy_Mike:

Also I understand pin 3 and pin 11 cannot be use for any other purpose

If that is what you understand then you are wrong.

Please explain. I am not an experienced coder.

I see in the comments that pin 11 is being disabled for the output that why i said i t is not available for use.
As for pin 3, i meant that since the 38 Khz wave will be available on that pin, it has been made use of.

Why not just use the Tone() function?
http://arduino.cc/en/Reference/Tone

This code generates 38 KHz on pin D11 on the Mega2560:

const byte LED = 11;  // Timer 2 "A" output: OC2A

void setup() {
  pinMode (LED, OUTPUT);
  
  // set up Timer 2
  TCCR2A = _BV (COM2A0) | _BV(WGM21);  // CTC, toggle OC2A on Compare Match
  TCCR2B = _BV (CS20);   // No prescaler
  OCR2A =  209;          // compare A register value (210 * clock speed)
                         //  = 13.125 nS , so frequency is 1 / (2 * 13.125) = 38095

}  // end of setup

void loop() { }

It does not use interrupts and does not interfere with any other pin.

(edit) Changed from D10 to D11. OC2A outputs on D11.

ErikEnglund:
Why not just use the Tone() function?
http://arduino.cc/en/Reference/Tone

This looks interesting!! and hugely simplistic.

Can this produce a freq. as large as 38 Khz? In the example they are using quite low frequencies. will test this tomorrow.

void setup ()
{
tone (10, 38000);
}
void loop () {}

That generates a 38 KHz output, more or less. However it's not as smooth as the hardware timer.

The tone library uses a timer, but that causes an interrupt. Inside the interrupt it does a counter. When the counter is met it toggles the pin. So there is a bit of jitter (because other interrupts might fire), and it consumes CPU resources.

The pure hardware solution described above runs without any code being called at all (once you set it up).

Thanks for the explanation. This method it is, then!

I used the following 2 fxn to measure frequency using your (nick gammon's timer method) code.

long getFrequencySampled()
{
#define SAMPLES 4096
long freq = 0;
for(unsigned int j=0; j<SAMPLES; j++) freq+= 500000/pulseIn(pin, HIGH, 250000);
return freq / SAMPLES;
}

long getFrequency()
{
long duration=pulseIn(pin, HIGH, 250000);
Serial.print("duration of pulse is: ");
Serial.println(duration); //in microseconds
duration=duration*2;
Serial.print("duration of pulse is: ");
Serial.println(duration); //in microseconds
freq = 1000000/duration;
Serial.print("Frequency is: ");
Serial.println(freq);

return freq;
}

getFrequencySampled() returned a value of 40.5-41 Khz.
getFrequency() returns a value that alternates randomly between 35 Khz and 41 Khz. (for pulse durations of 12 & 14 microseconds)

Any idea why the frequency doesn't equal the theoretical value?

praky:
long duration=pulseIn(pin, HIGH, 250000);

My code doesn't use pulseIn. Can you post the whole sketch?

I used pulseIn to measure the freq.

Here is the whole code...

const int pin = 7;
unsigned long duration;
long x;
long freq;
const byte LED = 10;  // Timer 2 "A" output: OC2A
void setup()
{
  pinMode(pin, INPUT);
  Serial.begin(9600);
  
  //
  pinMode (LED, OUTPUT);
  
  // set up Timer 2
  TCCR2A = _BV (COM2A0) | _BV(WGM21);  // CTC, toggle OC2A on Compare Match
  TCCR2B = _BV (CS20);   // No prescaler
  OCR2A =  209;          // compare A register value (210 * clock speed)
                         //  = 13.125 nS , so frequency is 1 / (2 * 13.125) = 38095
  
//  tone (10, 38000);
}
long getFrequency() 
{
  long duration=pulseIn(pin, HIGH, 250000);
  Serial.print("duration of pulse is: ");
  Serial.println(duration);  //in microseconds
  duration=duration*2;
  Serial.print("duration of pulse is: ");
  Serial.println(duration);  //in microseconds
  freq = 1000000/duration;
  Serial.print("Frequency is: ");
  Serial.println(freq);
  
  return freq;
}
void loop()
{
  x=getFrequency();
  Serial.print("Frequency is: ");
  Serial.println(x);
  
}
long getFrequencySampled() 
{
  #define SAMPLES 4096
  long freq = 0;
  for(unsigned int j=0; j<SAMPLES; j++) freq+= 500000/pulseIn(pin, HIGH, 250000);
  return freq / SAMPLES;
}

Is it possible to create a 38 khz modulated wave by the same method?

If you're going to use it for modulated IR, just connect one end of your LED to your constant 38kHz source, and the other end to another output pin.
Waggling the other output pin at your desired (<38kHz!) rate produces a modulated 38kHz IR beam.

If you want to modulate the IR then that is what the interrupted service routine was to do in the code I originally posted. It is best to do this since the modulation can be synchronised with the carrier.

PulseIn isn't particularly accurate. From the documentation:

The timing of this function has been determined empirically and will probably show errors in longer pulses

I checked the timer output on the oscilloscope. Plus, assuming your clock is accurate, it matches the theory. PulseIn just works by counting in a loop.

It looks like Mike's solution incorporates an ISR to turn the output of the timer on or off, exactly at the start of each pulse, which, as he says, would synchronize with the carrier.

Grumpy_Mike:

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
}

He's using a different mode (PWM) and a different prescaler, but you can work out the maths:

1 / ((1 / 16e6) * 8 * 52) = 38461.538

So, his timer will generate 38.46 KHz, as advertised.

I am a newbie with assembly with avr. can you please post the code of 38 Khz wave modulated with 1 Khz wave to be used with TSOP1738.
Will be a life saver. Thanks.

What was wrong with Claghorn's suggestion on page 1?

i don't know a lot about modulation and synchronization. I get the idea that grumpy_mike's code with little modification will produce a modulated 38 Khz wave with 1 Khz. Any idea what to modify in that code?

Hi,
If all you are trying to do is generate a 38khz carrier, switched at 1khz, why not do it in hardware with a single 556 Timer, that what this does -

It costs about 2 dollars to build.

Duane B

rcarduino.blogspot.com