
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
SRF-05 – 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:
http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
Arduino TV Remote Components
Arduino
Breadboard
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 * http://arcfn.com */ #include 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() { Serial.begin(9600); } void loop() { // altered the code just to send/test my raw code irsend.sendRaw(powerOn,68,38); delay(100); }
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.
/* http://luckylarry.co.uk 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 http://arcfn.com 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 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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 . */ #include 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: Serial.begin(9600); } 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); delayMicroseconds(50); digitalWrite(initPin, HIGH); delayMicroseconds(50); digitalWrite(initPin, LOW); pulseTime = pulseIn(echoPin, HIGH); distance = pulseTime/58; total = total + distance; delay(10); } // store the previous reading oldAverage = average; // store the current reading average = total/numReadings; // debug to check for spikes in the sensor etc.. Serial.println(average); // 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) irsend.sendRaw(powerOn,68,38); // 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.. delay(5000); // 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"); irsend.sendRaw(channelUp,68,38); delay(2000); } 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; } }
This content is published under the Attribution-Noncommercial-Share Alike 3.0 Unported license.
- Arduino – IR remote/ intervalometer for Nikon D80 DSLR (that means timelapse photography yarrr!)
- Arduino + Processing: Make a Radar Screen to Visualise Sensor Data from SRF-05 – Part 2: Visualising the Data
- Arduino + Processing – Make a Radar Screen to Visualise Sensor Data from SRF-05 – Part 1: Setting up the Circuit and Outputting Values
- Arduino – Sonic range finder with SRF05
- Obstacle avoidance Arduino robot – build your own larryBot
- larryBot – Arduino robot versions 0.1 to 0.5 lessons learned
- Arduino & Processing – Getting values from SRF05 ultrasound sensor & serial port
- Arduino – A Basic Theremin
- Arduino – motion triggered camera
- Arduino + Processing – 3D Sensor Data Visualisation



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 ?
Thx
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.