How to Use a TV Remote as Input Device in Your Arduino DIY Project (Video)
When you want to incorporate short-range wireless communication in a project, infrared signal is one of the protocols you can consider. Infrared communication is the use of a modulated low-frequency light signal that can be used for short-range wireless communication between devices. It is the technology used by TV remote controls to operate a Tv remotely. There are multiple other devices that utilize the infrared remote controls as input devices.
Similarly, you can use an existing IR remote control as input in your project. All you need is a simple IR sensor circuit and a microcontroller. The IR sensor circuit detects the IR signal from the remote control while the microcontroller runs the code that helps to decode the PWM-encoded IR signal. Once you have decoded the IR signal, you can then repurpose it to control certain outputs in your DIY project such as the lights in your house. In this project, you will learn how to control LEDs in your Arduino project using specific buttons of a TV remote control.
Parts
- 1 IR photosensor (PNA4602)
- Connector wires
- 4 LED
- 4 Current limiting resistors (100ohms – 220ohms)
- Breadboard
Circuit Diagram

Code
/* Raw IR commander
This sketch/program uses the Arduino and a PNA4602 to
decode IR received. It then attempts to match it to a previously
recorded IR signal
Code is public domain, check out www.ladyada.net and adafruit.com
for more tutorials!
*/
// We need to use the 'raw' pin reading methods
// because timing is very important here and the digitalRead()
// procedure is slower!
//uint8_t IRpin = 2;
// Digital pin #2 is the same as Pin D2 see
// http://arduino.cc/en/Hacking/PinMapping168 for the 'raw' pin mapping
#define IRpin_PIN PIND
#define IRpin 2
#define DEBUG ON
// the maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000
#define NUMPULSES 50
// what our timing resolution should be, larger is better
// as its more 'precise' - but too large and you wont get
// accurate timing
#define RESOLUTION 20
// What percent we will allow in variation to match the same code
#define FUZZINESS 20
// we will store up to 100 pulse pairs (this is -a lot-)
uint16_t pulses[NUMPULSES][2]; // pair is high and low pulse
uint8_t currentpulse = 0; // index for pulses we're storing
int buttonOnePin = 12;
int buttonTwoPin = 8;
int buttonThreePin = 7;
int buttonOnePinStatus;
int buttonThreePinStatus;
int buttonTwoPinStatus;
boolean powerStatus = true;
/** IR Codes **/
int buttonOne[] = {
// ON, OFF (in 10's of microseconds)
464, 454,
62, 168,
52, 176,
52, 176,
52, 62,
60, 54,
62, 52,
54, 60,
62, 52,
54, 174,
54, 176,
60, 168,
60, 54,
52, 62,
60, 54,
60, 54,
52, 62,
60, 54,
54, 60,
54, 174,
62, 168,
60, 54,
52, 176,
52, 176,
52, 62,
60, 168,
60, 168,
54, 62,
52, 62,
52, 176,
52, 62,
52, 62,
60, 168,
52, 0};
int buttonTwo[] = {
// ON, OFF (in 10's of microseconds)
464, 456,
60, 168,
62, 166,
62, 166,
62, 52,
62, 52,
62, 52,
62, 54,
60, 54,
60, 168,
60, 168,
62, 166,
62, 52,
62, 52,
62, 52,
62, 52,
62, 52,
62, 52,
62, 52,
62, 168,
60, 52,
62, 168,
60, 54,
60, 54,
62, 52,
60, 168,
62, 166,
62, 52,
62, 166,
62, 52,
62, 168,
60, 168,
60, 168,
60, 0};
int buttonThree[] = {
// ON, OFF (in 10's of microseconds)
464, 454,
62, 168,
60, 168,
60, 168,
52, 62,
62, 52,
60, 54,
62, 52,
60, 54,
60, 168,
62, 168,
60, 168,
60, 54,
60, 54,
60, 54,
60, 54,
60, 54,
60, 168,
52, 62,
62, 166,
62, 52,
62, 166,
62, 54,
60, 54,
52, 62,
60, 54,
60, 168,
60, 54,
60, 168,
62, 52,
62, 166,
60, 168,
62, 168,
60, 0};
int PowerButtonSignal[] = {
// ON, OFF (in 10's of microseconds)
464, 454,
62, 168,
60, 168,
60, 168,
60, 54,
62, 52,
62, 52,
62, 52,
62, 52,
62, 166,
62, 168,
60, 168,
60, 54,
60, 54,
62, 52,
62, 52,
62, 52,
62, 52,
62, 166,
62, 54,
60, 54,
60, 54,
60, 54,
60, 54,
60, 54,
60, 168,
62, 52,
62, 166,
62, 168,
60, 168,
60, 168,
60, 168,
62, 166,
62, 0};
/** end of IR codes **/
void setup(void) {
pinMode(buttonOnePin, OUTPUT);
pinMode (buttonThreePin, OUTPUT);
pinMode(buttonTwoPin, OUTPUT);
Serial.begin(9600);
Serial.println("Ready to decode IR!");
}
void loop(void) {
int numberpulses;
numberpulses = listenForIR();
Serial.print("Heard ");
Serial.print(numberpulses);
Serial.println("-pulse long IR signal");
if (IRcompare(numberpulses, buttonOne,sizeof(buttonOne)/4)&& numberpulses > 1) {
buttonOnePinStatus++;
Serial.println(buttonOnePinStatus);
if (buttonOnePinStatus == 1){
Serial.println("PLAY ON");
digitalWrite(buttonOnePin, HIGH);
}else if (buttonOnePinStatus == 2){
Serial.println("PLAY OFF");
digitalWrite(buttonOnePin, LOW);
} else{
buttonOnePinStatus = 0;
}
}
if (IRcompare(numberpulses, buttonThree,sizeof(buttonThree)/4)&& numberpulses > 1) {
buttonThreePinStatus++;
Serial.println(buttonThreePinStatus);
if (buttonThreePinStatus == 1){
Serial.println("REWIND ON");
digitalWrite(buttonTwoPin, HIGH);
}else if (buttonThreePinStatus == 2){
Serial.println("REWIND OFF");
digitalWrite(buttonTwoPin, LOW);
} else{
buttonThreePinStatus = 0;
}
}
if (IRcompare(numberpulses, buttonTwo,sizeof(buttonTwo)/4)&& numberpulses > 1) {
buttonTwoPinStatus++;
Serial.println(buttonTwoPinStatus);
if (buttonTwoPinStatus == 1){
Serial.println("FORWARD ON");
digitalWrite(buttonThreePin, HIGH);
}else if (buttonTwoPinStatus == 2){
Serial.println("FORWARD OFF");
digitalWrite(buttonThreePin, LOW);
} else{
buttonTwoPinStatus = 0;
}
}
if (IRcompare(numberpulses, PowerButtonSignal,sizeof(PowerButtonSignal)/4)&& numberpulses > 1) {
buttonOnePinStatus = buttonThreePinStatus = buttonTwoPinStatus = 0;
if(powerStatus){
digitalWrite(buttonOnePin, LOW);
digitalWrite(buttonTwoPin, LOW);
digitalWrite(buttonThreePin, LOW);
powerStatus = false;
}else{
digitalWrite(buttonOnePin, HIGH);
digitalWrite(buttonTwoPin, HIGH);
digitalWrite(buttonThreePin, HIGH);
powerStatus = true;
}
}
}
//KGO: added size of compare sample. Only compare the minimum of the two
boolean IRcompare(int numpulses, int Signal[], int refsize) {
int count = min(numpulses,refsize);
Serial.print("count set to: ");
Serial.println(count);
for (int i=0; i< count-1; i++) {
int oncode = pulses[i][1] * RESOLUTION / 10;
int offcode = pulses[i+1][0] * RESOLUTION / 10;
#ifdef DEBUG
Serial.print(oncode); // the ON signal we heard
Serial.print(" - ");
Serial.print(Signal[i*2 + 0]); // the ON signal we want
#endif
// check to make sure the error is less than FUZZINESS percent
if ( abs(oncode - Signal[i*2 + 0]) <= (Signal[i*2 + 0] * FUZZINESS / 100)) {
#ifdef DEBUG
Serial.print(" (ok)");
#endif
} else {
#ifdef DEBUG
Serial.print(" (x)");
#endif
// we didn't match perfectly, return a false match
return false;
}
#ifdef DEBUG
Serial.print(" \t"); // tab
Serial.print(offcode); // the OFF signal we heard
Serial.print(" - ");
Serial.print(Signal[i*2 + 1]); // the OFF signal we want
#endif
if ( abs(offcode - Signal[i*2 + 1]) <= (Signal[i*2 + 1] * FUZZINESS / 100)) {
#ifdef DEBUG
Serial.print(" (ok)");
#endif
} else {
#ifdef DEBUG
Serial.print(" (x)");
#endif
// we didn't match perfectly, return a false match
return false;
}
#ifdef DEBUG
Serial.println();
#endif
}
// Everything matched!
return true;
}
int listenForIR(void) {
currentpulse = 0;
while (1) {
uint16_t highpulse, lowpulse; // temporary storage timing
highpulse = lowpulse = 0; // start out with no pulse length
// while (digitalRead(IRpin)) { // this is too slow!
while (IRpin_PIN & (1 << IRpin)) {
// pin is still HIGH
// count off another few microseconds
highpulse++;
delayMicroseconds(RESOLUTION);
// If the pulse is too long, we 'timed out' - either nothing
// was received or the code is finished, so print what
// we've grabbed so far, and then reset
// KGO: Added check for end of receive buffer
if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
return currentpulse;
}
}
// we didn't time out so lets stash the reading
pulses[currentpulse][0] = highpulse;
// same as above
while (! (IRpin_PIN & _BV(IRpin))) {
// pin is still LOW
lowpulse++;
delayMicroseconds(RESOLUTION);
// KGO: Added check for end of receive buffer
if (((lowpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
return currentpulse;
}
}
pulses[currentpulse][1] = lowpulse;
// we read one high-low pulse successfully, continue!
currentpulse++;
}
}
void printpulses(void) {
Serial.println("\n\r\n\rReceived: \n\rOFF \tON");
for (uint8_t i = 0; i < currentpulse; i++) {
Serial.print(pulses[i][0] * RESOLUTION, DEC);
Serial.print(" usec, ");
Serial.print(pulses[i][1] * RESOLUTION, DEC);
Serial.println(" usec");
}
// print it in a 'array' format
Serial.println("int IRsignal[] = {");
Serial.println("// ON, OFF (in 10's of microseconds)");
for (uint8_t i = 0; i < currentpulse-1; i++) {
Serial.print("\t"); // tab
Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);
Serial.print(", ");
Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);
Serial.println(",");
}
Serial.print("\t"); // tab
Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);
Serial.print(", 0};");
}