Go Down

Topic: How to create a 38 Khz pulse with arduino using timer or PWM? (Read 21 times) previous topic - next topic


I am experimenting with an infra red remote, sending my normal data that I usually send by radio modules, using VirtualWire, or maybe EasyTransfer later.

I am driving the base of an LED driver transistor ,  ( via a resistor ) with 38 Khz from a similar timer generator as Nicks ( but with  one of 2 outputs for some reason http://tthheessiiss.wordpress.com/2009/08/05/dirt-cheap-wireless/ ? )

The data I take from another pin ( using NewSoftSerial)  to the base of the transistor with a diode chopping the 38 Khz stream.

It is working fine, and I want to try Nicks idea of reducing the duty cycle to pump the IREDs harder. 
I am only sending a few bytes at a time at 2400 baud, and can afford to have 100mS gap between bursts to keep the average drive down a bit too.

I see the background 38Khz is all done in setup.

What are the implications with this if I want my remote to go into sleep mode ?  (  The remote is 4.5 v battery operated   )

This is my general enter sleep routine that I blatantly copied from Crossroads, with little knowledge of how it works :-

Code: [Select]
void enterSleep()

  /* Setup pin2 as an interrupt and attach handler. */
  attachInterrupt(0, pin2Interrupt, LOW);
  delay(50); // need this?
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // setting up for sleep ...
  sleep_enable();                       // setting up for sleep ...
  ADCSRA &= ~(1 << ADEN);
  PRR = 0xFF;
  sleep_mode();                         // now goes to Sleep and waits for the interrupt

  /* The program will continue from here after the interrupt. */
  detachInterrupt(0);                 //disable interrupts while we get ready to read the keypad
  PRR = 0x00;
  /* First thing to do is disable sleep. */
}  // end of  enterSleep()  function
With my mobile phone I can call people and talk to them -  how smart can you get ?

Nick Gammon

Implications? Some sleep modes stop the timers, if that is what you are asking.


Hi Nick
Yes thats what I am asking really, I dont know if   ADCSRA &= ~(1 << ADEN);  and    PRR = 0xFF;   stop the timers.

And whether I can set the data and 38Khz pins high with pullups before sleeping ?  (  I have a  PNP driver transistor which would switch off )

I was trying to save some precious time,   I guess I will write some code , connect an ammeter and suck it and see !  :-)
With my mobile phone I can call people and talk to them -  how smart can you get ?


Nick, could you indulge me and explain how I might send some information as opposed to just modulating the carrier wave at some frequency?  For example, I would like to have a network of basic sensors that would each have a unique identifying ID number that, when sent, would tell the mother ship 'here I am and I have reached the limit!'.

Nick Gammon

What do you mean by modulate? Turn the signal on and off at a certain rate to indicate a number?


Yes exactly. What word would you use? It's kind of like the second derivative.

Nick Gammon

Can't you just use the protocol that IR remotes use? There is already code to send and receive that.


I could but it seems like they are very long numbers and I only need 40 or so distinct numbers.  Also, I am trying to use an attiny so the library won't work. I'm not really trying to get you to do the work for me but I have a more reductionist approach to learning so having something to dismantle is immensely helpful.

Nick Gammon

Yes, but the library lets you send raw protocols (ie. a series of bits).


The low-level output might need tweaking for the Attiny, but the rest should be the same. You basically want to break your data down into X bits, and then send those bits, right?


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

Code: [Select]

const byte LED = 10;  // 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.

Thank you very much for this nice code. On the Arduino Mini V5, the pin for OC2A seems to be 11, not 10.

Nick Gammon

Looks like a typo. OC2A outputs on D11. I've amended the post on page 1 of this thread, thanks!


I did set an other topic on a close subject:

Troubles modulating a pulse generated by CTC



Oh My Gosh!
"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."

AWOL, dude you are a genius.  I was thinking about doing a logic gate for that.  That is so dang simplistic and perfect.  You can just have the the direction of the led to invert the signal.  This is great.  Thank you!


USING Arduino nano v 3.0 

Just trying all that weak to put a IR led at 38khz  its so crazy reading all the posts,

I realy Please some ppl, can i have a simple code that work on arduino nano v3.0
geting a IR led at 38khz.  Please

I start geting crazy reading testing reading testing ..... dam god help us

Domino60   :~

Go Up