IR remote with Arduino?

I am very new to the whole microcontroller/Arduino thing. For my first real project I want to control a Nikon D40x using an infrared LED. I used the same pulse times as the ones here: bigmike.it - infrared remote control for Nikon with a simple digitalWrite in Milliseconds. I couldn't get that to work with the camera, and I am thinking that the timing is slightly off.

How fast is the Arduino clock cycle? Is it fast enough to display 400 microseconds (0.4ms) correctly? If not, is there a faster way to control an LED?

There's some code for sending and receiving IR remote codes on this thread:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1176098434

alternatively you could build this module and hook it up to the duino:

It would help a lot if you posted your code.

The Arduino can give you a precision pulse down to 3uS (0.003ms)

I suspect your problem is that you are turning the LED on for the entire on pulse. According to the site you linked, you should be modulating it at 38.4kHz.

Without your code though, all I can do is guess and it's much harder to guess what you might have done wrong than see it in your code.

Thanks for the quick responses!

It would help a lot if you posted your code.

The Arduino can give you a precision pulse down to 3uS (0.003ms)

I suspect your problem is that you are turning the LED on for the entire on pulse. According to the site you linked, you should be modulating it at 38.4kHz.

Without your code though, all I can do is guess and it's much harder to guess what you might have done wrong than see it in your code.

Yeah, all I did was modify the Blink example, so here tis:

/*

*copied from http://www.bigmike.it/ircontrol/download.html

WaveForm data:

Infrared period = 26us (~38.4kHz)

Strart pulse:       2000us 2ms
pause:            27830us 27.83ms
1st pulse:        390us 0.39ms
pause:             1580us 1.58ms
2nd pulse:        410us 0.41ms
pause:             3580us 3.58ms
3rd pulse:        400us 0.4ms
longpause:      63200us 63.2ms

REPEAT ONE TIME

*/

int ledPin = 13;

void setup()
{
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  digitalWrite(ledPin, HIGH);
  delay(2);
  digitalWrite(ledPin, LOW);
  delay(27.83);
  digitalWrite(ledPin, HIGH);
  delay(0.39);
  digitalWrite(ledPin, LOW);
  delay(1.58);
  digitalWrite(ledPin, HIGH);
  delay(0.41);
  digitalWrite(ledPin, LOW);
  delay(3.58);
  digitalWrite(ledPin, HIGH);
  delay(0.4);
  digitalWrite(ledPin, LOW);
  delay(63.2);
}

Like I said, I am new to this, so I don't know enough about modulating it at 38.4khz. How do I....I really don't entirely know what that means. yeah... Just keep the sequence running for that amount of time??? n00b moment.

There's some code for sending and receiving IR remote codes on this thread:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1176098434

alternatively you could build this module and hook it up to the duino:

IRMimic Trainable IR Remote Control Transmitter

Thanks, once I finish up this post, I am going to try to record my TV remote. I don't have a real d40x remote to experiment on, but I am thinking about going getting one.

I want to try to avoid getting new hardware for this kind of thing but the learning IR remote thing is pretty cool.

Yeah, all I did was modify the Blink example, so here tis:

Yes, all that does is turn the LED on when you want the pulses to occur. When you set it to be on for 2mS, you really want it to strobe on and off at 38.4kHz for 2mS. That's where the 26uS figure in your comments comes from. In other words, on for 26uS, off for 26uS. To get your 2mS, you need to turn it on for 26uS, off for 26uS, and repeat that 39 times (because 39262 is about 2000). This is what the receiver will automatically see as a 2mS pulse.

Like I said, I am new to this, so I don't know enough about modulating it at 38.4khz. How do I....I really don't entirely know what that means. yeah... Just keep the sequence running for that amount of time??? n00b moment.

Hopefully that will give you the idea. You can look up IR Modulation theory, but I don't know of any suitable tutorials off hand.

I'd like to write a decent IR library at some point, but it's very low on my todo list.

I want to try to avoid getting new hardware for this kind of thing but the learning IR remote thing is pretty cool.

You don't really need new hardware, and the best way yo learn about IR is what you're doing right here.

alternatively you could build this module and hook it up to the duino:

IRMimic Trainable IR Remote Control Transmitter

That's almost as much as an Arduino. It would be just as easy to add an IR emitter and receiver to an Arduino. You have to write a sketch anyway, the one that does all the work isn't that more complicated than controlling the irmimic.

Yes, all that does is turn the LED on when you want the pulses to occur. When you set it to be on for 2mS, you really want it to strobe on and off at 38.4kHz for 2mS. That's where the 26uS figure in your comments comes from. In other words, on for 26uS, off for 26uS. To get your 2mS, you need to turn it on for 26uS, off for 26uS, and repeat that 39 times (because 39262 is about 2000). This is what the receiver will automatically see as a 2mS pulse.

Thanks so much, I didn't quite get that before. How would you do that in code?

EDIT: I just noticed I put this in software interfacing rather than hardware interfacing. Sorry.

Yes, all that does is turn the LED on when you want the pulses to occur. When you set it to be on for 2mS, you really want it to strobe on and off at 38.4kHz for 2mS. That's where the 26uS figure in your comments comes from. In other words, on for 26uS, off for 26uS. To get your 2mS, you need to turn it on for 26uS, off for 26uS, and repeat that 39 times (because 39262 is about 2000). This is what the receiver will automatically see as a 2mS pulse.

Thanks so much, I didn't quite get that before. How would you do that in code?

this is just typed in the message board and not tested, but

for (i = 0; i < 39, i++){                // start pulse
  digitalWrite(ledPin, HIGH);
  delayMicroseconds(26);
  digitalWrite(ledPin, LOW)
  delayMicroseconds(26);
}
delay(28);        // pause
for (i = 0; i < 8, i++){                // 1st pulse
  digitalWrite(ledPin, HIGH);
  delayMicroseconds(26);
  digitalWrite(ledPin, LOW)
  delayMicroseconds(26);
}
delayMicroseconds(1580);        // pause

// and so on.

Also, I noticed your line of delay(27.83);
delay takes as input the long datatype, so it can only handle integers. Your value is being truncated to 27.
Use delayMicroseconds but keep in mind it's only accurate to a maximum of 16000.

Unfortunately I don't have access to the camera for a while. I wish I did, I really want to test out the code.

I didn't even know there was such a thing as 'delayMicroseconds'. I also didn't know the normal delay doesn't read the decimal.

Thank you very much for bearing with me. You are a great help, and I hope to stick around on this forum. It is a great one.

Once I can use than camera, I hopefully can get it to work. I really wanna try! This makes me happy, even if I don't entirely know what I am doing.

I finally got to test my code on the camera, and :frowning: It doesn't work. Assuming that website is right, I think the timing is off on my part.

/*

*copied from http://www.bigmike.it/ircontrol/download.html

WaveForm data:

Infrared period = 26us (~38.4kHz)

Strart pulse:       2000us 2ms
pause:            27830us 27.83ms
1st pulse:        390us 0.39ms
pause:             1580us 1.58ms
2nd pulse:        410us 0.41ms
pause:             3580us 3.58ms
3rd pulse:        400us 0.4ms
longpause:      63200us 63.2ms

REPEAT ONE TIME

*/

int ledPin = 13;

void setup()
{
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  for (int i = 0; i < 38; i++){                // start pulse
    digitalWrite(ledPin, HIGH);
    delayMicroseconds(26);
    digitalWrite(ledPin, LOW);
    delayMicroseconds(26);
  }
  delay(28);                                   // pause
  
  for (int i = 0; i < 8; i++){                // 1st pulse
    digitalWrite(ledPin, HIGH);
    delayMicroseconds(26);
    digitalWrite(ledPin, LOW);
    delayMicroseconds(26);
  }
  delayMicroseconds(1580);                  //pause
  
  for (int i = 0; i < 8; i++){                // 2nd pulse
    digitalWrite(ledPin, HIGH);
    delayMicroseconds(26);
    digitalWrite(ledPin, LOW);
    delayMicroseconds(26);
  }
  delay(36);                                 //pause
 
  for (int i = 0; i < 8; i++){                // 3rd pulse
    digitalWrite(ledPin, HIGH);
    delayMicroseconds(26);
    digitalWrite(ledPin, LOW);
    delayMicroseconds(26);
  }
  delay(63);                                //pause
  
  
  //again....
  
  for (int i = 0; i < 38; i++){                // start pulse
    digitalWrite(ledPin, HIGH);
    delayMicroseconds(26);
    digitalWrite(ledPin, LOW);
    delayMicroseconds(26);
  }
  delay(28);                                  // pause
  for (int i = 0; i < 8; i++){                // 1st pulse
    digitalWrite(ledPin, HIGH);
    delayMicroseconds(26);
    digitalWrite(ledPin, LOW);
    delayMicroseconds(26);
  }
  delayMicroseconds(1580);                  //pause
  
  for (int i = 0; i < 8; i++){                // 2nd pulse
    digitalWrite(ledPin, HIGH);
    delayMicroseconds(26);
    digitalWrite(ledPin, LOW);
    delayMicroseconds(26);
  }
  delay(36);                                //pause
  
  for (int i = 0; i < 8; i++){                // 3rd pulse
    digitalWrite(ledPin, HIGH);
    delayMicroseconds(26);
    digitalWrite(ledPin, LOW);
    delayMicroseconds(26);
  }
  delay(3000);                              //pause
  
  
  
}

Note that all of the last pulses rounded to 8 times in the loop. I think all of this is rounded too much and isn't accurate enough.

I recorded a sound of what it sounded like compared to a TV remote. I don't know if it is any different, but if they both are modulating at the same frequency, wouldn't they be the same pitch? I tried another button on my TV remote and got an entirely different pitch. Anyway here is the sound: http://uploader.polorix.net//files/129/remotes.mp3 The first is my thingy from the Arduino, the next is the TV remote. I don't know if it is any use. If you can and would be willing to try it on an oscilloscope, you might find something out.

Thanks for all the time people are spending to help me get this working, but it's still not quite working. Hopefully soon, I can compare it to the real remote at a camera store.

alternatively you could build this module and hook it up to the duino:

IRMimic Trainable IR Remote Control Transmitter

That's almost as much as an Arduino. It would be just as easy to add an IR emitter and receiver to an Arduino. You have to write a sketch anyway, the one that does all the work isn't that more complicated than controlling the irmimic.

I never said it was an optimal solution.

For someone who's struggling, and in a hurry, having a module that can learn the codes and spew them out again on demand is a good solution if you don't know how to program the duino to do it using an IR LED. And the devil is in the details - hence this thread and difficulty with timings.

I've been looking for a simple answer to this for a student of mine recently and this was one option. Anyway, when you're up against an imminent deadline, any solution is a good solution :wink:

Fortunately jmknapp might possibly have just come to the rescue.... http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1209565937/2

Looks like it's for Philips equipment only just now, but this would make the basis of a great library, by incorporating the info Joe points to at http://www.sbprojects.com/knowledge/ir/ir.htm

Wait a minute... If it is modulating at 26us, wouldn't each

for (i = 0; i < 8, i++){                // 1st pulse
  digitalWrite(ledPin, HIGH);
  delayMicroseconds(26);
  digitalWrite(ledPin, LOW)
  delayMicroseconds(26);
}

part be at 13us for two light pulses?

I changed my code for this as well (with help from my dad.) It still didn't work, but may be a little closer...

/*

*copied from http://www.bigmike.it/ircontrol/download.html

WaveForm data:

Infrared period = 13us (~38.4kHz)

Strart pulse:       2000us 2ms
pause:            27830us 27.83ms
1st pulse:        390us 0.39ms
pause:             1580us 1.58ms
2nd pulse:        410us 0.41ms
pause:             3580us 3.58ms
3rd pulse:        400us 0.4ms
longpause:      63200us 63.2ms

REPEAT ONE TIME

*/



int ledPin = 13;

void setup()
{
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  one_time();
  one_time();
  delay(1000);                              //pause
}

void one_time()  
{
  for (int i = 0; i < 77; i++){                // Send start pulse (2000 uS)
    digitalWrite(ledPin, HIGH);
    delayMicroseconds(13);
    digitalWrite(ledPin, LOW);
    delayMicroseconds(13);
  }
  
  delay(27);                                  // Pause (27830 uS)
  delayMicroseconds(830);
  
  for (int i = 0; i < 15; i++){                // Send first pulse (390 uS)
    digitalWrite(ledPin, HIGH);
    delayMicroseconds(13);
    digitalWrite(ledPin, LOW);
    delayMicroseconds(13);
  }
  
  delayMicroseconds(1);                     // Pause (1580 uS)
  delayMicroseconds(580);
  
  for (int i = 0; i < 15; i++){                // Send 2nd pulse (410 uS)
    digitalWrite(ledPin, HIGH);
    delayMicroseconds(13);
    digitalWrite(ledPin, LOW);
    delayMicroseconds(13);
  }
  
  delay(3);                                 // Pause (3580 uS + 7 uS from pulse2 = 3587 uS)
  delayMicroseconds(580);
 
  for (int i = 0; i < 15; i++){                // Send 3rd pulse (400 uS) - (in real world = 403 uS)
    digitalWrite(ledPin, HIGH);
    delayMicroseconds(13);
    digitalWrite(ledPin, LOW);
    delayMicroseconds(13);
  }
  
  delay(63);                                // Pause for 63200 uS
}

Oh and...

alternatively you could build this module and hook it up to the duino:

IRMimic Trainable IR Remote Control Transmitter

That's almost as much as an Arduino. It would be just as easy to add an IR emitter and receiver to an Arduino. You have to write a sketch anyway, the one that does all the work isn't that more complicated than controlling the irmimic.

I never said it was an optimal solution.

For someone who's struggling, and in a hurry, having a module that can learn the codes and spew them out again on demand is a good solution if you don't know how to program the duino to do it using an IR LED. And the devil is in the details - hence this thread and difficulty with timings.

I've been looking for a simple answer to this for a student of mine recently and this was one option. Anyway, when you're up against an imminent deadline, any solution is a good solution :wink:

Fortunately jmknapp might possibly have just come to the rescue.... http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1209565937/2

Looks like it's for Philips equipment only just now, but this would make the basis of a great library, by incorporating the info Joe points to at http://www.sbprojects.com/knowledge/ir/ir.htm

Thanks for the information, but I am not on a deadline, and most of the point of the project was to learn more about The Arduino. I did find that http://www.sbprojects.com/knowledge/ir/ir.htm page really useful though.

....

for (int i = 0; i < 8; i++){                // 2nd pulse
   digitalWrite(ledPin, HIGH);
   delayMicroseconds(26);
   digitalWrite(ledPin, LOW);
   delayMicroseconds(26);
 }
 delay(36);                                 //pause

for (int i = 0; i < 8; i++){                // 3rd pulse
   digitalWrite(ledPin, HIGH);
   delayMicroseconds(26);
   digitalWrite(ledPin, LOW);
   delayMicroseconds(26);
 }

According to the doc you provided, the pause after the second pulse is 3580us. You're pausing for 36,000us.

I think the change you made with your dad is right, and you caught the mistake in the pulse length.

Note that all of the last pulses rounded to 8 times in the loop. I think all of this is rounded too much and isn't accurate enough.

When you're sending pulses, they have to be done as the stream of the 13uS pulses, so I don't think it's possible to get "more accurate". At this point, I'd wonder if the original remote actually uses the pulses you got from the website.

Are you able to measure the actual pulse times off a real remote?

IR is a very inexact science. My current project uses 1ms and 2ms pulses, and what I receive is out by 15% easily. Your rounding error shouldn't be the problem. In my receive, I have to define a wide range of possible values.

Thanks for the information, but I am not on a deadline, and most of the point of the project was to learn more about The Arduino.

Glad to hear you have plenty of time for learning. Always the best way.

But there's a student of mine here who's working to a very tight deadline, and the info that's been unfolding here is exactly what he needs. So please excuse us if we highjack your thread temporarily! :wink:

I was able to make a remote for my Nikon D70 using the pulse profile on bigmike's page. I used a 555 timer chip to generate the 38khz signal, and then used code a lot like your first post to turn the led, which was being pulsed by the 555 chip, on and off. I'm not great with the electronics either so I'm sure someone could describe this better but what I did is use the 555 timer to constantly supply a 5V 38khz signal to the IR led and then used a digital pin on my arduino, which is normally set to high (so the led doesn't have a voltage drop across it), and dropped it low for the lower frequency pulses. This provides a current path for the led.

In talking to my cube neighbor it sounds like this might not be the most efficient arrangement and that I could "source" current into the 555 by flipping the led and driving the I/O pin high to illuminate. Sounded like I could also trigger the 555 timer on one of its pins. Mostly ahead of my learning curve, but I'm working on it.

Have Fun,
Scott

Oh!!! Sorry I didn't even see your reply until now. That sounds great, I was thinking of using some sort of pulser thingy away from the arduino. Great Idea!! I think I am going to try that.

This might be necroposting .. but I thought this would be useful for anyone else who might be looking for IR remote stuff.

See this page:
http://multyremotes.com/four-channel-IR-remote.htm

It demonstrates switching a 38kHz pulse generated by a 555 timer on and off depending on input pulse.

Those switches + decoder can be emulated by the Arduino code, or rather you can send any data you want by connecting a digital pin to that AND pin or directly to the trigger pin of the 555 .

Cool! I think that'll be helpful to me in the future, and anyone else trying to do something similar. Thanks!