Tutorial: Arduino and Infra-red control

Learn how to use Arduino and infra-red remote controls in chapter thirty-two of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A tutorial on the Arduino universe. The first chapter is here, the complete series is detailed here.

Updated 10/07/2013

In this article we will look at something different to the usual, and hopefully very interesting and useful – interfacing our Arduino systems with infra-red receivers. Why would we want to do this? To have another method to control our Ardiuno-based systems, using simple infra-red remote controls.

A goal of this article is to make things as easy as possible, so we will not look into the base detail of how things work – instead we will examine how to get things done. If you would like a full explanation of infra-red, perhaps see the page on Wikipedia. The remote controls you use for televisions and so on transmit infra-red beam which is turned on and off at a very high speed – usually 38 kHz, to create bits of serial data which are then interpreted by the receiving unit. As the wavelength of infra-red light is too high for human eyes, we cannot see it. However using a digital camera – we can. Here is a demonstration video of IR codes being sent via a particularly fun kit – the adafruit TV-B-Gone:

Now to get started. You will need a remote control, and a matching IR receiver device. The hardware and library used in this tutorial only  supports NEC, Sony SIRC, Philips RC5, Philips RC6, and raw IR protocols. Or you can purchase a matching set for a good price, such as this example:


Or you may already have a spare remote laying around somewhere. I kept this example from my old Sony Trinitron CRT TV after it passed away:


It will more than suffice for a test remote. Now for a receiver – if you have purchased the remote/receiver set, you have a nice unit that is ready to be wired into your Arduino, and also a great remote that is compact and easy to carry about. To connect your receiver module – as per the PCB labels, connect Vcc to Arduino 5V, GND to Arduino GND, and D (the data line) to Arduino digital pin 11.

Our examples use pin 11, however you can alter that later on. If you are using your own remote control, you will just need a receiver module. These are very cheap, and an ideal unit is the Vishay TSOP4138 (data sheet .pdf). These are available from element-14 and the other usual retail suspects. They are also dead-simple to use. Looking at the following example:

From left to right the pins are data, GND and Vcc (to Arduino +5V). So it can be easily wired into a small breadboard for testing purposes. Once you have your remote and receiver module connected, you need to take care of the software side of things. There is a new library to download and install, download it from here. Please note that library doesn’t work for Arduino Leonardo, Freetronics Leostick, etc with ATmega32U4. Instead, use this library (and skip the modification steps below). Extract the IRremote folder and place into the ..arduinoxxxlibraries folder. Then restart your Arduino IDE if it was already open.

Using Arduino IDE v1.0 or greater? Open the file “IRRemoteInt.h” in the library folder, and change the line

#include "WProgram.h"

#include "Arduino.h"

Then save and close the file, restart the Arduino IDE and you’re set.

With our first example, we will receive the commands from our remote control and display them on the serial monitor:

// example 32.1 - IR receiver code repeater
// http://tronixstuff.com/tutorials > chapter 32
// based on code by Ken Shirriff - http://arcfn.com

#include <IRremote.h> // use the library
int receiver = 11; // pin 1 of IR receiver to Arduino digital pin 11
IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results;
void setup()
  Serial.begin(9600); // for serial monitor output
  irrecv.enableIRIn(); // Start the receiver
void loop()
  if (irrecv.decode(&results)) // have we received an IR signal?
    Serial.println(results.value, HEX); // display it on serial monitor in hexadecimal
    irrecv.resume(); // receive the next value
  }  // Your loop can do other things while waiting for an IR command

Open the serial monitor box, point your remote control to the receiver and start pressing away. You should see something like this:

What have we here? Lots of hexadecimal numbers. Did you notice that each button on your remote control resulted in an individual hexadecimal number? I hope so. The number FFFFFFFF means that the button was held down. The remote used was from a yum-cha discount TV. Now I will try again with the Sony remote:

This time, each button press resulted in the same code three times. This is peculiar to Sony IR systems. However nothing to worry about. Looking back at the sketch for example 32.1, the

if (irrecv.decode(&results))

section is critical – if a code has been received, the code within the if statement is executed. The hexadecimal code is stored in the variable


with which we can treat as any normal hexadecimal number. At this point, press a few buttons on your remote control, and take a note of the matching hexadecimal codes that relate to each button. We will need these codes for the next example…

Now we know how to convert the infra-red magic into numbers, we can create sketches to have our Arduino act on particular commands. As the IR library returns hexadecimal numbers, we can use simple decision functions to take action. In the following example, we use switch…case to examine each inbound code, then execute a function. In this case we have an LCD module connected via I2C, and the sketch is programmed to understand fifteen Sony IR codes. If you don’t have an LCD you could always send the output to the serial monitor. If you are using the DFRobot I2C LCD display, you need to use Arduino v23.

Furthermore you can substitute your own values if not using Sony remote controls. Finally, this sketch has a short loop after the translateIR(); function call which ignores the following two codes – we do this as Sony remotes send the same code three times. Again. you can remove this if necessary. Note that when using hexadecimal numbers in our sketch we preced them with 0x:

// example 32.2 - IR receiver code translator
// for Sony IR codes (ignores 2nd and 3rd signal repeat)
// http://tronixstuff.com/tutorials > chapter 32
// based on code by Ken Shirriff - http://arcfn.com

#include "Wire.h" // for I2C bus
#include "LiquidCrystal_I2C.h" // for I2C bus LCD module (http://www.dfrobot.com/wiki/index.php/I2C/TWI_LCD1602_Module_(SKU:_DFR0063))

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
#include <IRremote.h> // use the library for IR
int receiver = 11; // pin 1 of IR receiver to Arduino digital pin 11
IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results;
void setup()
  lcd.init();          // initialize the lcd
  lcd.backlight(); // turn on LCD backlight
  irrecv.enableIRIn(); // Start the receiver
void translateIR() // takes action based on IR code received
// describing Sony IR codes on LCD module
    case 0x37EE: lcd.println(" Favourite      "); break;
    case 0xA90: lcd.println(" Power button   "); break;
    case 0x290: lcd.println(" mute           "); break;
    case 0x10:  lcd.println(" one            "); break;
    case 0x810:  lcd.println("  two           "); break;
    case 0x410:  lcd.println(" three          "); break;
    case 0xC10:  lcd.println(" four           "); break;
    case 0x210:  lcd.println(" five           "); break;
    case 0xA10:  lcd.println(" six            "); break;
    case 0x610:  lcd.println(" seven          "); break;
    case 0xE10:  lcd.println(" eight          "); break;
    case 0x110:  lcd.println(" nine           "); break;
    case 0x910:  lcd.println(" zero           "); break;
    case 0x490:  lcd.println(" volume up      "); break;
    case 0xC90:  lcd.println(" volume down    "); break;
    case 0x90:   lcd.println(" channel up     "); break;
    case 0x890:  lcd.println(" channel down   "); break;
    default: lcd.println(" other button   ");
void loop()
  if (irrecv.decode(&results)) // have we received an IR signal?
    for (int z=0; z<2; z++) // ignore 2nd and 3rd signal repeat
      irrecv.resume(); // receive the next value

And here it is in action:

You might be thinking “why would I want to make things appear on the LCD like that?”. The purpose of the example is to show how to react to various IR commands. You can replace the LCD display functions with other functions of your choosing.

At the start working with infra-red may have seemed to be complex, but with the previous two examples it should be quite simple by now. So there you have it, another useful way to control our Arduino systems. Hopefully you have some ideas on how to make use of this technology. In future articles we will examine creating and sending IR codes from our Arduino. Furthermore, a big thanks to Ken Shirriff for his Arduino library.


Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.


  1. I have downloaded your sketch but get an error
    on the line
      IRrecv irrecv (RECV_PIN);
    it says IRrecv does not name a type
    what could be the problem

  2. Hi, The code works fine for my DSTV remote but returns “0” for all buttons on JVC (RM-C3116) and Samsung remotes. Any ideas on how to resolve this.

  3. collection\arduino\arduino-1.5.2\libraries\ArduinoIRremotemaster\IRremote.cpp:23: fatal error: avr/interrupt.h: No such file or directory
    this is the error im facing while vrifying and loading it into arduino due

    • Looks like you haven’t modified or installed the library correctly. The library needs to be in a folder called IRremote, and you need to change it as described in the tutorial.



Comments are closed.