Arduino UNO R3/MEGA 2560 R3 Project 14: IR Remote Control

Posted by Fiona Su on



What is an infrared receiver?
The signal from the infrared remote controller is a series of binary pulse code. To avoid interference from other infrared signals during the wireless transmission, the signal is pre-modulate at a specific carrier frequency and then send out by an infrared emission diode. The infrared receiving device needs to filter out other wave and receive signal at that specific frequency and modulate it back to binary pulse code, known as demodulation.
Working Principle:
The built-in receiver converts the light signal it received from the sender into feeble electrical signal. The signal will be amplified by the IC amplifier. After automatic gain control, band-pass filtering, demodulation, wave shaping, it returns to the original code. The code is then input to the code identification circuit by the receiver's signal output pin.
The pin and the connection of the infrared receiving head.
Pin and wiring of infrared receiver:



Infrared receiver has 3 pins.
When you use it, connect VOUT to analog pin, GND to GND, VCC to +5V.


Hardware Required

  • Infrared remote controller x1
  • Infrared receiver x1
  • LED x6
  • 220Ω resistor x6
  • Breadboard wire x 10

Video Tutorial

Connection Diagram:
First, connect the controller board; then connect the infrared receiver as the above mentioned, connect VOUT to digital pin 11, connect the LEDs with resistors and connect the resistors to pin2,3,4,5,6,7.

Connection for REV4:


Connection for 2560 R3:




Experimental Principle:
If you want to decode the code from a remote controller, you must first know how it's coded. The coding method we use here is NEC protocol. Below is a brief introduction.
NEC protocol:


(1) 8 bit address and 8 bit command length
(2) address and command are transmitted twice for reliability
(3) pulse distance modulation
(4) carrier frequency of 38 KHZ
(5) bit time of 1.125ms or 2.25ms
Protocol is as below:
Definition of logical 0 and 1 is as below


Pulse transmitted when button is pressed and immediately released.


The picture above shows a typical pulse train of the NEC protocol. With this protocol the LSB is transmitted first. In this case Address $59 and Command $16 is transmitted. A message is started by a 9ms AGC burst, which was used to set the gain of the earlier IR receivers. This AGC burst is then followed by a 4.5ms space, which is then followed by the address and command. Address and Command are transmitted twice. The second time all bits are inverted and can be used for verification of the received message. The total transmission time is constant because every bit is repeated with its inverted length. If you are not interested in this reliability, you can ignore the inverted values, or you can expend the Address and Command to 16 bits each!
Pulse transmitted when button is pressed and released after a period of time


A command is transmitted only once, even when the key on the remote control remains pressed. Every 110ms a repeat code is transmitted for as long as the key remains down. This repeat code is simply a 9ms AGC pulse followed by a 2.25ms space and a 560µs burst.
Repeat pulse


Note: when the pulse enters the integrated receiver, there will be decoding, signal amplifying and wave shaping process. So you need to make sure the level of the output is just the opposite from that of the signal sending end.
That is when there is no infrared signal, the output end is in high level; when there is infrared signal, the output end is in low level. You can see the pulse of the receiving end in the oscilloscope. Try to better understand the program base on what you see.

Sample Code:

Note: add IRremote folder into installation directory \Arduino\compiler libraries, or it will fail to compile.
For example:C:\Program Files\Arduino\libraries

#include <IRremote.h>
int RECV_PIN = 11;
int LED1 = 2;
int LED2 = 3;
int LED3 = 4;
int LED4 = 5;
int LED5 = 6;
int LED6 = 7;
long on1  = 0x00FF6897;
long off1 = 0x00FF9867;
long on2 = 0x00FFB04F;
long off2 = 0x00FF30CF;
long on3 = 0x00FF18E7;
long off3 = 0x00FF7A85;
long on4 = 0x00FF10EF;
long off4 = 0x00FF38C7;
long on5 = 0x00FF5AA5;
long off5 = 0x00FF42BD;
long on6 = 0x00FF4AB5;
long off6 = 0x00FF52AD;
IRrecv irrecv(RECV_PIN);
decode_results results;
// Dumps out the decode_results structure.
// Call this after IRrecv::decode()
// void * to work around compiler issue
//void dump(void *v) {
//  decode_results *results = (decode_results *)v
void dump(decode_results *results) {
  int count = results->rawlen;
  if (results->decode_type == UNKNOWN) 
     Serial.println("Could not decode message");
    if (results->decode_type == NEC) 
       Serial.print("Decoded NEC: ");
    else if (results->decode_type == SONY) 
       Serial.print("Decoded SONY: ");
    else if (results->decode_type == RC5) 
       Serial.print("Decoded RC5: ");
    else if (results->decode_type == RC6) 
       Serial.print("Decoded RC6: ");
     Serial.print(results->value, HEX);
     Serial.print(" (");
     Serial.print(results->bits, DEC);
     Serial.println(" bits)");
     Serial.print("Raw (");
     Serial.print(count, DEC);
     Serial.print("): ");
 for (int i = 0; i < count; i++) 
      if ((i % 2) == 1) {
      Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
      Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
    Serial.print(" ");
void setup()
  pinMode(RECV_PIN, INPUT);   
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  pinMode(LED5, OUTPUT);
  pinMode(LED6, OUTPUT);  
  pinMode(13, OUTPUT);
   irrecv.enableIRIn(); // Start the receiver
int on = 0;
unsigned long last = millis();

void loop() 
  if (irrecv.decode(&results)) 
    // If it's been at least 1/4 second since the last
    // IR received, toggle the relay
    if (millis() - last > 250) 
       on = !on;
//       digitalWrite(8, on ? HIGH : LOW);
       digitalWrite(13, on ? HIGH : LOW);
    if (results.value == on1 )
       digitalWrite(LED1, HIGH);
    if (results.value == off1 )
       digitalWrite(LED1, LOW); 
    if (results.value == on2 )
       digitalWrite(LED2, HIGH);
    if (results.value == off2 )
       digitalWrite(LED2, LOW); 
    if (results.value == on3 )
       digitalWrite(LED3, HIGH);
    if (results.value == off3 )
       digitalWrite(LED3, LOW);
    if (results.value == on4 )
       digitalWrite(LED4, HIGH);
    if (results.value == off4 )
       digitalWrite(LED4, LOW); 
    if (results.value == on5 )
       digitalWrite(LED5, HIGH);
    if (results.value == off5 )
       digitalWrite(LED5, LOW); 
    if (results.value == on6 )
       digitalWrite(LED6, HIGH);
    if (results.value == off6 )
       digitalWrite(LED6, LOW);        
    last = millis();      
irrecv.resume(); // Receive the next value

Program Function

Decode the coded pulse signal emitted by the remote controller, then execute corresponding action according to the results of the decoding.
In this way, you are able to control your device with remote control.





All Tutorial



Leave a comment

Please note, comments must be approved before they are published