Infrared remote control receiver for Arduino

December 30th, 2007 · 43 Comments ·

I developed this infrared remote control decoder for Arduino on my Arduino-compatible STK500 evaluation board for Atmel’s AVRs.

The sketch is pretty much standard C code so porting to non-arduino dev systems is almost immediate.

Remote control receiver / decoder for Arduino

I actually developed the code in C for a smaller ATtiny24 for a specific project underway thenI adapted it for Arduino and made available to anyone whom might need it.

The sketch expects the IR receiver on digital pin 8 and is in the form of a demo where 4 LEDs on digital output 4, 5, 6 and 7 are turned ON on my STK500 (microprocessor’s output connected to LEDs’ cathodes) when keys 1 2 3 and 4 are received from the remote. The power button on the remote turns all LEDs OFF.

The code also ouputs the received code to the serial port to be read on the serial console (9600 Baud-8-N-1) .

Any RC5 Philips TV remote control seems to be fine and the few programmable ones I tried work fine. Feedbacks are welcome.

…yes, one day I`m buying a real Arduino !

The sketch for Arduino is here.

IMPORTANT : should you experience problems with random resets, read Mark Arduino’s comment on Jan 24, 2010 at 1:06 pm.

Enjoy.

Tags: ATtiny24 · Arduino · RC5 · STK500

43 responses so far ↓

  • Oscar G. // Mar 12, 2008 at 12:16 am

    Hey, excelent work! I will try this on my board soon :)

    Best regards,
    Oscar G.

    http://www.BricoGeek.com

  • Infrared Remote Control Receiver for Arduino | Circuit Projects & Schematics Blog // Mar 21, 2008 at 10:09 am

    [...] More Source: http://www.5volt.eu/archives/14  These icons link to social bookmarking sites where readers can share and discover new web [...]

  • Mark // May 15, 2008 at 9:45 am

    What is the IR reciever device that you have used?

    Regards – Mark.

  • admin // May 16, 2008 at 6:48 pm

    Ciao Mark, the one in the picture is a Sony SBX1610-11. Many other work fine, I also tried a Sharp GP1U7 and other Sonys like SBX1620 and 1644.

  • Makezine has a infrared remote for the Arduino | Gisvold blog // Jul 26, 2008 at 6:03 pm

    [...] Having a remote control pass data, via an Arduino and the serial port, can be a great addition to a lot of projects. This is not the most detailed of builds, but I think there is enough information there for anyone that is already tinkering with the Arduino. There is a link to the sketch code on the site if you want to give this project a try. – Link [...]

  • Tom // Nov 26, 2008 at 1:00 pm

    I tried compiling your sketch and I keep on getting this error:

    error: ‘OCR0A’ was not declared in this scope In function ‘void TIM0_COMPA_vect()’:

    Any advice ?

  • admin // Nov 29, 2008 at 7:57 am

    Ciao Tom, sorry for not replying earlier.
    I downloaded my pde to be sure and it compiled fine with Arduino 0012 Alpha.
    I really don’t know. I might say try to update your Java VM. I think the runtime edition should suffice ( not the JDK, I mean ).
    Let me know.
    Alex

  • Marek // Dec 9, 2008 at 11:01 pm

    Hi!
    I resolved that problem deleting first lines starting with ‘//’
    In my case helps.

    Bye.

  • Robin // Jan 12, 2009 at 1:54 am

    Hey I like your code, I used it in my box

  • admin // Jan 12, 2009 at 9:55 pm

    @Robin, I’m glad you did. Ciao
    Alex

  • Antonio // Mar 31, 2009 at 6:12 pm

    Hi,

    we have use a delay in one of our function add to your code, but we have found that it doesn´t work. Do you know which is the problem and how can we solve it?

    Thank you very much for your code.

    I´m from Spain, so if you speak Spanish, it will be easier for me to understand you.

  • admin // Apr 1, 2009 at 7:57 am

    @Antonio,
    ciao, sorry, I can’t speak Spanish.
    How did you implement the delay ? Used an Arduino library function ? If so be careful that it might use Timer0 used in my code already, messing it up.
    Why did you need a delay ? Is it related to the RC5 function or to your application ?
    Best
    Alessandro

  • Antonio // Apr 1, 2009 at 9:40 pm

    Hello Alessadro,
    The delay is in my function. Arduino doesn’t use any library and I don’t use Timer0.
    I want turn on sequentially with a delay some LEDs, when I press a key on the remote IR.
    Any solution?

    Thanks

    Antonio

  • admin // Apr 3, 2009 at 1:10 pm

    @Antonio, the demo code works, that is the remote is decoded and the LEDs are turned on as expected ? Add the delay function afterward .
    Ciao

  • Antonio // Apr 3, 2009 at 7:49 pm

    Alessadro,
    This is the problem.
    If I change your program for this, doesn’t work correctly

    switch(data_word) {
    case 0×01:
    digitalWrite(4,1);
    digitalWrite(5,1);
    digitalWrite(6,1);
    digitalWrite(7,0);
    delay (200);
    digitalWrite(4,0);
    digitalWrite(5,0);
    digitalWrite(6,0);
    digitalWrite(7,1);
    delay (200);
    digitalWrite(4,1);
    digitalWrite(5,1);
    digitalWrite(6,1);
    digitalWrite(7,0);
    break;

    //etc for other codes.
    }

    Bye,

    Antonio

  • admin // Apr 4, 2009 at 8:25 am

    @Antonio, if no other thing is changed in my source you should have the console still working : do you read on the console the RC5 codes still? If you remove the delay(200); do you get some output ?
    Still I’m not sure delay() does not use Timer0. Did you make some investigations on this ? I’ll try and chip some time on this myself.

    Best for now

  • Antonio // Apr 5, 2009 at 3:41 pm

    Hello Alessandro.
    I have not changed anything in your code (only the code of “case”) and it works well.
    If I remove the delay, I get some output.
    All works fine until I hit the 1 on the IR remote that is assigned a function with delay, but if I hit another code such as 2, the program work perfectly because in this “case 0×02″ there aren’t the function delay.
    I have checked that if we send a code to execute without delay function, this works well.

    Antonio

  • admin // Apr 6, 2009 at 8:13 am

    Antonio, this confirms my suspect : delay() uses Timer 0 in some way, haven’t checked the source code for delay() though.
    It could be worth and faster to use a different delay function or a for(…) loop. Writing a C function that uses timer1 or 2 directly or, better use the MStimer2 timer2 library function (http://www.arduino.cc/playground/Main/MsTimer2), the one I used in my XXI Century Sundial. MsTimer2 runs on interrupt also, and this is better use of processors resources.
    Ciao
    Alessandro

  • Antonio // Apr 7, 2009 at 10:45 am

    Thanks alessadro, so try and tell you the result.
    Best regards,

    Antonio

  • Angga // May 7, 2009 at 10:28 am

    Ciao Alessandro,

    I tried compiling your code with Arduino 0015 and got error like Tom had (4th comments above). I’m not sure if this is a JRE issue though. Can I have your original C implementation (the one for tiny24)? I want to learn from it since I’m quite a beginner too.. Thanks a lot!

    @Marek: Which lines do you mean? Lines starting with // are comments and I don’t find anything that might solve the problem..

    Best Regards,
    Angga

  • admin // May 7, 2009 at 10:58 am

    Ciao Angga, I don’t remember the assumptions I made to suggest to upgrade the JVM (duh !) : probably I found it on the Arduino’s forum. This is the kind of issues that are discussed in the relevant forums, let it be Arduino, Processing, AVR in general. Tom didn’t return to me on this (shame on you Tom !) this might mean that he succeeded.
    I’ll do some googling on it and will try to return to you on this.
    The source for ATtiny24 I have to look for it on my PCs as I abandoned it right after success and modified for Arduino. Tonight or in the weekend I’m after it.
    Best for now.
    Alessandro

  • Angga // May 8, 2009 at 7:36 am

    Wow thanks a lot then. I’ll do some googling and forum-searching as well. Will return here if I found something.

    Best Regards,
    Angga

  • thomas // May 11, 2009 at 9:46 pm

    I’m new in the Arduino world
    I found your RC5 code and I like it because it’s interupt driven
    The problem is, I can’t get any response from my Philips Remote control. It works with one of my PIC project
    I have Arduino Duemilanove board and pin 8 is connected to a TSOP4836 via 220ohm resistor

    I don’t know if any one can help me to get it to work

  • Antonio // Jun 16, 2009 at 7:33 pm

    Hi Alessandro,

    I’m trying to make an application when you press the same key I change the digital output alternately.
    For some unknown reason, I do not change the status of the variable.
    The code is as follows:

    case 0×01:
    {
    if (valverde==LOW)
    valverde=HIGH;
    else
    valverde=LOW;
    digitalWrite(verde,valverde);
    }

    the other code does not work either:

    case 0×01:
    {
    valverde=!valverde;
    digitalWrite (5,valverde);
    }

    Have you ever tried something similar?

    Best regard,

    Antonio

  • admin // Jun 18, 2009 at 1:20 pm

    Ciao Antonio, no, I haven’t tried anything similar.
    Of course you placed the “break;” statement before the following “case” statement.
    Anyways, I’d try something like this :
    if (valverde==LOW) {
    digitalWrite(verde,HIGH);
    valverde=HIGH;
    }
    else
    {
    digitalWrite(verde,LOW);
    valverde=LOW;
    }
    Very un-elegant I understand.

    The fact is I’m not sure about the type of LOW and HIGH and how these might be ‘casted’

    Another option :

    int valverde = 1; // declaration and initial value assignment

    case 0×01:
    digitalWrite (verde, valverde);
    valverde = 1 – valverde;
    break;
    case 0×02:
    …..

    I like this kind of approach when working with toggles !
    Hope this helps.
    Ciao
    Alessandro
    P.S. Let me know .

  • Matt Baker // Jul 13, 2009 at 10:19 am

    Hi, great project.
    I got it working on my Arduino in minutes. I am using a random IR receiver from an old VCR it took me more time to find the pin out of the receiver than get the S/W to work.

    One question, I added a println() to the Setup() function and setup() appears to be called every time the RC sends a button press. Have I hissed something ?

    TIA
    Matt

  • admin // Jul 14, 2009 at 8:42 am

    I’m not sure how println() works exactly in terms of interrupts used, It may use timers (say one that I use in the code). Don’t know.
    Try and use a simpler LED ON/OFF scheme.
    I’m still looking for a table that specifies for each library function the resources allocated (timers,interrupts, other) which would prevent this bogus tobe coded in. That would be very useful.
    Hope this helps
    Ciao
    Alessandro

  • Mark Farey // Aug 8, 2009 at 5:22 am

    Very nice work but I don’t get any output when I run this on a Duemilanove. Can you please help?

    Thanks,
    Mark.

  • Mark Farey // Aug 9, 2009 at 3:03 am

    Further thoughts… I know next to nothing about interrupts but is Timer 1 associated with a particular pin and must it be a PCM pin? What’s an appropriate pin number for the Duemilanove and does that change the initialization? As far as I can tell the program hangs at the lines:

    // Timer 0 : Fast PWM mode. Stopped, for now.
    TCCR0A = _BV(WGM00) | _BV(WGM01);
    TCCR0B = _BV(WGM02);

  • admin // Aug 17, 2009 at 4:02 pm

    @Mark, sorry I couldn’t reply to your message sooner.
    Arduino 2009 seems pretty much the same hardware as the one I used to develop the IR remote receiver. Provided that the issue is not with the type of remote control, it could be the release of Arduino developer’s kit (the one used to create the source code and compile).
    Are you using my same source pde without any modification ?

  • Rodrigo // Nov 29, 2009 at 1:30 pm

    Hi Alessandro,

    Great work! This is awesome.
    Still, I’m having the exact same Toggle problem Antonio had.
    I’m clueless. Everything seems to work allright when toggling using different buttons, but I’m still unable to toggle an output using the same button on the remote.
    What you suggested (below) does not work either!

    admin wrote:
    case 0×01:
    digitalWrite (verde, valverde);
    valverde = 1 – valverde;
    break;
    case 0×02:

  • admin // Dec 1, 2009 at 10:06 am

    Ciao Rodrigo,
    I can’t imagine anything different from what I already posted and regretfully Antonio did not return here on how he solved his problem…

    I sent him a message and hopefully he will post a comment with his solution .

    Best for now
    Alessandro

  • CaviaR // Dec 11, 2009 at 2:05 pm

    Hi Alessandro!

    That’s a great project, I really like it, but I have a big problem.

    I’m using this code with Arduino Duemilanove with the stock ATmega328 controller. It runs perfectly, sends the values to the computer, but in the switch statement, only the first line runs, after that, it steps out from the statement. Doesnt matter what I put in, it always runs only the first line.
    For example a dummy code:
    switch(data_word) {
    case 0×01:
    digitalWrite(ledPin, HIGH)
    digitalWrite(ledPin, LOW)
    break;

    }

    In this case, the led light stays on forever, while it should flash for an unnoticeable time.
    There is a more strange thing.

    If i put a for circle anywhere in the code, it starts, but only just the first line runs and just for one time.

    Why could it be? The IC is good, but I tried with another one with the same result. I’m using Arduino 0017 environment, but tried with 0016 and 0015.

    Please help me! Thank you!

  • admin // Dec 14, 2009 at 2:48 pm

    CaviaR,
    The code as written should not pulse the LED but just leave it in the LOW state .
    If i’m not missing anything here you should change the digitalWrite lines as follows:

    digitalWrite(ledPin, HIGH)
    digitalWrite(ledPin, LOW)
    digitalWrite(ledPin, HIGH)

    i.e. add a third digitalWrite() statement.

    Assuming the LED is connected to output pin and positive supply. Warning, it is going to be a very short pulse !

    I’m wondering if Antonio and Rodrigo came to some good solution …

  • Mark Arduino // Jan 19, 2010 at 12:30 am

    Hi,

    Great project!
    When I try to run this on a Duemilanove, the chip seems to continually reset after every few interrupts.

    Any idea what could cause this?

    Mark.

  • admin // Jan 19, 2010 at 10:31 am

    Ciao Mark,
    That seems to be a watchdog problem. Did you burn the Duemilanove bootloader yourself ? In case, check that you turned that off from the fuses.
    Best

  • Mark Arduino // Jan 19, 2010 at 5:43 pm

    Hi,

    Thanks for replying!
    I didn’t burn the bootloader myself.

    I have added a “wdt_disable()” call to the top of the “setup” function – but it doesn’t seem to make a difference.

    Is there anything else that needs to be done to disable the watchdog?

    Mark.

  • admin // Jan 20, 2010 at 10:19 am

    Mark,
    I really can’t say exactly. Did you copy my example pde and tried exactly that same ? Did you check if any updated development environment (the PC software) is available ? That could make a difference.
    The boot code that came with your Arduino should not matter.
    Bye for now.
    A.

  • admin // Jan 20, 2010 at 10:20 am

    Mark,
    almost forgot : try the good-old blinking LED demo to test the platform (and the Watchdog disable thing).
    Best, again.
    A.

  • Mark Arduino // Jan 23, 2010 at 9:31 pm

    Hi,

    Thanks for all the replies.
    I have figured out that the problem with the Arduino resetting is that instead of the “TIM0_COMPA_vect” ISR running when the timer match occurs the device was restetting – not sure why yet.

    Adding the following line to the top of the code solves the problem :-

    ISR_ALIAS(_vector_default, TIM0_COMPA_vect);

    A few questions :-

    1) Once you have 14 bits – why are you testing the data-word against 0×37C0? Is this to ensure that only RCU’s with address 0 will work? Why are you also masking the top bit of the command code?

    2) why do you have the “for(;;)” in the main loop – “loop” is called continually – so do you really need this?

    Mark.

  • admin // Jan 24, 2010 at 11:47 am

    Ciao Mark,
    great to know you solved the problem, thanks for sharing your solution also !
    Your assumption at 1) is correct except that – I’m going by heart here – I’m masking the toggle bit which could be 1 or 0.
    You are right also at 2). Just wanted to be the one to decide where and what should loop forever….
    Best regards
    Alessandro

  • Mark Arduino // Jan 24, 2010 at 1:06 pm

    Hi Alessandro,

    Thanks for replying.
    Been doing a little more digging and it seems that this may be a porting issue between the ATtiny24 and the ATmega168/328.

    For the ATmega168/328, the timer compare vector is defined as “TIMER0_COMPA_vect” and not “TIM0_COMPA_vect”.

    When an interrupt is received and no ISR can be found, the device will reset. I think this explains some of the issues others such as CaviaR and Matt Baker have been seeing.

    Mark.

  • admin // Jan 24, 2010 at 5:20 pm

    Mark,
    Ah, great find ! I’m adding a few lines in the post. I’m not correcting the pde though because I can’t test it now. Still have to understand how it could work on my STK500-Arduino or work for a few interrupts on other reader’s platforms and the Arduino DK compile it regularly.
    Again thank you a lot for sharing
    A presto (talk to you soon)
    Alessandro

Leave a Comment

Spam Protection by WP-SpamFree