Hello guys, In this tutorial we will see how to control TV with your gesture. You can use your gesture as a TV remote controller. So lets get started.

For this project you will need,

  1. Arduino Uno, or Arduino MEGA,
  2. Gesture Sensor PAJ7620 or APDS-9960
  3. IR Infrared Receiver,
  4. IR Transmitter,
  5. Jumper Wires.
  6. 220ohms resistance,
  7. Breadboard.

I wanted to do this project with arduino nano with small box that contain everything battery sensor etc.

small box for gesture control TV

But there was problem with arduino nano such as memory issue as well as stability issues. So I am using Arduino Uno for this project.

Find TV remote codes:

Do connection as shown in diagram for finding TV remote values.

IR receiver circuit

Upload the code IRrecvDump from IR remote library.

IR library IRrecvDump

We will find our TV remote codes for ON/OFF button, Voulme Up/Down and Channel Forward and backward button. If you want, you can add more buttons but you have to use arduino Mega for this.

press button in front of IR receiver

Press button in front of IR receiver few times, If you are getting constant values then copy that codes.

hexadecimal number should not change

Constant Hexadecimal Number

Copy this IR code

If you are not getting constant values, it means IR receiver is not connected properly. Make sure values are in correct format like this, separated with comma and without negative sign.

{8950, 4300, 650, 1550, 650, 450, 600, 500, 600, 500, 600, 500, 650, 450, 650, 450, 650, 450, 650, 1550, 650, 450, 650, 1550, 650, 1550, 650, 1550, 600, 1550, 650, 1550, 650, 1550, 650, 450, 600, 500, 600, 1600, 650, 1550, 650, 1550, 600, 500, 600, 1550, 650, 1550, 650, 1550, 650, 1550, 650, 450, 600, 500, 600, 500, 600, 1600, 650, 450, 600, 500, 600};

Add this code to our main sketch for Gesture control TV remote.

Testing IR codes working or not?

Now we will see IR transmitter is sending correct values to IR receiver or not. We can see with every gesture it is sending correct values with slightest difference. It doesn’t matter as far as hexadecimal number doesn’t change.

Testing IR sensor

Later i changed ON/OFF to my SONY TV remote and other buttons are from my setup box remote. If you add five buttons or more with 68 elements. It will not work due to low memory and stability. You have to use Arduino mega. Same code will work perfectly fine for arduino Mega.

getting error with arduino uno and nano

Do connection as shown in diagram for Gesture control TV remote.

gesture control TV remote circuit l

Download Libraries:

Download PAJ7620 library and IR remote library from github in your computer OR you can download it from here because github library may change by the time or it may not work.

Download library for Gesture_PAJ7620-master.zip

Download library for Arduino-IRremote-master.zip

Sketch for Gesture Control TV Remote
#include <Wire.h>
#include "paj7620.h"
#include <IRremote.h>

IRsend irsend;

#define GES_REACTION_TIME 500 // You can adjust the reaction time according to the actual circumstance.
#define GES_ENTRY_TIME 800 // When you want to recognize the Forward/Backward gestures, your gestures' reaction time must less than GES_ENTRY_TIME(0.8s). 
#define GES_QUIT_TIME 1000

unsigned int TvOnOff[26] = {2450, 550, 1250, 550, 700, 450, 1300, 500, 700, 500, 1250, 550, 650, 500, 700, 500, 1300, 500, 650, 550, 650, 550, 650, 500, 650};
unsigned int volumeUp[68] = {8900, 4400, 600, 1600, 550, 550, 600, 500, 600, 500, 600, 500, 600, 500, 600, 500, 650, 500, 550, 1600, 600, 550, 550, 1600, 600, 1600, 600, 1600, 600, 1600, 550, 1650, 550, 1650, 550, 550, 550, 550, 550, 550, 550, 550, 600, 500, 600, 500, 600, 500, 600, 1600, 600, 1600, 600, 1600, 550, 1650, 550, 1650, 550, 1650, 550, 1650, 550, 1600, 600, 500, 600};
unsigned int volumeDown[68] = {8950, 4350, 650, 1550, 600, 500, 600, 500, 650, 450, 650, 450, 650, 450, 650, 400, 700, 450, 650, 1550, 650, 450, 650, 1550, 650, 1550, 650, 1550, 650, 1550, 650, 1500, 650, 1550, 650, 1550, 650, 450, 650, 450, 650, 450, 650, 500, 650, 450, 650, 450, 650, 1550, 650, 450, 650, 1550, 650, 1550, 600, 1550, 650, 1550, 650, 1550, 650, 1550, 650, 450, 650};
unsigned int channelForward[68] = {8950, 4300, 650, 1550, 650, 450, 650, 450, 650, 450, 700, 400, 650, 450, 700, 400, 650, 500, 600, 1550, 650, 450, 700, 1500, 650, 1550, 650, 1550, 650, 1550, 650, 1500, 700, 1500, 700, 1500, 650, 450, 650, 1550, 650, 450, 650, 450, 650, 450, 650, 450, 650, 1550, 650, 450, 650, 1550, 650, 450, 650, 1550, 600, 1600, 650, 1500, 650, 1550, 650, 450, 650}; 
unsigned int channelBackward[68] = {8950, 4350, 650, 1550, 650, 450, 650, 450, 650, 450, 650, 450, 650, 450, 650, 450, 650, 450, 650, 1550, 650, 450, 650, 1550, 650, 1550, 650, 1500, 700, 1500, 650, 1550, 650, 1550, 650, 450, 650, 1550, 650, 1550, 600, 500, 650, 450, 650, 450, 650, 450, 650, 1550, 650, 1500, 700, 400, 700, 400, 700, 1500, 650, 1550, 650, 1550, 650, 1550, 650, 450, 600};

void setup()
{
uint8_t error = 0;
Serial.begin(9600);
Serial.println("\nPAJ7620U2 TEST DEMO: Recognize 9 gestures.");
error = paj7620Init(); // initialize Paj7620 registers
if (error) 
{
Serial.print("INIT ERROR,CODE:");
Serial.println(error);
}
else
{
Serial.println("INIT OK");
}
Serial.println("Please input your gestures:\n");
}

void loop()
{

uint8_t data = 0, data1 = 0, error;
error = paj7620ReadReg(0x43, 1, &data); // Read Bank_0_Reg_0x43/0x44 for gesture result.

if (!error) 
{
switch (data) // When different gestures be detected, the variable 'data' will be set to different values by paj7620ReadReg(0x43, 1, &data).
{
case GES_RIGHT_FLAG:
delay(GES_ENTRY_TIME);
paj7620ReadReg(0x43, 1, &data);
if(data == GES_FORWARD_FLAG) 
{
Serial.println("Forward");
irsend.sendRaw(TvOnOff, 26, 38);
delay(GES_QUIT_TIME);
}
else if(data == GES_BACKWARD_FLAG) 
{
Serial.println("Backward");
irsend.sendRaw(TvOnOff, 26, 38);
delay(GES_QUIT_TIME);
}
else
{
Serial.println("Right");
irsend.sendRaw(channelForward, 68, 38);
//delay(GES_QUIT_TIME);
} 
break;
case GES_LEFT_FLAG: 
delay(GES_ENTRY_TIME);
paj7620ReadReg(0x43, 1, &data);
if(data == GES_FORWARD_FLAG) 
{
Serial.println("Forward");
irsend.sendRaw(TvOnOff, 26, 38);
delay(GES_QUIT_TIME);
}
else if(data == GES_BACKWARD_FLAG) 
{
Serial.println("Backward");
irsend.sendRaw(TvOnOff, 26, 38);
delay(GES_QUIT_TIME);
}
else
{
Serial.println("Left");
irsend.sendRaw(channelBackward, 68, 38);
//delay(GES_QUIT_TIME);
} 
break;
case GES_UP_FLAG:
delay(GES_ENTRY_TIME);
paj7620ReadReg(0x43, 1, &data);
if(data == GES_FORWARD_FLAG) 
{
Serial.println("Forward");
irsend.sendRaw(TvOnOff, 26, 38);
delay(GES_QUIT_TIME);
}
else if(data == GES_BACKWARD_FLAG) 
{
Serial.println("Backward");
irsend.sendRaw(TvOnOff, 26, 38);
delay(GES_QUIT_TIME);
}
else
{
Serial.println("Up");
irsend.sendRaw(volumeUp, 68, 38);

//delay(GES_QUIT_TIME);
} 
break;
case GES_DOWN_FLAG:
delay(GES_ENTRY_TIME);
paj7620ReadReg(0x43, 1, &data);
if(data == GES_FORWARD_FLAG) 
{
Serial.println("Forward");
irsend.sendRaw(TvOnOff, 26, 38);
delay(GES_QUIT_TIME);
}
else if(data == GES_BACKWARD_FLAG) 
{
Serial.println("Backward");
irsend.sendRaw(TvOnOff, 26, 38);
delay(GES_QUIT_TIME);
}
else
{
Serial.println("Down");
irsend.sendRaw(volumeDown, 68, 38);

//delay(GES_QUIT_TIME);
} 
break;
case GES_FORWARD_FLAG:
Serial.println("Forward");
irsend.sendRaw(TvOnOff, 26, 38);
delay(GES_QUIT_TIME);
break;
case GES_BACKWARD_FLAG: 
Serial.println("Backward");
irsend.sendRaw(TvOnOff, 26, 38);
delay(GES_QUIT_TIME);
break;
case GES_CLOCKWISE_FLAG:
Serial.println("Clockwise");
irsend.sendRaw(volumeUp, 68, 38);

break;
case GES_COUNT_CLOCKWISE_FLAG:
Serial.println("anti-clockwise");
irsend.sendRaw(volumeDown, 68, 38);

break; 
default:
paj7620ReadReg(0x44, 1, &data1);
if (data1 == GES_WAVE_FLAG) 
{
Serial.println("wave");
}
break;
}
}
delay(100);
}
Sketch Explanation:

Coding part is simple. You have to add Gesture sensor and IR remote library.

#include "paj7620.h"
#include <Irremote.h>

if your sensor doesn’t recognised your gesture you can play with this values. But i would recommend keep it default.

#define GES_REACTION_TIME 500
#define GES_ENTRY_TIME 800
#define GES_QUIT_TIME 1000

These are the values we have added from our TV remote. It is 68 elements, it can vary depends on your TV remote company.

unsigned int TvOnOff[26] = {2450, 550, 1250, 550, 700, 450, 1300, 500, 700, 500, 1250, 550, 650, 500, 700, 500, 1300, 500, 650, 550, 650, 550, 650, 500, 650}; 
unsigned int volumeUp[68] = {8950, 4350, 600, 1600, 600, 500, 600, 500, 600, 500, 600, 500, 600, 500, 600, 500, 600, 500, 600, 1600, 650, 450, 600, 1600, 600, 1550, 650, 1550, 650, 1550, 650, 1550, 600, 1600, 600, 500, 600, 500, 600, 500, 600, 500, 600, 500, 600, 500, 600, 500, 600, 1600, 600, 1550, 650, 1550, 650, 1550, 650, 1550, 650, 1550, 600, 1550, 650, 1550, 650, 450, 650};
unsigned int volumeDown[68] = {8950, 4300, 650, 1550, 650, 450, 650, 450, 650, 450, 650, 450, 650, 450, 650, 450, 650, 450, 650, 1550, 650, 450, 650, 1550, 650, 1550, 650, 1550, 650, 1500, 650, 1550, 650, 1550, 650, 1550, 650, 450, 650, 450, 650, 450, 650, 450, 650, 450, 650, 450, 650, 1550, 650, 450, 650, 1550, 650, 1550, 650, 1500, 700, 1500, 650, 1550, 650, 1550, 650, 450, 650};
unsigned int channelForward[68] = {8950, 4300, 650, 1550, 650, 450, 650, 450, 750, 350, 650, 450, 650, 450, 650, 450, 650, 450, 750, 1450, 650, 450, 650, 1550, 650, 1550, 650, 1550, 650, 1550, 650, 1500, 650, 1550, 650, 1550, 650, 450, 650, 1550, 650, 450, 650, 450, 650, 450, 750, 350, 650, 1550, 650, 450, 650, 1550, 650, 450, 750, 1450, 650, 1500, 700, 1500, 650, 1550, 650, 450, 650};
unsigned int channelBackward[68] = {8900, 4400, 600, 1550, 650, 450, 650, 450, 650, 450, 650, 450, 650, 500, 600, 500, 600, 500, 650, 1500, 650, 500, 600, 1550, 650, 1550, 650, 1550, 650, 1550, 650, 1550, 600, 1550, 650, 450, 650, 1550, 650, 1550, 650, 450, 650, 450, 650, 450, 650, 450, 650, 1550, 650, 1550, 650, 450, 650, 450, 650, 1550, 650, 1500, 650, 1550, 650, 1550, 650, 450, 650};

I have given forward and backward gesture for ON/OFF TV. Either your gesture backward or forward it will do ON or OFF depends on TV is ON or OFF. Copy this code in Right, Left, Up and Down Flag.

if(data == GES_FORWARD_FLAG)
{
Serial.println("Forward");
irsend.sendRaw(TvOnOff, 68, 38);
delay(GES_QUIT_TIME);
}
else if(data == GES_BACKWARD_FLAG)
{
Serial.println("Backward");
irsend.sendRaw(TvOnOff, 68, 38);
delay(GES_QUIT_TIME);
}

In this code, we are sending TVOnOff which is 26 element and 38 kHz is carrier frequency.

irsend.sendRaw(TvOnOff, 26, 38);

Right gesture is for moving channel forward and left is for moving channel backward.

Serial.println("Right");
irsend.sendRaw(channelForward, 68, 38);

There are two gestures for turning volume up. First is UP gesture and second is clockwise gesture.

Serial.println("Up");
irsend.sendRaw(volumeUp, 68, 38);
case GES_CLOCKWISE_FLAG:
Serial.println("Clockwise");
irsend.sendRaw(volumeUp, 68, 38);

Similarly for turning volume down, first gesture is Down and second gesture is anti-clockwise.

Sometime this sensor miss or wrongly detect few gestures. But you will get more accurate results by practising with the sensor. I hope you will like my effort.

Gesture control TV remote

For more videos please like and subscribe, Till then keep learning keep making.