IRsend::sendRaw to constantly blink the LED at 38KHz

I want to blink an IR LED at 38KHz, using IRsend::sendRaw. I don't want to send any codes - I simply want to make the LED blink, constantly. And that's ALL I want this sketch to do. (I'll do the receiving on another Arduino.)

But sendRaw() takes 3 parameters:

sendRaw(unsigned int buf, int len, int hz)

I know I use 38 for the last one, but what should I use for the first two?

Also: once I know how to make it blink: should I do it continuously using while(1) at the top of the loop function, or should I call sendRaw once in loop, and just let it loop over and over and over?

Thanks. I've spent a few hours trying to find the answer to this question already, including digging into the low level files of the IRemote library. But since the blinking is done at a very, very low level using PWM - it's way over my head to decipher.

while(1) {
   digitalWrite(ledpin,HIGH)
   delayMicroseconds(12);   //if frequency is too low, reduce
   digitalWrite(ledpin,LOW);
   delayMicroseconds(12);
}

Or use Timer1, as described here.

jremington,

Thanks for the basic code. One question: you commented "if frequency is too low, reduce". But how will I know if it's too low? (Or too high?) I mean, the math seems pretty close (1,000,000 / 38,000 = 26.something), so using 12 (instead of 13) allows a couple microseconds for the actual operation of the circuit. But what if it should really be 11? As I said - how will I know? The thing that's looking for it is an IR sensor that works best when the LED is pulsing at 38KHz - but it's not going to tell me it's working optimally, or not - is it?

Anyway, thanks - I guess it should have been obvious.

But REALLY thanks for the link to the code to do it all with interrups! I don't understand any of it, but I know that's how the IRemote library does it. The page you linked me should let me do exactly what I want, very precisely. Awesome!

HOWEVER.... it was written in 2012, for a 16MHz Arduino. I'm working with an 80MHz ESP8266 board, and I can't decipher the code where he converts the clock cycle of the board into nanoseconds.

// set up Timer 1 - gives us 38.095 MHz (correction: 38.095 KHz)
TCCR1A = 0; 
TCCR1B = _BV(WGM12) | _BV (CS10); // CTC, No prescaler
OCR1A = 209; // compare A register value (210 * clock speed)
// = 13.125 nS , so frequency is 1 / (2 * 13.125) = 38095

// Timer 2 - gives us our 1 mS counting interval
// 16 MHz clock (62.5 nS per tick) - prescaled by 128
// counter increments every 8 uS. 
// So we count 125 of them, giving exactly 1000 uS (1 mS)
TCCR2A = _BV (WGM21) ; // CTC mode
OCR2A = 124; // count up to 125 (zero relative!!!!)
TIMSK2 = _BV (OCIE2A); // enable Timer2 Interrupt
TCCR2B = _BV (CS20) | _BV (CS22) ; // prescaler of 128

I can't figure out where to replace "16000" with "80000" to convert this to an 80MHz processor. The comments aren't detailed enough for me. For example, how does 210 x 16000 = 13.25 nS? It's all so cool, but way too deep for this noob. Maybe I'll just go w/ the original, simple code.

Thanks for everything!

There is no way the hardware Timer1 code will work on a completely different processor. All the details will be different.

There are various ways to optimize the simple while(1) code to get 38 kHz. One is to measure the timing with an oscilloscope and adjust the delay appropriately. Another is to change the delay value until you find one that gives a reliable response from your IR detector.

Finally, you can time the entire loop very accurately by using direct port access commands to set and clear the port pins, which takes just a couple of machine instruction cycles (1 cycle=62.5 nanoseconds on an Arduino Uno).

For example on an Arduino Uno:

while (1) {
PORTB |= (1<<5);  // set PB5 (D13 on Arduino Uno) HIGH.
delayMicroseconds(13);
PORTB &= ~(1<<5); // set PB5 LOW
delayMicroseconds(13); 
}

jremington,

I sincerely appreciate your help, but I need some clarification. How does that while() loop you last presented let me know how long it takes for a whole cycle? IOW, where / how do I know how long the loop takes? I don't see any serial output. Sorry if this is a dumb question. I'm obviously missing something.

Brian

IOW, where / how do I know how long the loop takes?

Use an oscilloscope to check the timing of the port pin output, or put an IR LED on the port pin (with current limiting resistor) and see if the IR receiver responds.

This particular loop toggles the port pin PB5 (digital pin 13) at very close to 38 kHz, on an Arduino Uno. I checked with my scope and got 41 kHz, so either my Arduino Pro Mini resonator is fast, or the scope is slow, or both.

pinMode(13,OUTPUT);
while (1) {
PORTB |= (1<<5);  // set PB5 (D13 on Arduino Uno) HIGH.
delayMicroseconds(13);
PORTB &= ~(1<<5); // set PB5 LOW
delayMicroseconds(13);
}

Can do it all in setup()
Leo..

const byte IR_LEDpin = 11; // IR transmitter LED with 100ohm (minimum) CL resistor

void setup() {
  pinMode (IR_LEDpin, OUTPUT);
  TCCR2A = _BV (COM2A0) | _BV(WGM21);
  TCCR2B = _BV (CS20);
  OCR2A =  209; // ~209 = ~38kHz | ~219 = ~36kHz
}

void loop() {
}

Can do it all in setup()

Not with an ESP8266 (reply #2).

jremington:
Use an oscilloscope to check the timing of the port pin output, or put an IR LED on the port pin (with current limiting resistor) and see if the IR receiver responds.

This particular loop toggles the port pin PB5 (digital pin 13) at very close to 38 kHz, on an Arduino Uno. I checked with my scope and got 41 kHz, so either my Arduino Pro Mini resonator is fast, or the scope is slow, or both.

Ah... an oscilloscope. I suppose I ought to have one of those. I guess I'll try it, and see if my IR receiver can see it. Thanks so much for your patience!