IR Remote Controller

Overview

Infrared receivers are available to you through this course, and this is the primary method for using them: with a TV remote. This method of control is familiar and simple. Although it's not conducive to precise control, it can still be very useful for those simple tasks, like driving.

Parts

-Arduino microcontroller and carrier board

-LiPo battery

-220Ohm resistor

-IR receiver

-Universal remote

-Jumper wires

Prepare the breadboard

-IR Remote Control Theory

Program the Microcontroller

This code uses the SONY decoding:

// SIRCS (Sony IR Control System) Controller
//
// Jon McPhalen
// 06 DEC 2007
// Modified by Dan and Abigail Frey
// 26 MAR 2011
#define irPin 10
int key = 0;
//--- Function: Setup ()
void setup()
{
    pinMode(irPin, INPUT);
    Serial.begin(9600);
    delay(25);
    Serial.println("Setup Complete");
}
//--- Function: loop ()
void loop()
{
    key = getSircs();
    switch(key)
    {
        case 0x95: Serial.println("Power key pressed"); break;
        case 128: Serial.println("Key Press #1"); break;
        case 129: Serial.println("Key Press #2"); break;
        case 144: Serial.println("UP"); break;
        case 145: Serial.println("DOWN"); break;
        case 146: Serial.println("RIGHT"); break;
        case 147: Serial.println("LEFT"); break;
        case 148: Serial.println("MUTE"); break;
    }
    delay(5); // whatever delay you want such as to allow key release
}
//--- Function: getSircs ()
int getSircs()
{
    int duration;
    int irCode;
    int mask;
    // wait for start bit
    do {
        duration = pulseIn(irPin, LOW);
    } while (duration < 2160 || duration > 2640);
    // get 12-bit SIRCS code
    irCode = 0; // clear ir code
    mask = 1; // set mask to bit 0
    for (int idx = 0; idx < 12; idx++)
    {
        // get all 12 bits
        duration = pulseIn(irPin, LOW); // measure the bit pulse
        if (duration >= 1080) // 1 bit?
            irCode |= mask; // yes, update ir code
        mask <<= 1; // shift mask to next bit
    }

// Serial.print(irCode); // uncomment for debugging;

    return irCode;
}

Program the Microcontroller II

If you want to use a different encoder, Ken Shirriff's library supports NEC, Sony SIRC, Philips RC5,

Philips RC6, and raw protocols.

To install, unzip and place 'IRremote' folder into your

'C:\Users\{user name}\Documents\Arduino\libraries' folder or '{Arduino IDE path}\hardware\libraries"

or {Arduino IDE path}\libraries" (for MacOSX) directory.

Restart the Arduino IDE, and open up the example sketch.

Here is some sample code :

/**
 * @file: IR remote example
 * @author Daniela Faas (dfaas@mit.edu)
 * @date: 4/27/2011
 *
 * @section DESCRIPTION
 * adapted from:
 * http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
 * Please run the examples to explore the library and its funcitons. 
 */
// include additional headers
#include <IRremote.h>
// this would be whatever pin you want to use
const int RECV_PIN = 4;
IRrecv irrecv(RECV_PIN);
decode_results results;
int keypressed = NULL;  // stores button values 
//define which remote message you are using: SONY  NEC
#define WHICHREMOTE SONY
//--- Function: Setup ()
void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}
//--- Function: Loop ()
void loop() 
{
  if (irrecv.decode(&results))  // if we are receivng
  {
    getMessage(&results);      // lets print those messages
    irrecv.resume();           // Receive the next value
    // add your code here that allows you to drive your servos, etc
  }
}
//--- Function: getMessage ()
void getMessage(decode_results *results) 
{
  // we are only getting code defined through WHICHREMOTE, everything else is ignored!
  if (results->decode_type == WHICHREMOTE) 
  {
    printRemote(results->decode_type);
    //      Serial.print(results->value, DEC);
    //      Serial.print(" (");
    //      Serial.print(results->bits, DEC);
    //      Serial.println(" bits)");
  } 
  
  // note: button mappings are the same for both decoder types! 
  // now get which button is pressed
  if (results->decode_type == SONY) 
  {
    keypressed = returnSonyButton(results->value);
  }
  else if (results->decode_type == NEC) 
  {
    keypressed = returnNECButton(results->value);
  }
}
//--- Function: printRemote()
void printRemote(long unsigned int decoder)
{
  if (decoder == NEC)        Serial.print("NEC: ");  
  else if (decoder == SONY)  Serial.print("SONY: ");
  else if (decoder == RC5)   Serial.print("RC5: ");
  else if (decoder == RC6)   Serial.print("RC6: ");
}
//--- Function: returnSonyButton () 
int returnSonyButton(unsigned long value)
{
  unsigned long key = value; 
  int button;  // this stores the button pressed value
  switch(key)
  {
  case 2320: 
    Serial.println("Key Press #0"); 
    button = 0; 
    break;
  case 16: 
    Serial.println("Key Press #1"); 
    button = 1; 
    break;
  case 2064: 
    Serial.println("Key Press #2"); 
    button = 2; 
    break;
  case 1040: 
    Serial.println("Key Press #3"); 
    button = 3; 
    break;
  case 3088: 
    Serial.println("Key Press #4"); 
    button = 4; 
    break;
  case 528: 
    Serial.println("Key Press #5"); 
    button = 5; 
    break;
  case 2576: 
    Serial.println("Key Press #6"); 
    button = 6;
    break;
  case 1552: 
    Serial.println("Key Press #7"); 
    button = 7; 
    break;
  case 3600: 
    Serial.println("Key Press #8"); 
    button = 8; 
    break;
  case 272: 
    Serial.println("Key Press #9"); 
    button = 9; 
    break;
  case 144: 
    Serial.println("Channel UP"); 
    button = 10; 
    break;
  case 2192: 
    Serial.println("Channel DOWN"); 
    button = 11;
    break;
  case 1168: 
    Serial.println("Volume UP"); 
    button = 12; 
    break;
  case 3216: 
    Serial.println("Volume DOWN"); 
    button = 13; 
    break;
  case 656: 
    Serial.println("MUTE"); 
    button = 14; 
    break;
  case 3344: 
    Serial.println("Enter"); 
    button = 15; 
    break;
  case 3536: 
    Serial.println("Previous"); 
    button = 16; 
    break; 
  default:  
    Serial.println("unknown"); 
    button = 20; 
    break; 
  } 
  return button;  
}
//--- Function: returnSonyButton () 
int returnNECButton(unsigned long value)
{
  unsigned long key = value; 
  int button; // this stores the button pressed value
  switch(key)
  {
  case 551487735: 
    Serial.println("Key Press #0"); 
    button = 0; 
    break;
  case 551520375: 
    Serial.println("Key Press #1"); 
    button = 1; 
    break;
  case 551504055: 
    Serial.println("Key Press #2"); 
    button = 2; 
    break;
  case 551536695: 
    Serial.println("Key Press #3"); 
    button = 3; 
    break;
  case 551495895: 
    Serial.println("Key Press #4"); 
    button = 4; 
    break;
  case 551528535: 
    Serial.println("Key Press #5"); 
    button = 5; 
    break;
  case 551512215: 
    Serial.println("Key Press #6"); 
    button = 6;
    break;
  case 551544855: 
    Serial.println("Key Press #7"); 
    button = 7; 
    break;
  case 551491815: 
    Serial.println("Key Press #8"); 
    button = 8; 
    break;
  case 551524455: 
    Serial.println("Key Press #9"); 
    button = 9; 
    break;
  case 551485695: 
    Serial.println("Channel UP"); 
    button = 10; 
    break;
  case 551518335: 
    Serial.println("Channel DOWN"); 
    button = 11;
    break;
  case 551502015: 
    Serial.println("Volume UP"); 
    button = 12; 
    break;
  case 551534655: 
    Serial.println("Volume DOWN"); 
    button = 13; 
    break;
  case 551506095: 
    Serial.println("MUTE"); 
    button = 14; 
    break;
  case 551508135: 
    Serial.println("Previous"); 
    button = 16; 
    break; 
  default:  
    Serial.println("unknown"); 
    button = 20; 
    break; 
  } 
  return button;  
}