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.

53 Responses to “Infrared remote control receiver for Arduino”

  1. Oscar G. says:

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

    Best regards,
    Oscar G.

    http://www.BricoGeek.com

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

  3. Mark says:

    What is the IR reciever device that you have used?

    Regards – Mark.

  4. admin says:

    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.

  5. [...] 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 [...]

  6. Tom says:

    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 ?

  7. admin says:

    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

  8. Marek says:

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

    Bye.

  9. Robin says:

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

  10. admin says:

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

  11. Antonio says:

    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.

  12. admin says:

    @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

  13. Antonio says:

    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

  14. admin says:

    @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

  15. Antonio says:

    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

  16. admin says:

    @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

  17. Antonio says:

    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

  18. admin says:

    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

  19. Antonio says:

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

    Antonio

  20. Angga says:

    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

  21. admin says:

    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

  22. Angga says:

    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

  23. thomas says:

    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

  24. Antonio says:

    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

  25. admin says:

    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 .

  26. Matt Baker says:

    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

  27. admin says:

    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

  28. Mark Farey says:

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

    Thanks,
    Mark.

  29. Mark Farey says:

    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);

  30. admin says:

    @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 ?

  31. Rodrigo says:

    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:

  32. admin says:

    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

  33. CaviaR says:

    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!

  34. admin says:

    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 …

  35. Mark Arduino says:

    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.

  36. admin says:

    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

  37. Mark Arduino says:

    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.

  38. admin says:

    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.

  39. admin says:

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

  40. Mark Arduino says:

    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.

  41. admin says:

    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

  42. Mark Arduino says:

    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.

  43. admin says:

    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

  44. on4tux says:

    I’m a real newbie (got my board yesterday :) ) but already playing with RC5 on my mega board. The code is not working, but I’m not sure if it is due to my IR controller (IRM38bl) which is active high? Only if it receives IR, the pulses make it go low.

  45. admin says:

    The IR receiver should be fine: to the datasheet your receiver is active low, not high. I mean : when 38kHz IR is received the output goes low. The same logic applies to the IR receivers I tried.
    Please read the comments and check if any of them helps you, otherwise please return. At this stage I can’ t help.
    Best regards

  46. Veli says:

    As a beginner I spent a lot of time with the rc5 stack from mikrocontroller.net triying to get it to work as an arduino sketch for a “quick” testing the TSOP4138 on Arduino Diecimila
    With your script, at first no LED went on, no serial output, “It cannot be that easy”, I thought, the highlight came with the oldest of my three remote controls (for some generic TV). It works! :D Thanks a lot.

  47. admin says:

    You’re welcome. Thanks for sharing !
    Best regards
    A.

  48. tom says:

    THANKS! I’ve been smashing my head against a desk for 3 days trying to get an ATTiny13 to understand any remote codes at all, I’ve modified this one to work!

    Again thanks!

  49. admin says:

    Thanks for sharing, Tom.
    I’m Happy this could help.
    Best regards
    A.

  50. Equinoxefr says:

    Hello,

    I tried this code on an arduino, it work’s like a charm. Thank’s !

    I would like to use it with attiny series (attiny 45 or 2313). How can i use it ? did you have some sample code ?

    Regard’s

    Pierre

Leave a Reply

(required)

(required)

Spam Protection by WP-SpamFree