Arduino – Redefining the TV Remote

We use them every day, but has no one got bored of pressing buttons on a stick, it’s far too much effort pressing buttons! Surely there are better ways to control a device? After doing some work with my Nikon camera using IR to control it, I wanted to do the same with other devices. Check out the video at the bottom of this post…

However, unlike the Nikon remote, my Samsung TV remote has many many buttons so each IR sequence sent from the remote will be different. This can be a problem when you want to decode the signals, which while not impossible I am lazy, so thankfully Ken Shirriff has built a library to do just that and while its built for TV remotes you can decode an IR signal to its raw pulses using it. Essentially the library senses IR and notes each pulse and gap between pulses, Kens library saves a lot of time and its well coded – I’ll cover the basics of it in a bit.

My idea is to capture the IR sequences and then using the Arduino send them by using different inputs other than buttons. My first idea is to use my SRF05 distance sensor (You can use any distance sensor) and the premise being that different distances from the sensor send different signals to the TV. So rather than pressing a button you just wave your hand above the sensor. Of course this is slightly limited but since I only have 5 channels (yep – only 5!) so it turned out to be quite feasible.

There are drawbacks to this of course – the main one being that you can only define so many actions in the sensors dectection range. But there is plenty of range to do the basics, power, sound and channel and by constantly measuring distances we can even say the direction of movement, up to down and vice versa, can have an effect on what signal to send. For example moving your hand closer to the sensor will change the channel down.

So first of all you may want to read some of my other tutorials/projects concerning IR and the SRF-05 and Sharp IR (it should also work well).
Arduino Nikon IR Intervalometer Camera Remote
– contains handy wiring diagram!
Arduino and Sharp GP2Y0A02 Infrared distance sensor

(Other Arduino projects and tutorials)

OK, next take a look at Ken Shirrifs IR library and guide here:

Arduino TV Remote Components

IR Diode
3pin (NPN) Phototransistor/ IR receiver (
Radio Shack 276-640 IR receiver, Panasonic PNA4602, Vishay TSOP4838 – or just get one out an old mouse)
SRF-05 (or any distance measuring device e.g. Sharp IR GP2Y0A02)
Jumper wires

Oh and stating the obvious but you’ll also need a T.V with working remote to steal the signals from – course you can use other remotes (stereos etc..)

The circuits themselves are very very easy to build, an IR LED to pin 3, a IR receiver to pin 11 and the SRF-05 I’ve plugged into pins 2 and 4. I have all of them in one breadboard and it works very well (see below).

Using Kens Arduino TV Remote Library

If you download the library and then unzip it to your Arduino/Libaries directory (older versions, I think its Arduino/hardware/libaries). The library assumes that your phototransistor/ IR receiver is on digital pin 11 and your IR diode is on digital pin 3. Typically you want a IR receiver with a 38Khz range – they seem to work best for me.

How to get our TV infrared/ remote codes

First of all use Ken’s IRrecvDump example (should be in your examples menu) load this into your Arduino and begin to capture your remotes codes. My Samsung wasn’t recognised so I used the Raw codes – there’s plenty of documentation on Ken’s site for this – it’s really simple, even I could figure it out. You need to note how many pulses etc.. it decodes in the raw signal which helpfully is outputted e.g. Raw (68):

Now we process the codes slightly and put them in an array for each one now that we have our codes and the information we need to use them – since mine are in the raw format I need to clean them up slightly ready to be put in my code – just adding commas etc…

Now we can test the remote codes to make sure you can control your TV

Now using the IRsendDemo example, altering it my case to send the raw signal, we can test the codes to make sure that we can control the T.V – just use the basic sketch to send the codes which I edited slightly just to use an array for the raw code. You can check out the library files themselves to see the functions.

 * IRremote: IRsendDemo - demonstrates sending IR codes with IRsend
 * An IR LED must be connected to Arduino PWM pin 3.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff


IRsend irsend;

// just added my own array for the raw signal
unsigned int powerOn[68] = {4450,4500,550,1700,500,1750,500,1750,500,600,550,600,500,600,550,600,500,600,550,1700,550,1700,550,1700,500,600,550,600,500,600,550,600,500,650,500,600,550,1700,500,650,500,600,550,600,500,600,550,600,500,600,550,1700,550,600,500,1700,550,1700,550,1700,550,1700,500,1750,500,1750,500};

void setup()

void loop() {

      // altered the code just to send/test my raw code


Add the distance sensor

This is actually the hardest bit and it’s not that hard really I just used my previous work and adapted it and wrote a few statements concerning the detected distance. You just have to spend some time debugging and getting your values right to ensure that your commands are only sent at the right time and that it doesn’t get confused. My code is still a little buggy if you’re not used to how to move your hand but it does work well once you’re used to it.

[ad#Google Ad in content]

    Larrys alternative TV remote - oops no buttons!
    Sends signals to TV based upon sensor readings

    Makes use of Kens Shirriffs IRremote library
    An IR LED must be connected to Arduino PWM pin 3.
    Version 0.1 July, 2009
    Copyright 2009 Ken Shirriff

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see .

IRsend irsend;

const int numReadings = 5;   // set a variable for the number of readings to take
int index = 0;                // the index of the current reading
int total = 0;                // the total of all readings
int average = 0;              // the average
int oldAverage = 0;           // the old average
int echoPin = 2;              // the SRF05's echo pin
int initPin = 4;              // the SRF05's init pin
unsigned long pulseTime = 0;  // variable for reading the pulse
unsigned long distance = 0;   // variable for storing distance

// setup my arrays for each signal I want to send
unsigned int powerOn[68] = {4450,4500,550,1700,500,1750,500,1750,500,600,550,600,500,600,550,600,500,600,550,1700,550,1700,550,1700,500,600,550,600,500,600,550,600,500,650,500,600,550,1700,500,650,500,600,550,600,500,600,550,600,500,600,550,1700,550,600,500,1700,550,1700,550,1700,550,1700,500,1750,500,1750,500};
unsigned int soundUp[68] = {4450,4500,550,1700,550,1700,500,1750,500,600,550,600,500,600,550,600,500,600,550,1700,550,1700,550,1700,500,650,500,600,550,600,500,600,550,600,500,1750,500,1700,550,1700,550,600,500,600,550,600,500,600,550,600,500,600,550,600,550,600,500,1700,550,1700,550,1700,550,1700,500,1750,500};
unsigned int soundDown[68] = {4400,4550,500,1750,500,1700,550,1700,550,600,500,600,550,600,500,600,550,600,500,1750,500,1750,500,1700,550,600,500,650,500,600,550,600,500,600,550,1700,550,1700,500,600,550,1700,550,600,500,600,550,600,500,600,550,600,500,600,550,1700,550,600,500,1750,500,1750,500,1700,550,1700,550};
unsigned int channelUp[68] = {4400,4550,500,1700,550,1700,550,1700,550,600,500,600,550,600,500,600,550,600,500,1750,500,1700,550,1700,550,600,500,600,550,600,500,650,500,600,550,600,500,1700,550,600,550,600,500,1700,550,600,500,650,500,600,550,1700,500,600,550,1700,550,1700,550,600,500,1700,550,1700,550,1700,550};
unsigned int channelDown[68] = {4450,4500,500,1750,500,1750,500,1700,550,600,500,650,500,600,550,600,500,600,550,1700,500,1750,500,1750,500,600,550,600,500,600,550,600,500,600,550,600,500,650,500,600,550,600,500,1700,550,600,500,650,500,600,500,1750,500,1750,500,1750,500,1700,550,600,500,1750,500,1750,500,1700,550};

void setup() {
  // make the init pin an output:
  pinMode(initPin, OUTPUT);
  // make the echo pin an input:
  pinMode(echoPin, INPUT);
  // initialize the serial port:

 void loop() {

    // loop for a number of readings on the SRF-05 to get an average to smooth the results. Much like all my other examples
    for (index = 0; index<=numReadings;index++) {
      digitalWrite(initPin, LOW);
      digitalWrite(initPin, HIGH);
      digitalWrite(initPin, LOW);
      pulseTime = pulseIn(echoPin, HIGH);
      distance = pulseTime/58;
      total = total + distance;
    // store the previous reading
    oldAverage = average;
    // store the current reading
    average = total/numReadings;
    // debug to check for spikes in the sensor etc..

    // now the fun part...
    // if my distance is less than 5...
    if (average <= 5) {
      Serial.println("Power Off");
      // use Kens IR library to send my signal (array, number of items in array, Khz)
      // these delays depend on how long it take my device to recognise the signal sent and to act - I don't want to send signals that aren't getting read etc..
      // otherwise if my hand is higher
    } else {
      // check to see if my hand is in the registered space above the sensor
      if (average <=20 && average >=10 && oldAverage >=10) {
        // the below statement is our sensitive the readings are so if the current and previous readings are different with a tolerance of +/- 1 we can look at the direction of movement
        if ((average != oldAverage)
        && (average+1 != oldAverage)
        && (average-1 != oldAverage)) {
          // if the current reading is higher than the previous, then my hand is moving upwards
          if (average > oldAverage) {
            Serial.println("Channel Up");
          } else {
            // otherwise if it is below then my hand is moving downwards
            if (average < oldAverage && oldAverage <=20) {               Serial.println("Channel Down");               irsend.sendRaw(channelDown,68,38);               delay(2000);                        }                  }          // otherwise my hand must be stationary so check where it is.         } else {           // if my hand is stationary between 10 and 15 cms away from the sensor           if (average >= 10 && average <=15) {             Serial.println("Sound down");             irsend.sendRaw(soundDown,68,38);           } else {             // if my hand is a bit higher up...             if (average >= 16 && average <=20) {               Serial.println("Sound up");               irsend.sendRaw(soundUp,68,38);             }           }         }         }     }        // clear our index and total for the next reading just in case     if (index >= numReadings)  {
      index = 0;
      total = 0;

[ad#Google Ad in content]


  • Saw this on HAD. Been looking for something like this for a while. My intention is to create a WebOS app or Web interface that suppliments my remote control. I couldnt figure out how to get my arduino to ‘save’ and ‘replay’ IR codes. This seems to do exactly that. Great writeup!

    • Cool, should be fairly easy to do from the web – just send the codes via Processing on the serial port. It’s very useful library I found for decoding IR.

  • How did you exactly manage to “clean them up” ? I can’t seem to get a hold of it -.-‘ (which bytes to delete and so on)

  • Good stuff LuckyLarry. This helped me enormously, I would have been totally lost without Kens library. Have you thought about using to SFR05 to create a 3D controller? Just an idea.

    @Henrik – Use PuTTY – download it and set it monitor COM4 (arduino) then just cut and paste into a string seperating each number with a comma.

  • Superb Work! 🙂

  • * An IR LED must be connected to Arduino PWM pin 3. Why?, any other option to connected to another PWM Pin ?

    Thank You

  • Good work, i look forward to implement this and might come back here with questions.

  • I am using arduino version 22

    022 paste version of the program after the following error.

    How can I change it to?thanks

    sketch_nov10c.cpp:1:9: error: #include expects “FILENAME” or
    sketch_nov10c:1: error: ‘IRsend’ does not name a type
    sketch_nov10c.cpp: In function ‘void loop()’:
    sketch_nov10c:32: error: ‘lt’ was not declared in this scope
    sketch_nov10c:32: error: expected primary-expression before ‘=’ token
    sketch_nov10c:32: error: expected `)’ before ‘;’ token
    sketch_nov10c:32: error: expected `;’ before ‘)’ token
    sketch_nov10c:52: error: ‘lt’ was not declared in this scope
    sketch_nov10c:52: error: expected `)’ before ‘;’ token
    sketch_nov10c:52: error: expected primary-expression before ‘=’ token
    sketch_nov10c:52: error: expected `;’ before ‘)’ token
    sketch_nov10c:59: error: ‘else’ without a previous ‘if’
    sketch_nov10c:61: error: ‘lt’ was not declared in this scope
    sketch_nov10c:61: error: expected `)’ before ‘;’ token
    sketch_nov10c:61: error: expected primary-expression before ‘=’ token
    sketch_nov10c:61: error: ‘amp’ was not declared in this scope
    sketch_nov10c:61: error: ‘gt’ was not declared in this scope
    sketch_nov10c:61: error: expected primary-expression before ‘=’ token
    sketch_nov10c:61: error: expected primary-expression before ‘=’ token
    sketch_nov10c:61: error: expected `;’ before ‘)’ token
    sketch_nov10c:77: error: expected `}’ at end of input
    sketch_nov10c:77: error: expected `}’ at end of input

  • This cleared up a lot, coz no matter how good Ken’s library is, the description is a bit vague mow and then. Just one question: How to handle the negative values. You have those in one of yr pictures (and I have them as well) but they seemed to have disappeared in the codes that you eventually used. How does one ‘clean up’ ‘-16202’?

  • Great tutorial,

    1 question,

    i have a little project myself. A coffeetable, 1 arduino, 2 led strips, a distence sensor, light sensor, ir receiver, robot voice, and one massive self made max/msp patch so that it can give me feedbank when i control it with my voice and can warn me about weather ( downloads weather rss feed ) and some other stuff ( ask me for the exact details ).But i can’t get my IR working.. and it’s because of max/msp i think.

    the question is, have you got any idea how to tranmist the right frequency intervals with max/msp ? using just a simple ir led like you?

    sorry for the bad english, i’m a dutch student and i’m very very interested!

  • Hi !
    I have a question. How you receive the signal in Raw (68) can you share your arduino code ?
    Thx and good job.

  • In fact, i have receive ir code like for apple tv up button : 2011254853 but now i want send this code to IR Led and i don’t know how do !
    Can you help me ?


  • Hi, my congratulations it’s a very good proyect. I’m trying to make a similar proyect but I want that when I press a botton Arduino send the code but when I try to decode a botton and press this botton more than one time Arduino write in the serial monitor, differents codes (the codes are similar but no identical). I don’t know if it can be caused for I’m using a 35 Khz receiver or because the program can’t decode my projector’s control remote. What do you think? I need make this proyect because is a proyect for the secondary school. Thanks, I hope your answer.

  • Hey I am a beginner to Arduino. We tried out your circuit for Getting the remote control codes. The problem we faced was that when we connected our circuit the Arduino power would go out.
    We connected it to the 3V power supply , that time the Arduino didn’t switch off but nothing was being detected. Also the IR receiver was heated in both the cases.
    Thinking of a current overflow, we added resistors to limit the current but it’s still not working. Could you help us out.

  • hey this is exactly what im looking for, but after importing the library an i go to verify the code it comes back with an error something about volatile struct riparams_t has no member name ‘rawlen’, any ideas

    thanks Newbie.

  • Yao , nice site 🙂

    I am wondering if you can use the same technique to capture signals from cars remote control, and use arduino to lock/unlock the car.

  • Not understanding how you “processed the code” please explain more.

You must be logged in to post a comment.