Arduino Project: 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 a 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 Principal:
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.

Next, we will do an infrared remote control experiment

Hardware Required:

  • Arduino Board *1
  • USB Cable *1
  • Remote Control*1
  • IR Receiver*1
  • Red M5 LED*2
  • Yellow M5 LED*2
  • Green M5 LED*2
  • 220Ω Resistor *6
  • Breadboard *1
  • Breadboard Jumper Wire*11

Connection for REV4:

Connection for 2560 R3:

Connect the motor to digital pin 9.
Compile a program to control the motor to rotate to the commanded angle input by the user and display the angle on the screen.

Experimental Principle:
If you want to decode code of 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 you will not be able to compile.
Infrared remote library:

#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; execute corresponding action according to the results of the decoding.
In this way, you will be able to control your device with remote controller.




Leave a comment

Please note, comments must be approved before they are published