Announcing a New Infrared Remote Control Library for Arduino

In April 2012 I begin work on a project to create an infrared remote control using an Arduino Uno. I downloaded a library of code called IRremote which was published by Ken Shirriff in his blog post here.
His library is available on at
It’s a remarkable piece of work that makes it incredibly easy to receive, decode, and transmit IR signals such as are used for TVs and other consumer electronics. It supported NEC, Sony, RC5 and RC6 protocols as well as a raw data mode and he later added a 32-bit hash code version. Note: so I don’t have to remember constantly have to spell “Shirriff” I’m going to refer to his original library as the KS library.

However I needed to add some additional protocols of my own. It took a lot of research from a variety of sites but I eventually found a pair of websites that will especially useful in helping me to understand the various protocols available.

One especially useful site is this one which I believe KS cites in his blog

However the one that had the most information is this one

It uses a notation called IRP notation that is insanely difficult to understand but once you do it is a very concise way of describing an IR protocol. I used that reference to determine that my Bright House cable boxes which are either Scientific-Atlanta or Cisco user protocol called “Panasonic old”. It also helped me identify NECx and Samsung36 protocols which I needed to implement for various devices I have.

After after adding several of these protocols to the original KS library I realize there was a lot of redundant code being created. Also the way it was written you either had to use all of the protocols at once or you had to create your own custom version in which you deleted or commented out the protocols you didn’t need. Although the code was written in C++ it really didn’t take advantage of object-oriented programming practices for which this application was especially suited. What we really needed was a variety of decoder objects based upon a base object that could be extended by additional protocols without having to modify or recompile the original library.

Also found it a bit difficult to understand what part of the code was hardware related dealing with timers and interrupts and PWM signals versus the encoding and decoding of protocols. Once you understand the protocols you really don’t need to know the hardware specifics. In many ways that’s the whole purpose of a library is to make things as “black box” as possible. The user doesn’t need to know the internal details, only the program interface.

For my own deeper understanding of the code and as a programming exercise I embarked upon a almost complete rewrite of the entire library using the principles of object-oriented programming. I am now ready to release my rewritten library on github for others to use. I did not created as a fork of the original KS library because the rewrite is so extensive that it really doesn’t work as a patch to the original code. I’ve also renamed it because it isn’t really very backward-compatible with the previous code at least from a software standpoint. If you have hardware configured for the previous library it should work out of the box with this library.

I also want to acknowledge the work of TKJ Electronics who have created a fork of the KS code. I use their version to obtain additional information about use of the library with other types of Arduino boards other than the standard Arduino Uno. This was especially helpful to me when I needed to point the code to the Arduino Leonardo especially since the Leonardo does not timer 2 and the pinouts are different. The timer and more detection information from this fork has been included in my rewritten library.

Because my library is such a major rewrite and is not backwards compatible I have given it a different name and have not created it as a fork of either of these two predecessor libraries. I have to acknowledge that this is my first publication of code using github and I really don’t know what the proper protocol is for creating a work based on someone else’s material. If I violated some custom or rule in the open source community please feel free to contact me and I will adjust the linkage of my github pages appropriately.

While much of the code is well documented and includes a variety of example sketches, my intent is to create a series of blog posts here which gives further explanation of how to use the library and explains in more detail some of the example sketches. I also hope to write a post explaining how to use the IRP notation. But for now I just want to get the code out there so that people can give me feedback and perhaps start using it themselves.

Here’s the link to my new library which I call “IRLib”

Here is a page where I link to all of my blog posts related to this library.

I welcome your feedback.

86 thoughts on “Announcing a New Infrared Remote Control Library for Arduino

  1. Hey Chris!
    Thanks for the library! I’m user (nomnom) from Arduino Forums….You linked me the library a few days back. It’s turned out to be quite helpful! It’s a pretty impressive library, too!

  2. Hello.

    I need help. I used both the old one and yours hoping to find a solution to my problem but unfortunately, my problem persist.

    When I press a button on any remote, Sony, Universal, cheap generic from China, etc., the same button dumps multiple codes instead of one. Thus, I cannot use any of the codes as it changes in every press.

    Please let me know if you can think of any solution.

    Thank you very much.


  3. The RC5 and RC6 protocols have a toggle bit changes back and forth every time you press a button. You said you get the same problem for even something like a Sony which typically is consistent. Note that Sony sends each code 3 times but it should still send consistent codes for a particular button press. Could you run the dump routine and email me the output from pressing the same button twice? Email it to my address at the bottom of this page.

    • hi. thanks for the response.

      i will try to send you the dump codes as soon as i get home.

      your help will be much appreciated.

  4. Hi.

    I already sent 2 files by email.

    1 for a Sony remote and another for the intended remote that I am planning to use.

    Thank you again for the help.

  5. i forgot to mention that i use a 2-legged IR receiver.

    i found in the forum that a 3-legged receiver is necessary as it can harness only in 38khz.

    that might be the reason why i am getting erratic readings.

    i’ll be getting one of those 3-legged receiver tomorrow and will try again. if it solves my problem, i’ll be using your library to create a menu for my home made Arduino for High Speed Photography.

    thank you very much and more power to you.

    • I think that is your problem. The three wire receiver actually has a bandpass filter incorporated in it that puts out a cleaner signal and eliminates interference from other kinds of IR. It only lets to the modulated signals that a remote produces. I got the files that you sent me and they were indeed quite random in nature. I was especially intrigued by the negative numbers. That means that the signal was so long it overflowed the timer which no regular remote would do. That meant it had to be something wrong with the receiver. Let me know how it works once you get the right device.

  6. Hey there,

    thanks for the great work on this library. I have the receiving part all figured out but somewhat the sending is not working for me. I got the IR LED connected together with a regular LED to pin9 of my Arduino Mega via a transistor and current limited to 100 mA as per my LED datasheet. However when I use IRRecord all of my devices don’t react to any of the codes I tried even though I can see the visible LED flashing. I also tried connecting different IR LEDs and also connected the IR LED directly to pin 9 with a resistor.
    Do you have any advice on what could be the issue? Did you ever try the code with an Arduino Mega?

    • I’m sorry I did not have a Mega to test the code. This library is based on a previous library by Ken Sherriff whose contact information is in the library and elsewhere in this blog. The parameters for the Mega are set in the file “IRLibTimer.h” which were copied directly out of the other library. I know of another guy who had trouble with a Mega but that was an interference between this library in the servo library causing his causing his server project to mess up. If you’ve not done so already, look at the following post regarding hardware setup. As far as I know pin 9 is the correct pin for the mega.

      • Thanks for the quick reply. I had a look at this and tried various hardware setups but somehow this thing does not like me (yet). I will try to give it a shot with an Arduino Uno tomorro.

      • So it turned out all is working well. Just the IR transmitter range is <1M even with the transistor.No clue why yet. The visible LED is blinking pretty bright.

        • Oh wow – as it turned out my USB port was just not strong enough for the high power LEDs. I now switched to an external power supply and things work well. Getting around 5-7m range. So AWESOME. Thanks

      • I don’t have a Mega or a Mega ADK to test the code. It may be that the ADK is using the default timer 2 for some other purpose. Take a look at IRLibTimer.h in the section for ATmega2560 and try using a different time or in different pin.

  7. I’ve worked with the IRremote library and it seems that a proper rewrite might be useful. I’ll have a look at your code later.

    Did you contact Ken about your rewrite and/or consider contributing your changes back into the IRremote library instead of creating a new library? Things get complicated for new users when there are multiple versions of a similar library around and development efforts are potentially wasted if they are spread over multiple similar libraries…

    • I’m sure Ken knows about my project. I did not create this project as a fork from his project because I wasn’t sure how to do that. It was my first and only experience with github. The rewrite is quite extensive and structural in nature. It’s not just a minor code cleanup work bug fix (didn’t really find many bugs). It really is a significantly different project. As with all open source projects is free to incorporate whatever he wants into his library. If he wants to restructure his in the way that I restructured mine is free to do so and then we might consider merging. Let me know how you like my rewrite.

  8. Is there anyway to change the IR Send LED? Ken’s Library is based on pin 3. I have a different version of Arduino called Induino which has inbuilt IR Transmitter and Reciever on Pins 13 and 14.
    This is the board I’m using.

    • Both my library and Ken’s allow you to use any digital input pin for reading IR signals. The code samples the input pin every 50us and it uses Timer 2 on an interrupt to do that sampling. For output however you have to use a PWM pin. Ken wrote his code in such a way to use Timer 2 to control not only the duty cycle but the frequency of the PWM pin. On the induino website you showed me, their sample code shows how you can “bit-bang” the output signal without using PWM. You could create a new send class that overrides (replaces) the IRsendBase::mark(int time) and void IRsendBase::space(int time) methods. Their sample code is hardcoded at 40 kHz. You would have to modify that using the parameter passed by “enableIRout (int khz)”. At some point I might try writing such code myself since it could be used on any Arduino type unit and give it the flexibility to use any output pin. However I have other projects in the works right now and do not have time to do that. If you do come up with working code, feel free to submit to my gethub page and I might incorporate it into a future version of the library.

  9. Hello Chris,

    Thanks for creating this amazing fork! I was pleasantly surprised at how easy it was to decode and receive IR signals using your library, examples, and blog posts.

    I’m working on an RGB LED controller using an Arduino Pro Mini, IRLib, and the also awesome Fast SPI LED library. Everything is working smashingly with the hardware remote I have, which came with an old Asus p5Wdh motherboard. IRLib indicates that it uses the NEC protocol.

    I’m having a bit of trouble with my next endeavor, which is adding these remote codes into an IR transmitter app for the Samsung Galaxy S4. The app allows custom codes to be entered but they must be in the Pronto hex format, and that specifically, is where I’m stuck. I’m not sure how to go from the hex code output by IRLib to the pronto format. Could you possibly nudge me in the right direction? Here is some example output generated by IRLib for the power button of the remote I’m using:

    Decoded NEC: Value:F7D02F (32 bits)
    Raw samples(68): Gap:47954
    Head: m8900 s4550
    0:m500 s650 1:m500 s600
    2:m500 s650 3:m450 s650
    4:m500 s600 5:m500 s650
    6:m450 s650 7:m500 s650
    8:m450 s1750 9:m500 s1750
    10:m500 s1750 11:m450 s1750
    12:m500 s650 13:m450 s1800
    14:m500 s1700 15:m500 s1750

    16:m500 s1750 17:m500 s1750
    18:m450 s650 19:m500 s1750
    20:m500 s600 21:m500 s650
    22:m450 s650 23:m500 s600
    24:m500 s650 25:m450 s650
    26:m500 s1750 27:m450 s650
    28:m500 s1750 29:m500 s1750
    30:m500 s1700 31:m550 s1750

    Mark min:450 max:550
    Space min:600 max:1800

    • I’m so sorry it’s taken me so long to reply to you. A number of people and asked for a way to convert my coding scheme into Pronto codes. Someone sent me a link to the specifications for the Pronto code but I haven’t had much chance to look at it in any detail. One of the problems is that if it’s an unknown protocol the Pronto version of it has to be able to detect the carrier frequency. The IR receiver chips that I use have been tuned to about 38 kHz although my experience is that even at 38 kHz they occasionally can recognize 56 kHz signals like those used on Scientific Atlantic/Cisco cable boxes. There is a different version of the IR receiver chip (partly I don’t know the part number right now) that give you the raw signal and does not include a bandpass filter nor does it include an auto gain control. If you use one of those chips as a receiver you can determine the frequency. There was a project on the crowd source funding site indigogo that is also linked here…

      Is a combination of a Windows application and a sketch for Arduino that allows you to do more detailed analysis of IR signals. They recommend using the unfiltered no gain control chip. They claim that using that chip in their software you can detect the frequency of a signal. One of the options on their program is to output Pronto codes based on the detected signal.

      Right now they are doing beta testing with their supporters. I don’t think it’s available for public purchase right now that you can check the link and contact them directly. They say that once the program is public they will allow the Arduino portion to be distributed freely. When that happens they have given me permission to try to incorporate their frequency detection methods into my IRLib. I’ve no idea how long that will take. I’ve got a lot of other projects lined up ahead of it.

      • Thank you for your detailed response! AnalysIR, looks really robust.

        For the time being, I’ve come up with a hacky workaround, which I thought I’d mention just in case someone else might benefit from it.

        Overview: In my sketch, each operation I want to execute will check for an IR code issued by either the phone or the hardware remote.

        Details: I’m using MakeHex along with a GUI to generate a list of NEC ProntoHex codes. I clean up the output for easier copy/paste and transfer the file to my phone. I use the SmartIR remote app, which allows me to manually enter the Pronto Hex codes, which I copy and paste into a custom button within the app. For example, I add the ProntoHex-formatted command “0”, which I will use to power on a device.

        Next, I fire the codes using the customized buttons in SmartIR Remote. Using the IR sensor attached to the arduino and the IRrecvDumpBasic sketch that comes with IRLib, I’m able to capture the codes as interpreted by the library. Finally, I simply run a check in my sketch to determine if either a button was pressed on my hardware remote or the phone, and execute the appropriate command.

        It’s a little bit lame, but it get’s the job done! 🙂

  10. Hi,
    First of, thank you for your hard work on the library. It takes me so much time to understand a little bit of KS library. I have a question, Can I use your IRLib to use 2 receivers to simultaneously receive 38 kHz signal from a single source? Can I use 2 timers 1 and 2 to control the 2 receivers?

    • Not sure why you would want to use two different receivers. If you did use two different receivers you might not need an additional timer. The timer just causes an interrupt every 50us and then the interrupt handler routine polls which ever pin you have the receiver connected to. You would have to modify the interrupt handler to poll both input pins and store the results in two different buffers. It would not be an easy task.

      I had thought about the possibility of trying to implement dual receivers because some IR signals around 38 kHz while others are as high as 56 kHz. Sometimes the bandpass filter on the 38 kHz receivers is wide enough that you can still get the 56 kHz signal to recognize when it would be nice to have dual receivers at different frequencies. I would think it would be easier to try to combine the signals about receivers using some sort of hardware solution perhaps a nand logic gate however I’m not a hardware expert. I mostly software.

  11. Hi, I use 2 IR receivers to control a turtle robot. I use bang-bang control to steer the robot left and right. I have modified the library code to use 2 receivers. But I having trouble with decode() function. Can I email you the modified version to take a look at it?

  12. Multiple receivers would be helpful as the is library does not handle these either and they can be helpful when searching for a beacon. Think three ir receivers one for left, one right, and one with a narrow center. You check all three to see which side the beacon is on, and then adjust course. Binary search for beacon lets you home in very quickly compared to a progressive sweeping scan. With only one receiver, the sweeping scan appears to be the only option.

    • I get the picture now as to why you might want multiple receivers. I still think there’s a hardware solution where somehow you merge the signals of all of the receivers. I’m tied up with some other projects right now but this is something I will definitely look into down the road.

  13. Thanks for this great work!
    Has anyone used this on a nano? The IRrecvDump sketch just continually pumps out blank results at a very rapid rate for me! (Same result on two nano’s both working fine on KS sketch).

    • I personally have not used in Arduino Nano however since it uses a 328 chip just like the Uno there’s no reason it shouldn’t work. It may be a question of pin numbers being different. I don’t have any experience but that would be the first place I would look. I have used it on an Adafruit Arduino Micro which uses the same chip as the Leonardo is about the same size as the Nano. What I would really like to do is get working on an ATtiny 85 chip so I could use it on an Adafruit Trinket or Adafruit Gemma or similar boards. Of course those chips run at 8 rather than 16 MHz and have different timers and interrupts so that’s going to cost me a lot of time poring over data sheets (which I’ve already proven not very good at).

        • I’ve gone back through the com output and it does actually capture the IR code. Just continually output blank captures inbetween. Tried with another ir reciever and same result yet all working fine on my nano.

  14. Hai, i used ken’s library, and i found that it’s not suited for my need. All i want is to send ir signals according to the pwm pin of my choice, does your library support such customization..?

    • You asked if you can use any PWM pin for output to send IR signals. The problem is that IR signals have to be modulated in a specific frequency. Most protocols use 38 kHz. Some use as low as 35 kHz or up to 56 kHz. There’s even one protocol used by high-end audio equipment from Bang and Olufsen that uses something like 400 kHz (I’m sorry I forget the exact number). The normal use of PWM pins on Arduino does not allow you to specify the modulation frequency. You can only specify the duty cycle of on versus off. My library allows you to use some different pins by changing which hardware timer that you use. The timer selection parameters are in the file IRLibTimer.h. I have seen some people write custom code that uses bit-bang code that can output to any pin. At some point I might try implementing that so that the code is less hardware dependent. I’ve already made a move away from hardware dependence with the new receiver classes which I created in the most recent release in late January. There are two new receiver methods one of which simply uses a tightly coded loop to poll any input can you specify. That gets you away from the dependence on interrupts and hardware timers and makes the code more portable.

  15. Ohh, good to know that you have been working on hardware independence. my main goal is to send IR signal from one to two pwm pins on arduino can this be possible. Where should i configure these pin no.s in IRLibTimer.h file.?

    • Take a look at that file and find the section for the particular kind of Arduino that you are using. For example if I’m using an Arduino Leonardo I would look of this section…

      #elif defined(__AVR_ATmega32U4__)
      #ifdef CORE_TEENSY
      // it’s Teensy 2.0
      //#define IR_USE_TIMER1 // tx = pin 14
      //#define IR_USE_TIMER3 // tx = pin 9
      #define IR_USE_TIMER4_HS // tx = pin 10
      // it’s probably Leonardo
      #define IR_USE_TIMER1 // tx = pin 9
      //#define IR_USE_TIMER3 // tx = pin 5
      //#define IR_USE_TIMER4_HS // tx = pin 13

      You can see that the default is IR_USE_TIMER1 in the Leonardo section and the comment tells you that it is pin 9 that you should connect to. If you want to use TIMER3 or TIMER4 you would use pins 5 or 13 respectively. We do not support TIMER0 because it is used by the built-in clock routines such as “delay()” etc. and there is no TIMER2 on the ATmega32U4 chip.

      You said in your comments you wanted to connect LEDs to “one or two PWM pins”. The library will only support one pin at a time and again only those that have the hardware timers associated with them. If you could give me an idea what your application is perhaps I could suggest some solutions. Why is it so important that you can only output from particular pins and why would you need more than one pin?

      • I would also like to connect IR LED’s to two PWM pins or more so that I could send the same IR signal to two different rooms in my house to control the same type air conditioner and only control one at a time. Is this possible?

        • My documentation shows a circuit for using multiple IR LEDs for output but it anticipates that the LED is mounted right on the circuit board or plugged into a prototype board of some kind. I really don’t know enough about electronics to know for certain if you ran extremely long wires (room to room) if it would degrade the signal or draw more current or what kinds of complications you might have. If I was going to do that I would have 2 separate Arduinos and try to connect them using Wi-Fi or X-Bee mesh radio. Take a look at my driver circuit hooks a really long wires on it and see what happens.

    • The library is mostly for 8-bit Atmel-based systems. The Teensy 3.0 and 3.1 both use core M4 advanced processors. You might be able to get the receiver portion working if you use the IRrecvLoop class introduced in the latest version of this library. Unlike the original IRrecv receiver class the new loop-based receiver doesn’t use any hardware interrupts or hardware timers except for the micros() built-in function. We created this to make it more hardware independent. We do not yet have a hardware independent version of the sending classes that you might be able to write your own if you do bit-bang instead of hardware timed PWM.

  16. Hi,
    What I am trying to do is to clone a remote I have that came with a small home theater system. The on button only works when it wants. I have used the KS library to decode my buttons, did a code that send the raw data. That works if when I tried to send the data one by one in a loop. What I want to do now is use another remote ( which I have already decoded the raw data on specific buttons for Power, Vol, Mute etc.) I want to be able to receive data from one remote and send via IR Led the translated data but it only works part of the time… I think it has to do with the timers and interrupts. I think I read somewhere that you cannot use the two of them at the same time, is this correct?

    • You can both send and receive but after sending you have to reenable receiving. Any of the send routines shut off the receiver interrupts. Take a look at the IRrecord sample sketch.

      • Thanks for the reply, I realize I can send and receive but I would like to have it done sort of simultaneously (a small delay would be acceptable). As I am pressing a button on the remote, the sketch would decode, and send a resulted raw signal to the IR Led to run the system I am trying to control. I tested your IRrecord sketch and I was able to record and send the recorded code via the serial monitor. I would like the sketch to send it automatically for me after I have pressed a button on the remote in the form of \” if (button pressed) { IRSend (xxx code);}\”. I understood how to decode raw data and send it with KS examples. I have not figured out how to send raw data with hour library. Is it possible to send raw data with your IRSendDemo sketch?

        • If I’m understanding you right what you want is sort of a relay system. I’m presuming that for some reason the transmitter on your Arduino is being used like an IR blaster perhaps in a location where your original remote can’t reach? There’s no problem doing that. You can send raw signals using IRsendRaw::send(unsigned int buf[], unsigned char len, unsigned char khz);

          Be sure you are using version 1.3 of my library which was uploaded a couple weeks ago. In older versions the raw data was stored as 50 µs ticks. Now the raw data is stored in actual number of microseconds and it makes it easier to pass the data onto the raw send routine.

  17. Hi Cy,
    I tested sending raw signal using IRsendRaw::send(unsigned int buf[], unsigned char len, unsigned char khz), it works at about every other IR blast if I use it in a loop using delay of a couple of seconds. I programmed it to send the Power Button code and at every second blast it turns on and at every other blasts it turns off. If I use in a sketch using IRreceive and IRsendRaw, I have to press the button on the remote 5 or 6 times to get the arduino to send the data that will turn on or off my device. What am I doing wrong? I have only been playing around with arduino for about a year and I am stronger at the hardware end of it then the programming. Can I send you my small sketch to see if you can see where I am going wrong?


      • Hi,
        I finally got it going, it all had to do with the placement of re enabling the receive. After I got it working, I used your switch case example of the Servo Control and it works great.


        • Hi Andrepit, I am encountering the same problems as you are. Any chance you can share the section of your code that shows the correct order for the re-enabling?

  18. Hi Chris,

    First of all; thank you very much for the library that you’ve made!! Very much appreciated!!
    I’ve been working now for a few months with Arduino and with some ‘trial-and-error’ getting more and more knowledge. I wanted to make a IR repeater and for two day’s I tried to modify KS example of ‘IRrecord’, but I was unable. Then I read about your library and in a few minutes it was working with a small modification in your ‘IRrecord’. So, I’m very happy with that! Thank you! Now I have two questions:

    1. I’m using an Arduino Uno and I tried to change the timer to 1. That worked and the IR is flashing when connected to pin 9, but only some of the signals are coming through. Do you know why? I only changed in IRLibTimer.h the following comment;

    // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
    #define IR_USE_TIMER1 // tx = pin 9
    //#define IR_USE_TIMER2 // tx = pin 3

    Is there anything else I should change? I would like to try to change the Timer because later on I will try to get it working on a Pololu Baby-Orangutan where Timer2 and Timer0 are already in use.

    2. I’ve used your library with decoding and sending, but do you know if an IR repeated could be made more simple than that. (without the library) Like digital or analog read the IR receiver and than send that signal direct to the IR led? I tried that, but it did not work for me. Basically, I want to send any light signal that the reciever gets to the IR led.

    Thank you for your help, you’re a blessing!

    • First of all I apologize for taking so long to reply to your message. Somehow your posting on my blog sort of got lost. I have things set up so that all comments have to be approved before going public. It cuts down on spam. I get an email notification every time a comment is posted but yours must have come on a very busy day. When I was recently going through some messages I noticed your message with pending.

      Unfortunately I cannot figure out why TIMER 1 on pin 9 would only work intermittently. I tested the code on Arduino Uno using both timer 1 and timer 2 and did not have any problems.

      One challenge of making a repeater without doing the actual decoding is that you would be required to transmit much more data. If you decode the data using my library or the KS library you need eight bits for the protocol number, 32 bits for the code, and another eight bits for the number of bits which is a total of six bytes or 48 bits. However if you tried to transmit raw data you would need at least a 16-bit number for each interval. If you have a 32 bit protocol requiring two intervals per bit plus a two interval header and a one interval trailer you’re talking at least 67 intervals or 134 bytes of data.

      Also if you are using the original IRrecv receiver it only samples the data every 50 microseconds so theoretically you can have as much as 99 micro seconds of error in the timing. That’s okay if you’re just decoding it. You can usually figure out the protocol. If you’re going to reproduce that error when retransmitting, the device you are trying to control may not have that much tolerance.

      Also keep in mind that different protocol use different modulation frequencies. Our raw send routine presumes 38 kHz because that’s a good average figure but what if you are using Old Panasonic which uses 56 kHz. Unless you’re going to measure frequency simultaneously with the raw data and transmit a frequency number as well you may have problems.

      While the new IRrecvPCI and IRrecvLoop receivers are more accurate, they have an entire set of limitations of their own.

      I’m hoping to come up with a way to measure both frequency and timing intervals simultaneously but that takes a lot of SRAM which limits what else you can do in the same sketch. We might be able to point off on an ATmega256 where there’s more RAM available but for general purpose, it’s going to be tough.

      I’m glad you did get some good use of my library. Good luck with your future projects.

  19. Great job there,
    The project that i am working on only requires decoding and producing a decoded output, I don’t even need to know the protocol. yours is a magnificent library with a lot of application, but my application does not need sending the codes, and most of the time i think the hash decoding will do.what i want to ask is , how can your library be stripped off so that it is just enough for
    *receiving the signal stream
    *decoding the received signal
    * generating a decoded numerical result
    all of this while compiling and taking up smallest space on my chip.
    I want or run your library on an attiny85 or more preferably attiny45.

    • You would need to create one instance of one of the receiver classes such as IRrecv and the IRdecodeHash decoder. The linking loader will not create an instance of any of the other code such as the sending routines as long as you don’t make any reference to them. Also if you do not need the text dump routines there is a define that you can comment out which would reduce your code size slightly further. But the bottom line is it should be able to do what you want it to do.

  20. Cy:

    Thanks for the incredible work on your IRLib library.
    I used your DirecTV demo to decode the remote signals from my DirecTV RC66 remote. The results came in hex format…is there an IRSend sketch handy specific for the DirecTV case that I could refer to as an example? If not could you send me a sample of an IRSend statement that would be appropriate for the DirecTV protocol? I am trying to set up an Arduino-based bluetooth remote system that will send DirecTV remote signals via bluetooth to the Arduino which will in turn operate my DirecTV HR24 receiver. The project is based on a couple of instructables for remotes I found on One of the projects also incorporates voice recognition. Thanks for your time!

    • There is an IRsendDirecTV routine in the example sketch. Make sure you have the latest version of the library however I think in that particular example there always has been a send routine. It sounds like an interesting project. Send me a link if you got a blog post or something describing it. Also stop by the Wednesday night Adafruit show-and-tell video chat on Google+ if you have a WebCam. Show it off when you get it done.

      • Hmmm I guess I am not understanding how your DirecTVDemo example is working (I have the latest version of your library and I do not see a separate IRSend demo example for DirecTV). Does the sketch record my button presses automatically? So once the demo sketch was uploaded to my Arduino I would press all 41 buttons on my remote and after the last button press save the sketch under another name and then reupload to my Arduino? Prior to running across your library I was using a custom Android app to send text corresponding to each button via bluetooth and the Arduino sketch would then associate the transmitted text to a particular remote command. Unfortunately I have not been able to get this to work with Ken Shirriff’s library since his IRRec function does not understand the DirecTV protocol and my attempts to use Ken’s sendRaw function has not worked for me to date.

        • The way the example sketch works is you upload the sketch using the Arduino IDE and when it has completed uploading, you open the serial monitor. Then you point your remote at the receiver and send a signal. If it recognizes the signal it records it. Then you type any character into the serial monitor command line and it will resend whatever code it had most recently received from you. The IRsendDirecTV routine is about line 98. We do plan to eventually support Pronto HEX format but it could be quite some time before we get around to it. It’s really not a very efficient way of storing or sending codes and would only be used if you had a protocol that wasn’t supported by the library.

  21. Hi there
    It seems you have a great library 🙂 well done !
    Please could you tell me how to or provide and example of how to capture multiple keypresses ?
    Like entering a number into a calculator or phone 1234 etc and then the # button completes the input.
    I would like to light and LED as i enter 123#

    Thanks a million

    • I’m happy to answer any questions directly related to the library. But that’s just a basic programming question. It doesn’t really have anything to do with IR or with my library. I want to be helpful but I’m not here to teach people how to program. I’m sorry if that sounds blunt or rude because I don’t mean it to be.

  22. Thanks for your effort!

    I’ll be waiting for your tutorial part 3 where you explain adding protocols. I am trying to control the volume on an RCA Home Theater but because you do not support RCA, the codes are shown as unknown. I can get the raw data, but I’m not deft enough to figure out how to send it. I thought I could do it with Shirriff’s library, but couldn’t get it to work. I have some info that says RCA uses 56kHz carrier. I hope you will discuss that in your tutorial.

    Thanks again

  23. Cy, thanks for the library!

    I used both yours and the original one, and it seems that they both fill up pins 3 and 11, making them unaccessible. You can get readings from some other pin (even A0), but it doesn’t free pin 11, and if you try to use it while receiving IR from other pin, it either hangs the device or makes the readings incomprehendible. I tried it with send-only mode, pin 11 still works rather strange (no PWM). It’s a shame, really, as you’re left with only 4 PWM outputs on Uno…

    Well, the questions are (sorry if they’re lame, as I’m new to both Arduino and c/c++):
    – is it possible to totally separate sending and receiving stuff into two libraries? I think you use only one mode in 90% cases, as you either want to control your Arduino contraption with IR or to control something else with Arduino. It should definitely free one of the pins, no?
    – why is pin 11 behaving thus? It’s not connected to ISR according to documentation, but the behavior suggests that it is. Can it be some legacy code in the library that definitely does something to the pin 11, regardless of what pin was declared as the receiving one?
    – why is pin 3 used for sending? In my opinion, sending does not require interrupts, as it’s pro-active action initiated by the code and not some external event (even if it’s just a relay). But still both libraries tend to definitely take one of two ISRs out of use even if you don’t try to receive anything…

    Again, I’m new to this, so sorry if my questions sound lame. Will be glad to hear the answer.


    • I’ve been going through a process to try to make the library less hardware dependent. The process is incomplete but I think most of the issues you raised can be resolved.

      When receiving signals using the IRRecv class, it defaults to hardware interrupt TIMER 2 to create a 50 µs interrupt to sample the input pin. You can choose any input pin you want for that class or for the IRRecvLoop class. There are options to change which hardware timer is used if there is a conflict with other libraries or hardware devices. The options for changing timers are in the header file “IRLibTimer.h”. The library also always installs an ISR routine whether you are using hardware interrupts or not. For example if you’re using the IRRecvLoop receiver class do not need interrupts at all or as you mentioned if you’re not doing receiving but only sending you do not need interrupts. To disable the default ISR routine there is an option in IRLib.h at about line 46 that is #define USE_IRRECV that if you comment it out, then the ISR is not defined.

      Because hardware timers and hardware interrupts are restricted to using certain pins, you cannot change the pin numbers without using a different timer.

      When sending signals, the output has to be modulated at about 38 kHz. It can range anywhere from 36 kHz to 58 kHz but most use 38. In any case, a hardware timer has to be used in conjunction with a PWM pin in order to generate this modulation. We have attempted an alternative to using hardware timers. We tried to create a software loop to generate this modulated frequency but have only had mixed results. It’s hard to get a software loop to toggle the bits using bit-bang at the right frequency. Also if there is any other interrupt activity going on, it causes the software loop to get out of time while the extra interrupts are being processed and in the end the signal is corrupted. So the only reliable way to generate that modulated frequency is by using a hardware timer and that restricts you to certain pins and using up the limited resource of timer circuitry.

      We’re trying to find an inexpensive hardware solution to modulating the output frequency. There are programmable frequency generators that use I2C interface that might be a possible solution but they can add only to your hardware costs. I’m looking at the possibility of creating an IR modulator out of an ATtiny 85 system such as an Adafruit Trinket that only costs about $7. But I just haven’t had the time to implement that yet.

      The bottom line is if you are receiving only, and do not create an instance of any of the send classes, then you should not have any conflicts with the sending routine. If you are sending only, you can use that define to get rid of the ISR definition and of course do not create any instances of receiver classes and that will free you up from any conflicts there.

      Your questions are not lame. They’re just complicated by the limitations of the hardware.

  24. Thanks for the comprehensive answer! It seems that you use the original IRrecv method that was used in Ken Shirriff’s library, and it uses a timer hardwired to pin 11. Thus it’s unavailability.

    In any case, your library provides an excellent solution called IRrecvPCI.

    The good news: if you use interrupt 0 (pin 2), you get all PWMs, including 3 and 11, totally free for any use. If you use 1 (pin 3), you get 11-th and 2-nd pins. It was actually rather important for my project, as I used a different library that relies on pin 11 due to it’s involvement in Slave/Master processess. Great!

    Bad news are present in your manual – IRrecvPCI is prototype and doesn’t guarantee exact results. With LG TV remote (NEC protocol) I get an acceptable error rate of 10%. It’s great for me, as I intended to use this remote for my project. But with Philips remote (RC6) the error rate goes up to 90%. In fact, PCI method doesn’t provide errors itself, it just increases their likeability. NEC protocol gets about 5% errors in normal mode (on pin 11), RC6 gets less than 50% correct results there. Actually, I now understand why my home theater is reacting so badly to it’s own remote, I thought it was due to some clatter or distance, but in fact it’s the problem with either the protocol itself or the remote.

    So, again, thanks a lot for your library – it provided the answer I needed! And I do hope to get a look at the newer version.

  25. hi, thanks a lot for answers, but i like to send and recive with the protocole Samsung36 (Samsung36Irsend and Samsung36Irrecive) but i can\’t , i looked for documentation but i nothing found i surch tutorial a found this tutorial but the IRsend don\’t work ,; this is the cod e, please help me void IRsendSamsung36::PutBits (unsigned long data, int nbits){ for (int i = 0; i < nbits; i++) { if (data & 0x80000000) { mark(500); space(1500); } else { mark(500); space(500); }; data <<= 1; } } void IRsendSamsung36::send(unsigned long data, unsigned long data2) { data <<= 32-20; data2 <<= 32-16; enableIROut(38); mark(4500); space(4500);//Send header PutBits (data2, 16);//Send data2 16 bits mark (500); space (4500);//Send break PutBits (data, 12);//Send 12 bits space(68);//Send tiny break data <<= 12; PutBits (data, 8);mark(500); //Final eight bits and one stop bit space(118*500);//Lead out is 118 times the base time 500 };

    • Don’t use the “PutBits” method. Use the “send” method. Also note that that is not the most recent version of the library. You should always get the most recent version at

      Also are you certain that your device uses Samsung36 protocol? Not all Samsung devices use that protocol. Many use NEC or NECx protocol.

      • I’am Certain that i use the Samsung36 protocol and I’am using the last version of the library (1.5) , and why i bon’t have to use the PutBits and what i should write then in her place ?

    • I’ve heard something about someone doing IR the ESP 8266 but I don’t know if it was my library or perhaps the one from Ken Shirriff. I recently got one of the boards and it’s on my things to do list but I’ve been preoccupied with 3-D printing and other projects. Everything related to IR is on hold right now.

  26. I’m trying to get an IR signal out of an adafruit gemma with no luck using KS’s library. I know it isn’t the hardware because I can get the signal to work using a duemilanove. Does your library support the gemma? I must be missing something on the translation from one board to the other.

    • The Gemma uses the ATtiny 85 processor however I do not support that processor at this time. I was pretty sure that KS’s library did. Make sure that you have it configured for the ATtiny 85. Also make sure that the system clock variable is set properly. I believe the Gemma runs at 8 MHz instead of 16. I’m not sure what pin number you need to connect to as well. Also note that because it is such a small capacity in terms of RAM and ROM you might have to comment out parts of the library you are using to get it all to fit.

  27. Greetings,

    Thank you for this awesome library. I have not used it yet, as I am trying to find a solution that I haven’t yet found with the KS IRremote Lib. I have a Pioneer Stereo Receiver that uses the NEC protocol. However, some of the commands are actually two 32 Bit codes spaced closely together, for example INPUT ATT = 0xA55A7A85 0xA55AE01F # toggle analog input attenuation. I can receive this just fine using KS’s library (after some cleanup of my code… just a few Serial.println() will slow it down enough not to receive the second segment). But, I can’t seem to send it, no matter how quickly or closely I space the two send commands, the receiver will not respond.

    Does your library account for these? Initially I thought they were NEC extended, but now I’m not so sure. I’m pretty new to all of this!

    Thank you again.

  28. Hello Chris!

    For some reason my previous comment seems to have been moderated out… I have now loaded up your library and run it. It looks much easier to navigate and understand than the IRremote internal workings, however I have a problem. When I use my Pioneer Stereo Remote, which is decoded with no problem by the IRremote library, the IRLib decoder shows it as “Unknown” with 0 bytes of data. However, when I use my Universal remote from the cable company, which I’ve programmed to control the Pioneer, it works fine with IRLib, showing Decoded NEC(1): Value:A55A50AF (32 bits). It almost looks to me like the tolerances are too tight for my actual Pioneer remote to be decoded, but the Universal Cable box remote is fine. Could this be the case? Any ideas?

    My other question, from my previous post, was that I’m wondering if there is any way to handle the double codes that some remotes output, specifically my Pioneer remote uses Two 32 bit codes for several functions, for example: inputatt 0xA55A7A85 0xA55AE01F (# toggle analog input attenuation). I haven’t been able to make them work with the IRremote library, and so far am unable to test how they are decoded and re-transmitted by your library because my NEC remote is not decoding properly with IRLib. With IRremote I’ve tried sending the two codes as close together as possible, but I’m unable to get the stereo to react to the double code.

    Thank you so much for the time you’ve put into this project!


    • All comments on this blog have to be approved before they go live. There’s too much spam on the Internet. Sorry I didn’t get around to approve your comment sooner. I don’t have time to write a longer reply now but I will get back to you.

      • cy,

        Thank you, and I did not mean to rush you! I just didn’t realize how the thread worked, I guess. I had an idea this morning that maybe the batteries in my Pioneer remote were failing, and that maybe was the issue (that for some reason the output was outside of IRLib’s tolerances, but still within IRremote’s). But, I changed the batteries, and the remote still does not work with IRLib. I have the IRanalyze output for both the Universal remote and the Pioneer remote, 15 samples each, if you’d like me to send. Thank you.

        • Check out the IRrecvDump example in my library. Because it uses an external buffer and re-enables receiving before it begins decoding it is good for capturing two consecutive signals quickly. I have some reference material which unfortunately is no longer online but fortunately I made a copy for myself before it disappeared. It says that Pioneer uses a variant of NEC called NEC2. The only difference between traditional NEC and NEC2 is that it doesn’t use the strange repeat codes that NEC uses. My reference material also says that Pioneer often uses two consecutive codes like you are seeing. It also says that Pioneer uses 40 kHz instead of 38 kHz. I would think that the frequencies are close enough that it wouldn’t matter might try editing my NEC code to change the frequency. Just a copy of the NEC code and make the following changes.

          void IRsendPioneer::send(unsigned long data) //would lead to make appropriate changes in the header file as well
          // if (data==REPEAT) { //pioneer does not use specialized repeat so eliminate it
          // enableIROut(38);
          // mark (564* 16); space(564*4); mark(564);space(56*173);
          // }
          //else {
          sendGeneric(data,32, 564*16, 564*8, 564, 564, 564*3, 564, 40 /* 38*/, true);//change frequency to 40 instead of 38
          delay(564*78/1000);//this delay probably should’ve been in my library but isn’t. I explain below.
          // }

          The official definition for NEC and played Pioneer says that there should be 78 base units of empty space after each code. In the vast majority of cases the amount of wait after sending your code is irrelevant so I never implemented it. The base time unit in this protocol is 564 µs so the delay should be 564 times that and then divide by 1000 to get milliseconds. There is a possibility that the only problem you are seeing is because of the change in frequency. You might not need to put this gap between the codes. Or perhaps just putting the gap and not changing the frequency would get it to work although I believe you said you had tried various gaps.

          Using my dump routine look at the “gap” reported in the second of the paired codes. That tells you the number of microseconds since the end of the last received code. My guess is it will be in the neighborhood of 44,000 if my specifications are correct. That means you would want a delay (44) between the codes.

          So anyway try changing the frequency and then play around with that delay and see what you come up with. Let me know how it turns out.
          Chris Young

  29. Thanks for the great library. I was able to get it up and running in a simple sketch pretty quickly.
    In my application (on an Arduino Nano), I need to use a remote to control some NeoPixels. But when I added the code for the NeoPixels, pressing a button on the remote causes the Arduino to reset, running the setup() function.
    The NeoPixel library doesn’t use any of the Timers from what I can see.
    My application will require the use of one of the timers in order to animate the NeoPixels. From what I could see in the code, it appears that the IR code uses Timer2, so I’m planning on using Timer1.
    I realize that it might be a memory issue. Is there a way to determine how much local variable memory the IRLib needs?
    Lastly, is there a way to remove/disable all of the send code? I only need to receive.
    Again, thanks for all the hard work you’ve put into your code!

    • It sounds to me like perhaps a power issue. Can you run the NeoPixels without my library and the IR code loaded? Running an Arduino off of a usual USB often is not sufficient to light up a bunch of pixels. There should be no conflict between my library and the NeoPixel code. Lots of people have used it successfully. There is no need to disable sending code in the library. If it is unused, the linking loader will get rid of it. If you have an application that sends but does not receive then there are defines in my library that allow you to disable the receiving code. The receiving code uses several global variables and ISR that the linking loader does not remove if unused. But there is nothing in sending that the loader can’t unload. Or rather that the loader will not load when you don’t need it. Here is some code I use occasionally to see how much free RAM I have although the Arduino IDE most recent versions does a pretty good job of reporting memory usage.

      void ShowFreeRam(void) {
      extern int __bss_end; extern int* __brkval; int free_memory;
      if (reinterpret_cast(__brkval) == 0)
      free_memory = reinterpret_cast
      (&free_memory) - reinterpret_cast(&__bss_end);
      free_memory = reinterpret_cast
      (&free_memory) - reinterpret_cast(__brkval);
      Serial.print(F("Free:")); Serial.print(free_memory, DEC);

      • Thanks Cy for the quick reply.
        The board does run a sketch with just the NeoPixel code, but I did try using an external power supply, and it no longer resets. The difference is that the stand-alone (no IR code) program was setting the brightness to a lower value. There are only 20 NeoPixels, so I didn’t think that would be the problem. Good catch!

        Regarding the RAM usage, I do use the IDE to show the total RAM usage, and after globals, I only have 409 bytes left (1639 used for globals. I was wondering if that is enough leeway for your library. I will also try to figure out if that’s enough for the other libs (NeoPixel and Serial).
        Thanks for the answers and a great library! I’ve learned a lot looking through the code.

  30. Hi Cy,

    I have the code working with the NeoPixels and have the power issue resolved. It’s still a bit inconsistant on reading (reads a zero occasionally). I think it is a timing issue because I’m sending out to a lot of pixels and doing the calculations frequently. In any case, it’s close enough for now.

    I tried to use the tone/notone functions and of course ran into the issue with the timer2 conflict. I’m using timer1 so I can’t switch the IR lib to that timer. I’m not using any of the send functions of the IR lib. Can I just comment out the code in the lib that references timer2?

  31. In the users guide distributed with the library check out section 1.4.2 Changing Defaults. I would send you a link to the webpage but unfortunately the webpage version of my documentation is not 100% up-to-date with what was distributed in the Manuals folder of the code distribution.

    • Now that I think about it, I seem to recall someone else had a problem with tone. I think there’s something about the way it’s implemented that it actually takes over all of the timers. You could try using the PCI version of my receiver object or try one of these alternatives to the tone library. Here is a link to one that uses no timers but the same guy has written other versions that might work as well.

  32. I was looking for a library for my IR project.
    Need to send RC6-6-32 codes.

    I was frustrated since all other libs that I had found could not deal with that properly.

    Wanted to give up but searched many hours till I found your lib here which works like a charm.

    Thank you very much for your work !!!

    Regards Martin

    • I’m glad to hear it works for you. If you have an article without your project, post a link or give me a brief description. I was always curious what people are doing with my code.

  33. I had a SAT-receiver for many years brand XTREND.
    The layout of the remote-control is very logical and it’s a pleasure to use.

    For technical reasons I bought another receiver brand VU+
    The layout of this rc is a real mess …

    So I wanted to use XTREND rc for VU+ receiver.
    Xtrend sends NEC-24bit codes but VU+ uses RC6-6-32

    So I built up a little “translator” with Arduino Nano.
    USB powered and works very well …

    Code is real simple.
    Receive NEC-Code – translate – send RC6 code (consider toggle bit)

    The problem was to send RC6-6-32 with those other libs which did not work.
    Sending RAW-codes was not an option due to memory limitations (48 buttons …)

Leave a Reply

Your email address will not be published. Required fields are marked *