A Multi-Protocol Infrared Remote Library for the Arduino

Code now on github

Do you want to control your Arduino with an IR remote? Do you want to use your Arduino to control
your stereo or other devices? This IR remote library lets you both send and receive IR remote codes
in multiple protocols. It supports NEC, Sony SIRC, Philips RC5,
Philips RC6, and raw protocols. If you want additional protocols, they are straightforward to add.
The library can even be used to record codes from your remote and re-transmit them,
as a minimal universal remote.

To use the library, download from github and follow the installation instructions in the readme.

How to send

This infrared remote library consists of two parts: IRsend transmits IR remote packets, while IRrecv receives and decodes an IR message.
IRsend uses an infrared LED connected to output pin 3. To send a message, call the send method for the desired protocol with the data to send and the number of bits to send. The examples/IRsendDemo sketch provides a simple example of how to send codes:

This sketch sends a Sony TV power on/off code whenever a character is sent to the serial port, allowing the Arduino to turn the TV on or off. (Note that Sony codes must be sent 3 times according to the protocol.)

How to receive

IRrecv uses an infrared detector connected to any digital input pin.

The examples/IRrecvDemo sketch provides a simple example of how to receive codes:

The IRrecv class performs the decoding, and is initialized with enableIRIn(). The decode() method is called to see if a code has been received; if so, it returns a nonzero value and puts the results into the decode_results structure. (For details of this structure, see the examples/IRrecvDump sketch.) Once a code has been decoded, the resume() method must be called to resume receiving codes. Note that decode() does not block; the sketch can perform other operations while waiting for a code because the codes are received by an interrupt routine.

Hardware setup

The library can use any of the digital input signals to receive the input from a 38KHz IR receiver module. It has been
tested with the Radio Shack 276-640 IR receiver and the Panasonic PNA4602. Simply wire power to pin 1, ground to pin 2, and the pin 3 output to an Arduino digital input pin, e.g. 11. These receivers provide a filtered and demodulated inverted logic level output; you can't just use a photodiode or phototransistor. I have found these detectors have pretty good range and easily work across a room.

For output, connect an IR LED and appropriate resistor to PWM output pin 3. Make sure the polarity of the LED is correct, or it won't illuminate - the long lead is positive. I used a NTE 3027 LED (because that's what was
handy) and 100 ohm resistor; the range is about 15 feet. For additional range, you can amplify the output with a transistor.

Some background on IR codes

An IR remote works by turning the LED on and off in a particular pattern. However, to prevent
inteference from IR sources such as sunlight or lights, the LED is not turned on steadily, but is
turned on and off at a modulation frequency (typically 36, 38, or 40KHz). The time when a modulated
signal is being sent will be called a mark, and when the LED is off will be called a space.

Each key on the remote has a particular code (typically 12 to 32 bits) associated with it, and broadcasts
this code when the key is pressed. If the key is held down, the remote usually repeatedly broadcasts the
key code. For an NEC remote, a special repeat code is sent as the key is held down, rather than repeatedly
sending the code. For Philips RC5 or RC6 remotes, a bit in the code is toggled each time a key is pressed;
the receiver uses this toggle bit to determine when a key is pressed down a second time.

On the receiving end, the IR detector demodulates this signal, and outputs a logic-level signal indicating if it is
receiving a signal or not. The IR detector will work best when its frequency matches the sender's frequency,
but in practice it doesn't matter a whole lot.

Handling raw codes

The library provides support for sending and receiving raw durations. This is intended mainly for debugging, but can also be used for protocols the library doesn't implement, or to provide universal remote functionality.

The raw data for received IR measures the duration of successive spaces and marks in 50us ticks. The first measurement is the gap, the space before the transmission starts. The last measurement is the final mark.

The raw data for sending IR holds the duration of successive marks and spaces in microseconds. The first value is the first mark, and the last value is the last mark.

There are two differences between the raw buffers for sending and for receiving. The send buffer values are in microseconds, while the receive buffer values are in 50 microsecond ticks. The send buffer starts with the duration of the first mark, while the receive buffer starts with the duration of the gap space before the first mark. The formats are different because I considered it useful for the library to measure gaps between transmissions, but not useful for the library to provide these gaps when transmitting. For receiving, 50us granularity is sufficient for decoding and avoids overflow of the gaps, while for transmitting, 50us granularity is more than 10% error so 1us granularity seemed better.

Obtaining codes for your remote

The easiest way to obtain codes to work with your device is to use this library to decode and print
the codes from your existing remote.

Various libraries of codes are available online, often in proprietary formats. The Linux Infrared
Remote Control project (LIRC), however, has
an open format for describing codes for many remotes. Note that even if you can't find codes for your
exact device model, a particular manufacturer will usually use the same codes for multiple products.

Beware that other sources may be inconsistent in how they handle these protocols, for instance reversing the order, flipping 1 and 0 bits, making start bits explicit, dropping leading or trailing bits, etc. In other words, if the IRremote library yields different codes than you find listed elsewhere, these inconsistencies are probably why.

Details of the receiving library

The IRrecv library consists of two parts. An interrupt routine is called every 50 microseconds, measures
the length of the marks and spaces, and saves the durations in a buffer. The user calls a decoding routine
to decode the buffered measurements into the code value that was sent (typically 11 to 32 bits).

The decode library tries decoding different protocols in succession, stopping if one succeeds. It returns
a structure that contains the raw data, the decoded data, the number of bits in the decoded data,
and the protocol used to decode the data.

For decoding, the MATCH macro determine if the measured mark or space time is approximately equal to
the expected time.

The RC5/6 decoding is a bit different from the others because RC5/6 encode bits with mark + space or
space + mark, rather than by durations of marks and spaces. The getRClevel helper method splits up
the durations and gets the mark/space level of a single time interval.

For repeated transmissions (button held down), the decoding code will return the same decoded value over and over. The exception is NEC, which sends a special repeat code instead of repeating the transmission of the value. In this
case, the decode routine returns a special REPEAT value.

In more detail, the receiver's interrupt code is called every time the TIMER1 overflows, which is set to happen after 50 microseconds. At each interrupt, the input status is checked and the timer counter is incremented.
The interrupt routine times the durations of marks (receiving a modulated signal) and
spaces (no signal received), and records the durations in a buffer. The first duration is the length
of the gap before the transmission starts. This is followed by alternating mark and space measurements.
All measurements are in "ticks" of 50 microseconds.

The interrupt routine is implemented as a state machine. It starts in STATE_IDLE, which waits for the gap
to end. When a mark is received, it moves to STATE_MARK which times the duration of the mark.
It then alternates between STATE_MARK and STATE_SPACE to time marks and spaces. When a space of
sufficiently long duration is received, the state moves to STATE_STOP, indicating a full transmission is
received. The interrupt routine continues to time the gap, but blocks in this state.

The STATE_STOP is used a a flag to indicate to the decode routine that a full transmission is available.
When processing is done, the resume() method sets the state to STATE_IDLE so the interrupt routine can
start recording the next transmission. There are a few things to note here. Gap timing continues
during STATE_STOP and STATE_IDLE so an accurate measurement of the time between transmissions can
be obtained. If resume() is not called before the next transmission starts, the partial transmission will be discarded.
The motivation behind the stop/resume is to ensure the receive buffer is not overwritten while it is
still being processed; debugging becomes very difficult if the buffer is constantly changing.

Details of the sending library

The transmission code is straightforward. To ensure accurate output frequencies and duty cycles, I use the PWM timer, rather than delay loops to modulate the output LED at the appropriate frequency. (See my Arduino PWM Secrets article for more details on the PWM timers.)
At the low level, enableIROut sets up the timer for PWM output on pin 3 at
the proper frequency. The mark() method sends a mark by enabling PWM output and delaying the specified time. The
space() method sends a space by disabling PWM output and delaying the specified time.

Sony: 12 or more bits are transmitted, most-significant bit first. Typically 12 or 20 bits are used. Note that the official protocol is least-significant bit first. (protocol details) For more details, I've written an article that describes the Sony protocol in much more detail: Understanding Sony IR remote codes.

RC5: 12 or more bits are transmitted most-significant bit first. The message starts with the two start bits,
which are not part of the code values. (protocol details)

RC6: 20 (typically) bits are transmitted, most-significant bit first. The message starts with a leader pulse, and a start bit,
which is not part of the code values.
The fourth bit is transmitted double-wide, since it is the trailer bit. (protocol details)

For Sony and RC5/6, each
transmission must be repeated 3 times as specified in the protocol. The transmission code does not
implement the RC5/6 toggle bit; that is up to the caller.

Adding new protocols

Manufacturers have implemented many more protocols than this library supports. Adding new protocols should
be straightforward if you look at the existing library code. A few tips: It will be easier to work with
a description of the protocol rather than trying to entirely reverse-engineer the protocol. The durations you receive are likely to
be longer for marks and shorter for spaces than the protocol suggests.
It's easy to be off-by-one with the last bit; the last space may be implicit.

Troubleshooting

To make it easier to debug problems with IR communication, I have optional debugging code in the library. Add #define DEBUG to the beginning of your code to enable debugging output on the serial console. You will need to delete the .o files and/or restart the IDE to force recompilation.

Problems with Transmission

If sending isn't working, first make sure your IR LED is actually transmitting. IR will usually show up on a video camera or cell phone camera, so this is a simple way to check. Try putting the LED right up to the receiver; don't expect a lot of range unless you amplify the output.

The next potential problem is if the receiver doesn't understand the transmitter, for instance if you are sending the wrong data or using the wrong protocol. If you have a remote, use this library to check what data it is sending and what protocol it is using.

An oscilloscope will provide a good view of what the Arduino or a remote is transmitting. You can use an IR photodiode to see what is getting transmitted; connect it directly to the oscilloscope and hold the
transmitter right up to the photodiode. If you have an oscilloscope, just
connect the oscilloscope to the photodiode. If you don't have an oscilloscope, you can
use a sound card oscilloscope program such as xoscope.

The Sony and RC5/6 protocols specify that messages must be sent three times. I have found that receivers will ignore the message if only sent once, but will work if it is sent twice. For RC5/6, the toggle bit must be flipped by the calling code in successive transmissions, or else the
receiver may only respond to a code once.

Finally, there may be bugs in this library. In particular, I don't have anything that receives RC5/RC6,
so they are untested.

Problems with Receiving

If receiving isn't working, first make sure the Arduino is at least receiving raw codes. The LED
on pin 13 of the Arduino will blink when IR is being received. If not,
then there's probably a hardware issue.

If the codes are getting received but cannot be decoded, make sure the codes are in one of the supported protocols. If codes should be getting decoded, but are not,
some of the measured times are probably not within the 20% tolerance of the expected times. You can
print out the minimum and maximum expected values and compare with the raw measured values.

The examples/IRrecvDump sketch will dump out details of the received data. The dump method dumps out these durations but converts them to microseconds, and uses the convention of prefixing a space measurement with a minus sign. This makes it easier to keep the mark and space measurements straight.

IR sensors typically cause the mark to be measured as longer than expected and the space to be shorter
than expected. The code extends marks by 100us to account for this (the value MARK_EXCESS). You may need to tweak the expected values or tolerances in this case.

The library does not support simultaneous sending and receiving of codes; transmitting will disable receiving.

Thanks for the library!I'm trying to use the example IRrecord.pde.Everything works fine on a superficial level: the elctronic circuit is ok, I'm receiving the infrared data from the remote control of a sat decoder box and I'm printing it on the serial window... Then when I try to play it back nothings happens (I'm not able to trigger the satellite decoder with my IR led from the arduino). If I look at the ir led with my camera I see it pulsing... so my question is: since the library is sampling the ir signal from the remote control with a resolution of 50microseconds, is it possible that the raw data recorded is not usable for the playback of the same signal? Would it be possible to increase the sampling resolution?

Hi.I really like this project. Thank you very much. It helps me a lot.But I have one problem. Everything works, except sending the IR pulse.Neither in the example IRrecord nor with IRsendDemo.There´s no output at the PWM pin 3. I´ve tested it with a camera, a LED instead of the IR-diode and the oscilloscope. There´s definitely no signal.First i mentioned there´s something wrong with the sourcecode. But it´s programmed really sophisticated and i couldn´t find a mistake, though i consider myself a quite acceptable programmer.Sorry for self-praise.But Giorgio O wrote, the diode is sending. So there´s another problem.Is there anything I could have forgot or has anybody else had a similar problem? I´m trying for 4 days....I use the Arduino mega board with the 0017 software.Excuse my mistakes in English. I´m not a native speaker.Thanks for help..

Giorgio: there are several reasons your sat decoder box may not respond. At the low level, it might be using a different modulation frequency than 38KHz, or a different IR wavelength. Higher level, it may be expecting more than just the played-back signal. For instance, RC5 alternates between two different codes, so simple playback won't work. Sony codes require the code to be transmitted at least twice. Your box may have its own strange requirements, such as different codes with particular timings. It could be the 50us resolution, but I've found that generally isn't a problem. More likely is IR sensors typically extend the on time and shrink the off time; my code tries to correct for this, but the correction factor could be different for your sensor. Unfortunately, there are a lot of variables to investigate. Also, try the circuit with your TV or stereo, to see if it works there. If you let me know what model satellite box you're trying to control, I could investigate a bit.

australopitecus: My code won't work with an Arduino mega as it has a different processor and the pins are all different. (Sorry I didn't mention that in my original article.) You could see if there's anything on PWM pin 9; I believe that's where the OC2B output connects on the mega. Probably you'll need to study the atmega 1280 datasheet and see how the PWM flags are different for the mega's processor, and change the code appropriately. Unfortunately I don't have a mega, so I can't try this myself.

Hi.That was the problem, yes.Today I found in the o-file "pins_arduino.c.o" the path to the "cores" folder and a file named "pins_aruino.c".According to this, in the digital_pin_to_timer, which is a part of the program memory, I think, Timer2B is related to PWM9. I tried it and it worked. I had only to change the output of the pinMode.I don´t know if that´s exactly the same you mentioned, but I have a signal now. So I can receive and send.Thanks to you, this saved my weekend.I love the internet.And also thanks to Wolfgang for the Panasonic protocol.

Hi I try to control my LG tv using a arduino and I found you lib and i think it would work great. I also found my tv ir codes on LIRC but I have no idea how im going to use the information at LIRC to controle my tv.

Hi reconnnn: I'm in the process of writing an explanation of LIRC data, but for your case LG usually uses 32-bit NEC protocol. Take the pre_data bytes in the LIRC file and join them to the bytes for the button you want to control to make a 4-byte hex number, and use sendNEC. Power on is probably 0x20df10ef; some LG devices use 0x897641be or 0x34347887. If you have an IR detector, you can read out what your remote sends, rather than looking in the LIRC files.

Thanks for this great great Library. A few observations I made:Receiving does not work with official Ethernet-Shield, but I had no problems sending. The Problem (I guess) is that SPI (pins 10 - 13) is needed for commucation with the ethernet shield and also used for the ir communication. But it might also be interrupt or timer related.I will take a deeper look at it, but atm I'm covered in "look-at's", so no promises.Again thanks and keep the good work flowing ;)

Never mind. I got it now why the MARK is defined as 1 and SPACE is as 0 for the receiving side. It's because the the receiver is active low. (It should be as named. Don't pay attention to the actual values for easier understanding.)

I had refactored the code into little tiny C modules for sending and receiving, so that you can choose to link a particular sender and receiver with very small flash size that fits to 2K ATTINIES, such as, the ATTINY25.

Also, the code is now Arduino-free, meaning running on any Atmel chip, as long as you chnage interrupt part of the code. (I had to write one simple module that support digitalWrite()/digitalRead()/pinMode() functions.)

I had also optimized to code to do bit packing of the port info into 16 bits, as well as misc info, for example, when using uint8_t instead of uint16_t.

The core functionality is exactly the same as the original code, without change.

I frankly haven't tested the original code by Ken, the author, because the compiled hex file won't fit into an ATMEGA8/ATTINY25.

But I tested out my stuff.

I do have one question in general.

The moment the receiver receives sufficent IR data to get it into the STATE_STOP state, I have noticed that it took almost 4 secs (SECS with an ATMEGA8 at 16Mhz) to actually to have irparams->timer > GAP_TICKS, which is calculated out to be 100, thus, 100 * 50us = 5000us = 5 ms, but it really shouldn't be 4 secs between the moment I finish sending some IR data (via a remote control) to the time STATE_STOP is set. Why?

I compiled the demo (Sony TV power), and modified it to send a on/off every 1 second. Only one in about 60 work and I'm 3 feet from the TV. I took a peek at the LED output via a digital camera and it looks very dim. I've removed the resistor on the LED and it's still noticably less bright than a regular remote (viewed through the camera, and it only works at all this way). Swapped in another LED - same thing.

You indirectly revealed the "bug". I was sending the code 3x (your Sony power code snippet) with the 100ms delay between pulses, every one second. I reduced your 100ms to 50ms and it worked. So you might consider changinge your sample snippet to 50ms delays between pulses.

I've been using this library for a while; I'm doing a project that involves using the Arduino as a webserver for controlling IR output. Some interesting things I'm implementing are the webduino libraries, EEPROM for storing received values, and a 8x2 LCD.

One really important thing I've noticed is that the Arduino cannot provide enough power from the Digital Out pins. I'm using a Stock IR LED from Radio Shack, which can operate at up to 100mA at 1.2 Volts. For more power, I am using a 2N2222 transistor: the base is in series with a 2K resistor and the digital output pin; the emitter goes to ground; and, the collector is in series with a 47 ohm resistor, the IR LED, and the 5V supply. I haven't ran this through a ammeter; regardless, on paper there is more than enough power, and it works well for me, regardless of how much power i'm drawing from the power supply.

Let me report, also, that I haven't experienced a code, received and sent by these libraries, that doesn't work. Kudos, my friend, Kudos!

I was receiving codes and then sending codes and I couldn't figure out why it would hang after sending a code. The reason is that I didn't know that you needed to use the irrecv.enableIRIn() after every send before you can receive again. Spent many hours trying to figure out what was going on .

Yesterday i finally discovered your amazing IRLibrary for Arduino... I would like to thank you for sharing your job... it's by far best IRLibrary for Arduino, it works very very well and it's very easy to use, too.

After playing with it a bit, controlling leds, switches and anything that could be attached to my arduino, I tried to use it for controlling some DMX devices... it would be amazing for me to control my house illumination with an IRRemote and some standard DMX equipment (I've got a lot of DMX devices and i love to deal with them, DMX works very very well in many environments)

I use this DMX Library http://code.google.com/p/tinkerit/wiki/DmxSimple

Sadly, i soon discovered that both the IRLibrary and the DMX library use Timer2, in a different, different way, and as far as I've seen they won't work together

my programming skills are not advanced enough to get out of this issue... and i was wondering if you have some ideas

I think it would be very useful to use arduino to control DMX devices via IRRemote, because DMX controllers are usually very expensive and not so customizable, and there are hundreds of DMX devices that asks only to be controlled :)

Love this library! I ran into a little hitch that caused me some confusion, but I eventually found a work-around that I wanted to mention here. While using the library to enable an IR receiver (salvaged from an old VCR) while elsewhere in my code also driving an RGB LED using other PWM pins (on pin 9,10,11 for r,g,b) I got some odd behavior: I couldn't control 'green' on pin 11). I'm a bit of a newbie at this, but it seemed like a timing issue affecting the PWM.

Looking at the library code, I could see that it manipulates one of the microcontroller's timers (timer2, via TCCR2A and TCCR2B) in order to properly sense the incoming IR signal. Through Googling I came across the PWM cheatsheet on the arduino playground (http://www.arduino.cc/playground/Main/TimerPWMCheatsheet) which mentions that timer2 handles PWM timing for pin 3 and 11. Since I originally had my 'Green' connection on pin 11, the cheatsheet seemed to indicate that it was affected by the library's use of timer2. Sure enough, moving the Green conenction to to another PWM pin (not handled by timer2) seemed to solve my issue.

So, if one uses this library, looks like PWM on pin11 is not possible, given the library's use of timer2. A small limitation on an otherwise incredibly useful library!

Many thanks,Michael

ps: I saw the comment above regarding the DMX controller library conflict because it uses timer2. Wondering: In order to solve the conflict - or, as above, if one absolutely needs PWM on pin11 - could one modify the IR library to just use timer1 (ex: TCCR1A,TCCR1B, OCR1A, OCR1B etc) or timer0 (ex: TCCR0A,TCCR0B, OCR0A, OCR0B etc)?

I really like this project. Thank you very much. It helps me a lot.But I have one problem. Everything works, except sending the IR pulse.Neither in the example IRrecord nor with IRsendDemo.There´s no output at the PWM pin 3. I´ve tested it with a camera, a LED instead of the IR-diode and the oscilloscope. There´s definitely no signal.

Before the modification it would only successfully decode a panasonic signal in debug mode. I assume this is because Macros are not type safe nor do they handle expressions entered as arguments perfectly in all cases. I didn't look too deeply into the failure but this fix worked for me.

*Note instead of sending the REPEAT constant if you want the JVC repeat signal sent, send the original code value and change the repeat argument from 0 to 1. JVC protocol repeats by skipping the header NOT by sending a separate code value like NEC does.

Hi Just a quick note to say I used your lib to implement a protoype ethernet based remote for my TV & DVDR which I access from my iPhone via wifi. I also make use of a local web server between my Iphone & the IRremote arduno/ethernet shield. Hopefully, I will be able to do without the web server in-between by using ajax on the iPhone. The IR receiver component was very useful for decoding my DVD remote. The TV and DVDR are from philips and both use RC6. The TV also accepts a base set of RC5 codes as well.

As some people mentioned above, the library uses timer2 so it will conflict with other software that uses timer2. Timer0 is used by the Arduino framework for millis() and delay(), so the library can't easily use timer0. Timer1 is a 16-bit timer, so it's not directly compatible with timer2. I'm looking into modifying the library to use timer1.

(From the have-my-cake-and-eat-it-too department): If you were to undertake adding support for timer1, might it be worthwhile to make it user-configurable so the lib could use either timer1 or timer2 based on some sort of configuration directive/variable setting?

Thinking that if you substituted timer1 support *in place of* support for timer2, that might fix the issues on pin 3 and 11 but it would probably negatively affect those using PWM on pins 9 and 10 (since timer1 controls PWM on 9 and 10)...

Simply fabulous! I was searching for an Arduino IR library & found your blog only a couple days after you 1st posted it. Been using it ever since, of course. I've seen other IR code here & there but nothing as good as yours.

Thank you very much for sharing this & your continued work on it.

Also thanks to all who have added more protocols.I'm sure many people haven't found this yet. Would you mind if I add a link in the Arduino Playground wiki? http://www.arduino.cc/playground/Main/GeneralCodeLibrary

Simon: there are two ways you can get the codes. First, you can look at the Sony LIRC files and try to find one with codes that work on your TV. One complication: the Sony LIRC codes are a bit ambiguous about the last bit. A lot drop the last bit, so they are 11 bits long instead of 12, and you need to multiply them by 2. Others end in 1 and you need to subtract 1 (try the RM-S609 codes and subtract one).

Alternatively, if you have an IR receiver module, you can run the IRrecvDump example to print out the codes from your existing remote.

I LOVE this library,I have been playing the entire week with it. I have one issue. The first time I tried the code I run all the samples, the first sample IRSendDemo was not working for me, I tried the IRRecord and it worked perfecltly, pressed a button, saved the code and then submitting that code to my TV. Great! The thing is that I'm not able to JUST send a code. I try to use the sendNec method but no output on pin3, what I'm missing here? Thanks!!!

mmmm sorry for the previous post, I tried again and remove the first if on IRSendDemo....and ir worked PERFECTLY...sadly, I was using the entire block on ALL my tests...removing the IF for the Serial.read solved it...I'M VERY HAPPY!! :)

Hello Ken, this library is really great. I just like to have the Panasonic Option but I don´t know how to integrate the Codes above (Wolfgang and next). I get many Errors and persistenly "in decode there is no address" The decoding function maybee different from the others. Sorry I´m a Newbie and there should be some adapptions I don´t understand for now. Could someone explain the integration of the Panasonic-Code (Step by Step in Detail with every associated File:)thanks Christopher

Ok, I fixed the Problem above (just the variable address to add). But now I´ve got serious trouble. I am trying to implement the RECS-80 (a very old, but cheap-chip protocol) and got stuck. I modified the NEC-Code (for the RECS-80 is pulsewidth modulated) but can´t get a reaction. The Marks are very short (158us) and the spaces very long (4900us = 0, 7432us = 1). The Duration of the Signal may be to long? Could it be a problem with irparam.timer or RAWBUFFER?

Glen H: I don't know what the codes for an Acer projector would be. I'd suggest using IRDump and see if you get lucky enough that Acer uses an encoding that the library handles.

CrYoPyRe: I don't have an Atmega 8 so I can't port the library. You'd have to change the code to use the appropriate registers. An earlier comment said the code is too big to fit in an Atmga 8 in any case, so it might need to be cut down to size too.

I am working on a project in which I want to control home appliances using any TV/DVD remote. I am using Atmega8 for this purpose and I dont have any Arduino Board. I have downloaded Aurduino Software and ur IR decoding libraries are working on it. Now the problem is that how I burn micrcontroller with hex file generated from ur libraries ? In which directory the Arduino Software save these hex files ?

Thanks for this awesome IR library.I was able to use it for an IR translator application.

I did want to mention that one problem that I encountered was that I needed to do receive IR and send IR for my application, and it took me a while to realize that the send IR routine DISABLES the receive IR function. So anyone who need to send and receive IR, make sure to do "irrecv.enableIRIn();" right after you finish sending IR. Otherwise our Arduino would stop receiving IR.

Brilliant!, I have Vately Air-conditioner remote which is still working if you bend the PCB in just the right way. I want to see if can read the codes and then build a replacement remote.

I have a totally unrelated question though... What are those nice looking connecting wires you used in your project? I live in South Africa, and getting local suppliers for hobby electronics stuff can be rather frustrating at times.

This allows you to control a Samsung TV using OBC to provide additional functions not on the remote (OBC's can be found online).

First change 9000 to 4500.

Then for example OBC 190 switches to HDMI#2. Convert 190 to binary and REVERSE the order (I got this idea from looking at NEC examples), THEN convert to hex, e.g this becomes 7D. Invert the binary and and convert to hex 82. Thus web page value becomes NE0E07D82.

Could you please do another example for OBC code converion to the IR library hex code?For my NEC IR code, I have 8 hex digits. If I have the JP1 OBC code, how do I translate it to the IR library hex code for the send function?Thanks in advance.

1) When I put the circuit together as explained it would at first not work. After reading the datasheet for my particular IR receiver, I discovered that pins 1, 2 and 3 are not the same as the ones described at beginning of the blog. Once I got that sorted out, the RcvDump example just streamed random junk the whole time. Back to the datasheet. It seems like its always good idea to use the sample circuit your manufacturer suggests in the datasheet. 1 cap and 2 resistors later and it worked like a charm (the extra components filters out power supply noise).

2) The next weird thing I noticed that my aircon remote was always sending the same sequence no matter what settings I used on it. After digging in the code of IRremote.cpp I found this little section of code:

IRremote.h had RAWBUF set to 76, which just happened to be exactly the same number of values I was getting in the dump. I had to increase it all the way to 200 to fit in the whole message from the air-conditioner remote. It seems like air-conditioner remotes send all the settings (temperature, fan speed, mode, swing etc) all in one go every time you press a button.

Next: I have to reverse engineer the codes so that I can build a replacement remote. I have already figured out which 4 bits is used for temperature.

Hi, I'm curious if I can use this library to make a beam-break detector, so the IR LED transmits continuous and the receiver detects when the beam is broken, when an object is between the two. Is this possible?

Re another example, I just used an online convert at mathisfun com. Try it with the example I've provided and I think you can make it work. By reversing the order I mean for example 10110000 becomes 00001101, then convert this to hex. The second hex is the inverted 11110010 convert to hex. It helps to google the NEC code format. Hope this helps.

Reply to loan: for a beam break detector, you could use this library to generate the modulated signal for the IR source. I wouldn't recommend using the library to detect the breaks; you could just read the detector directly on a digital input.

Thanks for the hints for the Panasonic code, but it's still not working...I did increase the space to 450, and change the tolerance to 35%.It's getting further, but still couldn't decode. This is what I get now:

Anonymous Panasonic: it looks like the code is designed to receive 48 bits and you're receiving about 16 bits. (You're running out of data too soon and getting the 0 time value.) You could try cutting out all the decode address code. Or you could replace the "return ERR" with "break" inside the loops, and then it would succeed rather than fail when it runs out of data.

Thanks for the tips. I finally go the Panasonic decode working. I had accidentally modified the original Panasonic code during the course of debugging. The original Panasonic code with tweaks that you suggested (space, and tolerance) made it work.Thanks again for the help and this awesome IR library.

Hey Loan, I would not suggest using the send functions from the library to do the IR break detection. The IR send function DISABLES the receive function. So you will not be able to receive and when you are sending IR.I guessing that you can do a simple analogwrite on a pwm pin to get a constant 38 khz IR output.But maybe Ken has better ideas.

This all looks great. Is there any reason I couldn't use a production quality Ir Receiver? I've hooked one up (Niles m220) and I get the flashing light, but it can't decode the IR. I ran the dump program and it just says "can't decode message" and a bunch of negative numbers.... Thoughts?

Ben: I can think of a couple reasons why your M220 receiver might not work:a) Maybe the receiver is active-high instead of active-low?b) Maybe the code your remote is transmitting isn't one the library understands? In that case, look at http://www.arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.htmlc) Maybe the tolerances of your receiver are a bit different than the ones I use?

Can you send me the output from the dump program? I can take a look and see what's happening.

I'm using the M220 in an attempt to be able to cover all remotes. This receiver is not limited to a 38.1 kHz remote. I'm a bit unclear on the active high/low thing. To clarify, the output from the m220 is normally high and goes low as it receives impulses from a remote. As a result I had to cobble together a not-gate from a 3 input nand gate with both other inputs forced high.. With the output from the m220 going directly to the input pin on the arduino, I got absolutely no response.

I am a home theater contractor and have been amazed at how much the remote companies charge to do fairly simple things. If I were more of a programmer, I could probably use an arduino and a few cents worth of other bits and replace a 600 dollar remote processor. It's a dream..

First, I can tell from the positive and negative pattern that on and off are reversed. My library expects an active-low signal, which your M220 provides, so remove the inverter.

Second, your off durations are ~100ms when they should be ~600us, and your on durations are ~500us too long. In other words, your receiver is taking about 500us to switch from on to off. My code allows 100us for this transition (based on the IR receivers I've used), but 500us will probably throw off the decoding. In the file IRremote.h, change the constant to #define MARK_EXCESS 500

I think with these changes you should decode successfully. I could manually decode the dump output and see that you're pressing the UP button on your Sony DVD remote, right?

Many thanks for providing this for free - it has saved me a lot of time and trouble.I think that I have a bug fix for you though regarding the NEC protocol.In IRremoteInt.h you have defined NEC_ONE_SPACE as 1600. I think that this should be 1690 (2250ms - 560uS = 1690ms not 1600ms). The original value was not recognised by an InFocus projector, but the amended value did work.

Hi there, I'm trying to use this library to reset the lamp hours timer on my Plus U2-1130 projector (which, for some stupid reason requires the remote to reset the timer, and the remote is lost). I got the Arduino board and the 950nm IR LED from RobotShop, and have started playing. The LED blinks as verified with a camera, but I'm not getting any response from the projector. From the manufacturer, I have a file that says custom code 18E9 (though I've been told on RC forums it should be 1816), and On code 08F7. I've tried sending (with sendNEC, since the manufacturer says it is NEC protocol) 0x18E908F7, (ie irsend.sendNEC(0x18e908f7, 32);) but I'm not seeing any response on the projector. Am I missing something? Does the bit order need to be reversed, or does something need to be complemented? I don't have the remote, so I can't use a receiver to get the true code. I've held the LED up against the projector in case it is a low power issue, still no response. Once I can get it to turn on, I will need to simulate the On button held down for 10 sec, which I imagine involves something like irsend.sendNEC(REPEAT, 32); being repeated every some number of ms. Thanks for the awesome library, and the help!

I'm trying to send the power-on code for an Xbox360...I'm using the LIRC file from here: http://lirc.sourceforge.net/remotes/microsoft/Xbox360

Using the data in this file, I figured that I needed to send the following code:

irsend.sendRC6(0x37ff086f3, 37);

This comes from the fact that the pre_data is listed as 0x37ff0 with 21 bits, and the power on/off code is 0x86f3, with 16 bits. I clearly have something wrong, because the Arduino software spits out the error: "integer constant is too large for 'long' type." I understand that the code I'm trying to send is too long, but what should I do to get this to work correctly?

I've just about thrown all this out the window in frustration so I was excited to find a promising library. (Thank you, btw)

Unfortunately seems the library isn't working for me either so I must be missing something somewhere. Hope you can provide some ideas.

When I run the send and receive demos I only get three 0's for output. The IR appears to be sending (seen via camera) but not getting anything valid. I tried a Sony remote also but all I get is 0's for any button.

I'm using a sharp IR receiver (38KHz)(http://media.digikey.com/pdf/Data%20Sheets/Sharp%20PDFs/GP1UE261X,267X,26X.pdf). Testing with two Arduino Pro Mini's. Not sure if it matters but these do run at 3.3v and 8 MHz. Does that change the PWM stuff?

Before trying this library I was getting somewhat consistent (although noisy) results using the classic oscillationWrite and pulseIn functions so I'm pretty sure the wiring is correct. However, it's far from reliable so I'm going crazy.

Anonymous: before you throw everything out the window, try changing the clock speed in in IRremoteInt.h to: #define SYSCLOCK 8000000. I think the problem is your clock speed is 8MHz, and my code is designed for 16MHz.

Vishal: if you need 37 bit NEC codes, try changing sendNEC to take a uint64_t type, since long is limited to 32 bits.

Anonymous: yes, you are right; NEC_ONE_SPACE should be 1690.

DrNeon: I don't have any good suggestions for you. Maybe try Anonymous's change to NEC_ONE_SPACE above.

This is the only floating-point code used in the library, and it means that the compiler pulls in the Arduino floating-point libraries, which are rather large, and it is wasteful of memory to use them for this simple calculation.

If you delete these three lines, and modify the definitions of TICKS_LOW and TICKS_HIGH (the only lines that use them) to

you get exactly the same behaviour, but you don't need the FP libraries any more. On my sketch, this one change reduced the memory used from 16404 bytes to 15220 bytes - a saving of well over 1kbyte, which is very worthwhile in the Arduino's limited memory footprint.

In general, on embedded systems, you should use integer maths wherever possible - floating-point is invariably expensive in terms of memory and processing power.

Bobrik: that's how RC5 and RC6 codes work. They have a toggle bit that is set every other time you press the button. You can subtract (AND) off the toggle bit if you don't want it. For details see Philips RC5 Protocol.

Simon Long: that's a good point about using floating point. I'll replace that with integer arithmetic in my next release (whenever that is).

Hi Ken, I just tried it and found your library really useful and well documented. I'm using it to gain control over an LG DVX482H DVD player for an arts installation (replace its AKB35840202 remote). The Remote seems to use 2 different versions of NEC Protocols for TV control and DVD control. TV Protocol uses a MARK of 9000, the DVD part works when I change NEC_HDMARK to 4500 (tried this value by guessing from raw value readings). Since I don't use the TV part this change is fine for me. Maybe this is of use for someone else. I'm both successfully receiving and transceiving right now. Thanks!

Great Library. I'm developing a remote control for watching TV. I set a home channel, then when a commercial comes on, I can surf all over for 2 minutes or so, then the Arduino sends the signal to return to the home channel. I call it the AdBlaster.

For those who want to measure IR LED current, don't forget that the Arduino has 6 ADC inputs. I turn the IR LED on, and measure voltage at both ends of the series resistor. The IR LED voltage can also be measured.

The typical IR LED's are rated for 100 mA+ continuous current, so by making the duty cycle 25 to 30 percent, higher currents are easily tolerated.

I'm an Interaction Student on the HKU in Hilversum, the Netherlands. I'mcurrently busy with a project that requires constant IR-communication and Ihave a question about the IRremote library.I'm using an Yamaha remote. Now I want to use the volume + button(5EA158A7),that the remote is sending, to power a led and the volume - button(5EA1D827)to disable the led, but that doesn't work..

I've been playing with your IRRecvDump example...the timing data makes my life SO much easier. Before I got your code, I was measuring pulse widths from my receiver chip using a oscilloscope in the lab...

I'm still having trouble with the Xbox360 remote. I have ascertained that the remote uses the RC6 IR Protocol, and I have used a photodiode/opamp setup in that lab with an oscilloscope to verify that the timing data your program receives is accurate, and that the modulation frequency is in spec for RC6 (36kHz).

My assumption is that this was the toggle bit that I was seeing. Noting that your code doesn't call the toggle bit, I figured that if I put the following code in my sketch, the Arduino would indeed turn on the Xbox:

I've tested the LED circuit I'm using (IR LED with forward voltage 1.2V, and forward current 100mA, in series with 39 Ohm resistor) with IR code I've written for a different (and much easier to understand) remote protocol, and it works. Of course, I have connected the LED to digital pin 3, as you said, so I'm certain it's not a hardware failure.

I know you've stated that you do not have any hardware that supports RC5/RC6, and are thus unable to test the code yourself. However, you appear to be quite knowledgeable on this subject, and it's my hope that you can point out something I've overlooked.

Thanks again for taking the time to help people use your software, and continuing to respond to comments like mine. Your code is a great help to tinkerers (and college EE majors trying to finish their design projects) everywhere. =D

Hi Vishal! Let me try to explain the RC6 toggle bit. If you press and hold a button on a remote, the code will be transmitted multiple times without the toggle bit as long as you hold down the button. If you then release the button and press and hold it again, the code will be transmitted multiple times with the toggle bit set. If you release and hold the button again, it will be transmitted multiple times without the toggle bit set. The point of this is that if you're holding down the power button, the TV (or other receiver) can tell if you've pressed it once or twice, even if the signal is interrupted (e.g. someone walks in front of the TV).

Your code fragment will flip the toggle bit over and over, which won't work.

If the toggle bit is the issue, you should be able to send a code once, but then it won't work again unless you use the remote (which will flip the receiver's expected toggle bit).

I don't know if the toggle bit is your problem or not; the 36-bit Xbox codes are outside what I've dealt with, so lots of things could go wrong with the code. Maybe if someone loans me an Xbox :-)

You said you're using an oscilloscope; you should be able to compare the codes the Arduino transmits to the code the remote transmits and see what's different. A couple things to look for: some receivers expect the code to be transmitted multiple times with a particular spacing (expecially Sony), so see how many times the remote transmits the code if you press the button once. Also, make sure the transmitted codes are the same, especially at the end. I wouldn't be surprised if there's an off-by-one problem and the Arduino is transmitting one last pulse too many or too few.

I'm back, but with an other question this time... I want to use multiple IRreceivers and I thought it would be a piece of cake.. When I wanted to test the code, only 1 of the 2 receivers responded. It's not the receiver because I've already switched it with the pins... I guess that the code isn't correct.

I'm saying I have connected multiple IR receivers to one Arduino pin, and I just told the Arduino to listen on that one pin for both receivers. My receivers are in separate rooms, so they never operate at the same time.

TiStyle: The code doesn't currently support two receivers on different pins, mainly because I never thought of implementing that. The interrupt handler would need to be modified slightly to check the status of each pin, not just one pin. Maybe in the mythical version 2.0 :-)

greenembrace: it looks like your input is inverted; the code expects an active-low input, so it can't interpret the data it's receiving from your (NEC?) remote. Are you using some strange type of IR detector? Stick in an inverter and it should work.

TiStyle: running 30-50 independent receivers sounds like a lot! It sounds like an interesting project; do you want to give more details?

To outline what you'd need to do to support multiple independent IR receivers...

The code currently uses a single irparams global structure to keep track of the received code. The timer 2 interrupt code checks the status of the input pin and updates the irparams structure.

You'd need a separate irparams structure for each pin. You could have an array of them, or maybe have irparams part of the IRrecv class. The array would make it easier for the interrupt handler, but putting it in the class would be architecturally cleaner. Then the interrupt code would need to loop through all of them, updating each one according to the input.

Then the decoding routines would need to process a particular irparams structure, rather than the global one.

I'm not sure how many inputs you could process before you'd run out of time in the interrupt handler.

Hopefully this all makes sense; let me know if there's anything else I can help explain.

We'll probably use a Mega or maby 2 seperated, we still need to test it out. We'll be making a big light that has about 50 power LEDS. You'll have beacons that will emmit a pulse and the receivers will be used as direction trackers. There where the beacon is, the light will shine uppon(Sounds a bit mythical)...

I'm not sure if I get what you mean... So in the IRremote.cpp/.h I'll need to make an array for the "irparams"?

I've implemented a new version of the library with a whole bunch of changes including multiple input support (TiStyle, this is for you), support to send and receive codes for arbitrary space-encoded remotes (not just NEC and Sony), and some other features and cleanup.

we are trying this here with an arduino mega and could get it to work (physically, meaning we have output on the LED) setting the pinMode in the library (as described here in the comments). however no matter which hex value we're trying to send, it will always output the same bit sequence (we are using an oscilloscope to monitor it). we are using the RC5 protocol and (meanwhile) the latest source from github. has anybody encountered the same problem or any idea what the cause could be?

tilluigi: the latest github code (dev) is really untested; if you're having problems, I'd suggest using the original code at http://arcfn.com/files/IRremote.zip . Also, I haven't tried any of this on a mega, so I would not be surprised if there are problems. The only board I have is the Arduino Duemilanove, so it's pure luck if the code works with anything else.

I am having problems getting the irrecvdemo sample to run. It seems to be crashing runtime at irrecv.enableIRIn(); in the setup method. I have only modified "int RECV_PIN = 6;" Do you have any ideas what might be causing this? I am running windows 7 with arduino 0018 (but I have also tried 0017 with no success).

I am having problems getting the irrecvdemo sample to run. It seems to be crashing runtime at irrecv.enableIRIn(); in the setup method. I have only modified "int RECV_PIN = 6;" Do you have any ideas what might be causing this? I am running windows 7 with arduino 0018 (but I have also tried 0017 with no success).

Hey Ken, I'm back with an other problem (I'm so sorry to bother you like this)... The new code works fine, but as soon as I define 5 or more receivers the arduino starts to lagg or something like that.. I really can't figure out what it is...

I've checked your library and I think our project won't be needing as much as your library has in it..

Our project is about a lamp that can be controlled bij a beacon. The beacon is the sender and the bulb of light has receivers in it.. All the receivers will be looking at other directions. The receiver that picks up a IRsignal, turns on a 1watt power LED in that direction. The beacon can also control the intensity of the LEDS trough a potentiometer. As soon as the potentiometer-value changes, so does the HEX that the beacon is sending...

That's pretty much it.. I hope that you could help us, this is the final thing we need to fix.

I have managed to send and recieve commands with it, but I have a problem with the only command I really need to send. I would like to send the record/stop code of my camcorder as a raw ir-code. I measured the the raw ir-code with both arduino and usb ir-toy. After that I was also able locate my remote (canon wl-80, not any regular protocol)commands at the lirc-site, but I can't figure out how to use the send.raw command. Perhaps you would like to write an example?

Because my coding is really beginners level and I need only one ir-command, I'm not trying to write the whole protocol.

@Miles: Those codes look mighty strange. It looks like there are at least three different coding schemes in there. You have signals that start with on for 1800us, off for 300; ones that start on for 2700us, off for 900us; and ones that start on for 4450us, off for 4500us. (Looking at your dumped values, starting with the second number.) The third set look like 32-bit NEC codes, except the first on value is 4450us instead of 9000us. Try changing NEC_HDR_MARK to 4450 and see if those ones decode. The first code is mystifying. It definitely doesn't look like the documented RC-6 protocol; see http://www.sbprojects.com/knowledge/ir/rc6.htm and notice the timings don't match. The first code has timings all over the place, especially the 1550us and 2050us values. The second code looks like RC-6 with 24 bits of data. However, the marks (positive numbers) are a bit short and the spaces (negative numbers) are a bit long; the sensors I've seen are all the other way around. Try changing MARK_EXCESS to 0 or maybe -80 or -100 and see if that helps. (The RC-6 timing should be 444us, but you're seeing on for 350-400us and off for 500-550us.)

now to the question :=) :I was thinking about using both the sending and the receiving functions in a single sketch (project which involves both sending and receving of IR) and i was asking myself: won't the interrupts called by the receiving function corrupt the code being sent with irsend? That is, when i call the function irsend, do the interrupts (called when timer1 overflows) get called also while i'm sending the data?

I built an Arduino steering wheel to IR control circuit this weekend to control an xpressRCi XM satellite radio receiver in my car. Your fabulous library and my previous experience hacking JP1 remotes allowed me to get my project up and running in no time.

I did run into one issue with your library; there is no way to send RC5 extended codes. The fix would be to comment out the two lines that say "Second start bit" in IRsend::sendRC5() but doing that breaks any existing code so a better solution is to create IRsend::sendRC5X().

I'd also suggest tweaking the comments to IRsend::sendRC5():

-// Note: first bit must be a one (start bit)+// Caller needs to take care of flipping the toggle bit+// (which is 1st passed bit)void IRsend::sendRC5(unsigned long data, int nbits)

BTW, the current comment is wrong; the code clearly sends both start bits.

Sorry for the above comment, i just noticed that you have written that it doesn't support simultaneuos receiving and transmitting.

But that makes me want to ask you something else: what does that exactly mean? Does it mean that when i use "irsend.sendSony(0xa90, 12)" the interrupt won't be called while transmission is being sent, or does that mean that just writing "IRsend irsend;" disables reception for the whole sketch? I guess it's the first case (=reception disabled WHILE transmitting) even because of your other project which receives codes from other remotes and duplicates them.

Problem is it'll work once every 10 tries or so (and only turns off my tv not on). I put it up to a oscilloscope (solar cell going to my computer) and I get about 21hz from my viewsonic remote, but my arduino program changes between 10-889hz. Your sony code stays at about 19-20hz (sorry don't know if its hz, mhz, or khz, too lazy to turn on my other computer to see).

I changed enableIROut() int but still doesn't work. Am I missing something?

One last thing: above it says that the receiver interrupt code is called when TIMER1 overflows. I have checked the .cpp file and there is no sign of timer1 while there clearly is something related to timer2. Did i miss something?

@TomTom: I looked at the LIRC file for Viewsonic. I think the main thing is you need to send a mark(VIEWSONIC_BIT_MARK) at the end of your code. You could also try tweaking your timings a bit to match the LIRC file: http://lirc.sourceforge.net/remotes/viewsonic/RC00070P but I think the missing mark at the end is the problem.

@CaptainTuna: yes, the code uses TIMER2. No simultaneous sending and receiving: when you send a code it disables IR input, and you need to call enableIRIn to start receiving again. (I do this because I kept running into trouble with the board receiving the code it was sending, so it seemed better to just do one thing at a time.)

@Craig: I didn't know there were RC5 extended codes; I'll look into adding them to the next version.

Regarding the next version, I have some ideas about handing sony12/sony15. I wanted a macro that could hand device and command (OBC) values. However thanks to the "LSB first" feature of the Sony protocol, this is a hassle. I started by writing code that used a reverse bit routine:

My next idea was to make a send sony routine that clocks the bits out backwards from the other IR routines. That way the user doesn't have to worry about reversing the bits. He can pass the data in "normally" and the routine automatically reverses the bits. That works great:

@Craig: I have some bit-reversing logic and logic to break apart Sony codes in the dev version: see http://github.com/shirriff/Arduino-IRremote . But that's the opposite direction from what you're doing; assembling the Sony codes from the component parts. I'll merge your code in when I have time.

I'm trying this on my photoframe, and it's working partialy.. The IRrecord sketch works, and it recognizes it as NEC. Recieved NEC: 1FE7887.When i push the button it sends it out, perfect..But what do i do with this recieved code.. i tried to paste it in IRsendDemo, i get an error invalid suffix.

I've got a Photoframe, without the original remote, but found out, by accident, that all those cheap remote's (fotoframe, usb-dbv-t, and the 3$ remote nuelectronics sells, etc) have a few buttons in common.. So with the help of your program, and a lot of different remote's i testet, i made the control my photoframe.. Digital digital controlled..

the library works really fine with some of my remotes, thank you very much! unfortunatly, most of my stuff is controlled with the panasonic protocol... and my skill seems not good enough to bring the code pieces together.

is there a "full" version of the library available including the panasonic protocoll?

if not, i will dive deeper in the code and will figure out why it's saying

/Applications/Arduino.app/Contents/Resources/Java/libraries/IRremote/IRremote.cpp:625: error: 'class decode_results' has no member named 'address'

Thanks for the answers Ken. I got some more though (hope i'm not bothering you much with these):

1) there's a constant in your library called GAP_TICKS. If i well understood it is the min time before two consecutive transmissions. Why did you introduce it? Why do you want to have a minimum time between 2 transmissions and not make the receiver pick consecutive ones?

2) why are you using a time interrupt? I see that the ISR routine gets called when the TIMER2 overflows (set at 50us). Why not use the attachInterrupt offered by the arduino so that interrupt routine is called only when the arduino detects a change in the state of the input pin connected to the IR receiver (goes LOW from HIGH(idle)), and then maybe use pulsein to measure the lenghts of marks and spaces? It sounds much easier to me, but i'm not an expert like you so i am surely missing some CONs about this method.

I've created some tv remote pranks using your library and an IR LED to send out data. For example: if they hit channel up, the arduino will send out channel down, and vice versa. Also, if they try to turn the TV off the arduino will turn it back on.It's posted at the arduino website:http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1277840151

I'm not able to get 2 receivers to work. I tried code simlar to TiStyles. If the pins assigned to RECV_PIN and RECV_PIN2 are reversed, only the receiver attached to RECV_PIN works. Please take a look at the below code. Is there a sample multiple receiver code?

Ignore last post. The problem was hardware. The second IR receiver was missing its 5V wire. (Yeah, I know it is a pretty simple circuit.)

Thanks for the great library. It makes my project much easier.

My project is tank war: 2 remote control bots that move around and can 'shoot' at each other. There would be 2-4 receivers to detect shots from any direction. The bots themselves would be remote controlled. The human commander can drive the tank and shoot.

Technologically, this is pretty similar to Polulo's beacon, http://www.pololu.com/catalog/product/701, but I got the idea from laser tag: http://www.ibm.com/developerworks/edu/os-dw-os-arduino1.html

I tried 5 different 38 kHz receivers. I picked 38 kHz for compatibility with common remotes. They all work pretty well. The more expensive ones have better noise suppression, a wider reception angle and can pickup some reflections.

The 56 kHz with a short signal might be better for laser tag to minimize the dead time during transmission. I'm not sure if it matters. I have not put it all together to test usability.

I'm not sure which 38 kHz receiver is best for laser tag. Noise suppression seems good, but don't actually want to pick up reflections.

Current test circuits are just bread boards with exposed receiver and led. Next step would be too restrict hits to well aimed shots.

I will add a tube around the led. A lens would be better. In the IBM link a few posts back, a lens was added the doubled the range.

The receiver has 2 Vishay receivers. I'm not sure how many to use and of what quality for best results. One suggestion on arduino fourms was to use a single receiver with an acrylic lens. The lens would be a piece of an acrylic tube with the receiver in the hole. Not really sure how this works.

Any thoughts on either of these optical factors: - the led tube and lens - the receiver lens

@Andrew RosenblumWould you have the part numbers to the 5 different 38 kHz receivers you tried & could you comment on which turned out better?Perhaps post on http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1251570417.Also if anyone wants more room to discuss Ken's IR Library head on over there too.

@Ken might be good to add a prominent to the forum so that some of these comments might land there instead.

but it dosen't work.neither "static unsigned int powerOn[194]"then a led was used to instead of the IR led,it dosen't blink.however,while use a smaller array such as "unsigned int powerOn[10] = {650,1600,600,1600,600,1550,650,1550}",the led blinked.so i guess that the array powerOn[194] was too big. the question:how to tackle the problem rised by those big raw codes?

My application is a tank bot with an ir gun. I'd like range of 10-20', but they shooter must be fairly accurate. The receiver should work 360 degrees.

I'm fairly enamored with the tsop 2438 and 1138. Both are wonderful receivers in terms of robustness and angle of acceptance. They seem to accept echos. The 2438 could read a signal from 31' away, the length of my living room. It would be a good choice for a remote control tv.

Today, I worked on restricting the shooting angle. The LED will be mounted in a cardboard tube. I'm not sure how much cardboard shields IR, but it seems to work.

There a several great posts about laser tag. Here they are looking for 100-300' range. I actually bought a magnifying glass to try this. But I could not get this to work.

Laser tag is a bit of a distraction, but the technology is so similar I felt like trying it. Besides using 56 kHz signals, they mount 3 sets of 3 sensors on a helmet. I imagine they just tie the signal pin together in each set to simplify the wiring. I tried both ways (connecting the signal pins to separate arduino inputs and connecting them to the same input), but did not reach any conclusions. I think I will use their design as it seems mature.

You are right. Every lasertag system i've seen out there has the receivers connected in parallel. I am curious about having different pins for reception though, as it would be quite cool. It surely needs some modification of the library though.

Woww, I think this is just what I was looking for.However, I´m trying to send and receive ir signals in the same applicattion, and when I use the irsend.sendSony, it blocks the irrecv.decode(&results), and then it doesn´t work any more...

Do you have any idea which is my mistake?

#include

int RECV_PIN = 11;IRrecv irrecv(RECV_PIN);decode_results results;

IRsend irsend;const int buttonPin = 4; // the number of the pushbutton pinint buttonState; // current state of the button

Thank you for the IR library. I have downloaded and tried it. I am getting the "Could not decode message" error. I read the messages by some other users who are also getting this and it is advised to use an inverter to fix this.

Can anyone please tell me how to use an inverter? Or any link having tutorial on using inverter with IR receiver module would be nice.

I have a Samsung remote, and as this Excellent library IRemote hasn´t (yet!) a decode/send samsung. Using that also Excellent post http://www.maartendamen.com/?p=257, is simple to add that funcionallity. The send method is basically the same as NEC.

After follow the instructions in maartendamen (wich decodes the samsung ir),

Thanks Ken for the great library and Wolfgang for the Panasonic IR protocol. I managed to capture the signal from my remote control after tweaking the mark & space and moving the inline offset++ out to a line on its own, i.e.

@Jessarel: I'm glad you figured out how to use the other timer. If you're looking for more information on how to use other boards or timers see http://www.pjrc.com/teensy/td_libs_IRremote.html where Paul Stoffregen has ported IRremote to multiple platforms. When I have time, I'll merge this in with my code, but for now, you can pick up the modified library there.

Awesome code, Ken. Thanks! I thought I would add my twist: I need to send IR to 2 different applicances (TV and cable set top box). So I need to send IR out on pin 3 (as you do) and another pin. This means of course using another timer (Timer 1 for me). My result is below for pin 9. It works, but it's hacked together and I would appreciate anyone improving it! Ben

@Vlad: It looks like the Dell MR425 remote uses 37 bits, while my code only supports 32 bits. You could probably change the library to use "long long" integers. Are you trying to receive codes from this remote, or use the Arduino to send codes? To receive, see my article Using arbitrary remotes with the Arduino IRremote library. If you're trying to send using the raw codes, note that the RC6 protocol alternates between two different codes for each button, so you'll need to do that too.

Thanks for the reply Ken. I am trying to send codes. Receiving seems to work just fine. From all the remotes I have around in my place, I only managed to send keys to a cheap DVD player that uses NEC protocol. Four other remotes are not recognized. I've tried sending raw codes from all, but failed.I've noticed that the raw codes recorded from all of the remotes begin with two random codes. For example, here's the same key of the same remote pressed a few times (once every two seconds):

Am a student trying to build a arduino clock with 7 segment displays driven by 74hc595. Trying to set time with IR Remote. The existing code uses a clock to set display. IR Remote is not getting detected or rather can say not working while sending the serial data.

I have kept the code here. http://pastebin.com/c8BYpeUr ...

Is it because of serial data push / ShiftOut causing the issue ? If yes, any help on how to rectify it. ?

This is my very first Arduino program/sketch. My intention is to control my AV system. I've tried the Logitech remotes, and lately a Phlips Pronto. In the end, none of them work. At least not in a way my wife or the children can use. I looked around and found the Arduino! Great. Now I can write my own and add controls/sensors to see if the things are actually working the way they are supposed to and report back so corrective actions can be taken. The idea (like many others here) is to provide a web interface to all this so I can access it all through an iPad.

This code will parse a Pronto Hex code set and send it through Ken's library.

Ken, thanks a lot! You saved me a lot of work. Feel free to do as you please with this code. As I said, it's my very first so it may not be all that. The famous: it works for me...

I tried appending the code to the comment but it was rejected for being too large (beyond the 4k limit). Instead, I've uploaded to my server. You can download it here: IRProntoSend.tgz.

Wow! after wasting half a day trying to decode some IR signals with my own Arduino code, I'm so glad I came across your blog!! I'm using SEN-08554 from sparkfun, and your library seems to work perfectly :)

The whole reason for my project is I have an obscure remote for my A/C unit which I'm trying to 'record' a control for 'play back' at a later date via an 950 IR led (COM-09349).

So my first question is what the best way to play back this raw data. Can I just put it back into an array and call SendRaw? or will the MARK_EXCESS errors cause me trouble.

Q2. I would have just tried the above, but I only have a single Arduino. So I tried a push button on an interrupt to trigger a send sony control (code from IRSendDemo).

However this seems to block and stop the receive functionality working. I'm know this isn't the multi-threaded world I'm used to with Java :) but is there any way to make the send and receive co-exist? I want to see if what I send is similar to what the original remote sent.

Hey Guys, Where should i unpack this on a MAC? I don't see any file structure for the arduino/hardware/libraries I am using an Arduino Mega and I can upload and run sketches on it fine but when I try to run an example from this project, it obviously doesn't know where the includes should be pointing to. I am new to this so I apologize in advanced for being stupid.

Has anyone managed to get an Xbox 360 to power on? I know the code is RC6: 800F740C (36 bits), but that doesn't work using the command "irsend.sendRC6(0x800F740C, 36);". All my other remotes work perfectly using this.

Carl: there's some discussion of the Xbox360 remote earlier in the comments; look for "Vishal". Unfortunately I don't think Vishal got it working. If anyone was successful with the Xbox360, please let me know.

I still haven't got it working, but I did manage to get a look at it under an oscilloscope today. Bear in mind, I have absolutely no idea how to work an oscilloscope, this was the first time I touched one, but I did get some sort of output (excuse the fact that this machine looks like it was built in the stone age).

What I tried to do was get the entire packet into the screen at once, so it's really tiny, but maybe you'll be able to spot something. I shortened the code to just loop the Xbox code with a delay(30), that seemed to match the output.

The following images are the best I could capture (how do you capture data on these old things?).

http://imgur.com/a0EF6.jpg -ARDUINO

http://imgur.com/hhAD5.jpg -XBOX REMOTE

When you look at these, they look pretty similar, but blurry and small as hell. I'll try to get something better to you soon. We have some digital scopes, but they were being used today, so I'll have a look again tomorrow if I can.

Carl: The oscilloscope traces are extremely helpful. It looks like the code you want is 37 bits and your code is 36 bits. (I don't know how you got 36 bits since my code only supports 32 bits, so you must be doing something sneaky.) The other problem is the XBOX remote's code is 0x1001fe8180 (if I manually decoded the oscilloscope trace correctly), which is entirely different from the code you're sending. The timing all looks good, so I think you're close.

I didn't get to use an oscilloscope today, but I have got a solution (sort of). I gave up on RC6 and went with Raw.

So, if you decode the raw file, assign the values to a string, and call that in irsend.sendRaw(), it will work. Now, the Xbox 360 sends 2 different codes for on/off, so this will only do one or the other. I'll decode the other one tomorrow, maybe.

That should either switch your xbox on, or switch it off, so you'll need a remote to send the other code.

Ken, what do you think would be the best way of implementing this so when the command is called, this code and the other corresponding raw code is sent? Just send them both fairly quickly and hope the Xbox doesn't just switch on and off again?

As you can see, it appears the marks and spaces are inverted. Wondering if it was someting wrong with my wiring, I checked a sony remote, and it decoded fine.

So, is there a way to invert the output/IRsend marks and spaces in code.I want to do it in code because the dongle I'm looking at making will send out these non-standard codes alongside sony codes, so don't want to invert the output wholesale.

Hey I have a mac and I downloaded your library and dumped the file under arduino/libraries next to the file arduino.jar Then I tried to open the IrRecivdump and compile the program but it tells me Variable or field 'Dump' declared void and the first error line message is IRrecvDump.cpp:9:22: error: IRremote.h: No such file or directory

did i put the zip file in the wrong place? and if it is can someone can please tell me where to put it in a mac thx!!!

im very new to arduino but have picked up your code and have maneged to dump all my remote code's and play them back with the IRSendDemo with a push button one at a time but i wish to have 5 push button's each sending a differnt code,,,i have tryed to wright one script with 2 button's (one for power one for chan-up) but when i upload it only the first one work's [code]

*/

#include

IRsend irsend;

// constants won't change. They're used here to// set pin numbers:const int buttonPin = 2; // the number of the pushbutton pinconst int buttonPin1 = 4; // the number of the pushbutton pin // the number of the LED pin

@Rotceh_dnih: it looks like you are closing the for loop and the if statement in the wrong place, so the second signal will only be sent if both buttons are pressed. You need to move a couple of the closing braces up. Go to Tools -> Auto Format, and the code structure will be clearer. Let me know if a more detailed explanation would help.

Ken, is it possible to put an IR LED on each of the 6 PWM pins on an Arduino Pro Mini? I'm looking to address each IR output individually. The idea is to say something like: "3,stb,power_on" where 3=IR LED #3, stb=the remote, power_on=the power on command.