Introduction: VLC Media Player Control Using IR Remote

Hi guys, this instructable is for all those who want to control your VLC media player or control your laptop with an IR remote or make a wireless keyboard out of the IR remote.

You can use this to play,pause,increase and decrease volume, increase and decrease speed of the video and stop and play from beginning options also comes along with this tutorial.

Here I will be using an arduino leonardo along with an IR remote. I used the IR remote of my TV for this purpose. You will need the following softwares pre-installed on your computer:

Arduino IDEVLC Media player

Step 1: The Programs

The required programs are given here to download. You can also read them at the end

Step 2: Grab the Materials:

Hurry up and gather the following things

around you:

a) Arduino Board-( you can use any version , I’m using an arduino Leonardo)

b) A remote control ( I would suggest you to use the remote of your TV or DVD player at home)

c) A TSOP-( well, It’s a kind of IR sensor)

d) The cable to connect your arduino with your PC/Laptop

e) Arduino IDE-( The software used to program your arduino)

Step 3: Basic Concepts:

For all those who don’t know what an arduino board is, it’s an open source development platform that is used by professionals, hobbyists, and artists alike to develop products and art. The main advantage with arduino’s are that they are really easy to program and to use (even school children with basic programming knowledge can do it). In short it is “simple and powerful” but not much “robust”, I’d say.

So our project works by sending serial data corresponding to the buttons pressed on the remote, from the arduino board to the serial port of our PC. The keyboard action is achieved by using the “keyboard” library which helps us to imitate the keyboard action using the arduino board.

Here's a basic outline of how the data is sent. Every time you press a button on a Sony remote control, it sends out a 13Bit data. The first bit is a start bit indicating there are 12 bits of data following it. The next 7 bits are the command bit which will vary depending upon the keys being pressed. The last 5 bits are the address bits which will the same for all buttons but vary for remote controls of different devices.

The above
diagram shows a TSOP‘s pin out and how to connect it. The TSOP outputs a constant HIGH signal when idle and as it receives data, it tends to invert the data. i.e when an IR LED is transmitting data onto the TSOP, every time the IR led goes high, the TSOP will go LOW and vice versa. Remote control signals are often bytes of data that is encoded and transmitted by pulsing(switching ON & OFF the IR LED at a specific frequency) Most TV remote controls work at 32-40 Khz frequency and most receivers can receive this range.

The SIRC protocol uses a pulse width encoding of the bits. The pulse representing a logical "1" is a 1.2ms long burst of the 40kHz carrier, while the burst width for a logical "0" is 0.6ms long. All bursts are separated by a 0.6ms long space interval.

Here we connect the TSOP’s signal pin to the 5th analog pin of the arduino, So as to receive the signal from the TSOP. To simplify things I used the IR remote library.

So all set to build your IR VLC controller?? Let’s kick off.

Step 4: TSOP and SIRC Protocol

Coming over to the working of the remote, it communicates by sending IR pulses to the TSOP. If you look at the image, you can see the the 1.2ms high of the Logical '1' has further black lines with spaces in between. These correspond to the ON/OFF cycles. The space between these is what is called the frequency. The frequency of occurrence of a ON/OFF cycle is what it means. The black bars in the below image correspond to high signals (called marks) and the white spaces in between correspond to low signals (called spaces). The duration of the 'marks' varies according to the bit being transmitted. It is 2.4ms for the start bit, 1.2ms for HIGH bit and 0.6ms for LOW bit. The duration of the 'spaces' is a constant 0.6ms. Every mark is followed by a space. Any data can be converted to binary format and transmitted in this manner. In fact this is the basic form of all types of serial communication. LSB=least significant bit MSB= Most significant bit The picture above shows a typical pulse train of the SIRC protocol. With this protocol the LSB is transmitted first. The start burst is always 2.4ms wide, followed by a standard space of 0.6ms. Apart from signalling the start of a SIRC message this start burst is also used to adjust the gain of the IR receiver. Then the 7-bit Command is transmitted, followed by the 5-bit Device address. In this case Address 1 and Command 19 is transmitted. Commands are repeated every 45ms (measured from start to start) for as long as the key on the remote control is held down.

Step 5: ​Come, Let’s Build It

a) First open the game you want to play and open the control details menu and note down all the controls in order.

b) Now take your arduino board and TSOP and make the connections as per the instructions.

c) Now connect your board to your PC using the USB cable. Open your arduino IDE and open the program1. Select the port in which you have connected your board and upload your program into the board.

d) Now open the serial monitor in the IDE and press each key of your remote and note down the decoded details that appears on the serial monitor. Note down each of these on a book.

e) Now open program2. This program has the basic structure to assign each key of the remote to each key of the keyboard as per the requirement of the game control.

f) If only one key is to be pressed, using keyboard.write() function is advised, and if pressing 2 or more keys together is required , using keyboard.press() and keyboard.release() is advised.

g) You can edit the programs as per your requirement.

h) Now upload the program into your board.

So that’s it friends, all you have to do now is open the player and start operating!!! Hurray!! Your IR VLC controller is ready and running! You can use it as a keyboard, IR joystick and what not!! So start developing and take your new gadget to new heights!

Step 6: Program 1

#include

int RECV_PIN = A5;

int BUTTON_PIN = 12;

int STATUS_PIN = 13;

IRrecv irrecv(RECV_PIN);

IRsend irsend;

decode_results results;

void setup()

{

Serial.begin(9600);

irrecv.enableIRIn(); // Start the receiver

pinMode(BUTTON_PIN, INPUT);

pinMode(STATUS_PIN, OUTPUT);

}

// Storage for the recorded code

int codeType = -1; // The type of code

unsigned long codeValue; // The code value if not raw

unsigned int rawCodes[RAWBUF]; // The durations if raw

int codeLen; // The length of the code

int toggle = 0; // The RC5/6 toggle state

// Stores the code for later playback

// Most of this code is just logging

void storeCode(decode_results *results) {

codeType = results->decode_type;

int count = results->rawlen;

if (codeType == UNKNOWN) {

Serial.println("Received unknown code, saving as raw");

codeLen = results->rawlen - 1;

// To store raw codes:

// Drop first value (gap)

// Convert from ticks to microseconds

// Tweak marks shorter, and spaces longer to cancel out IR receiver distortion

for (int i = 1; i <= codeLen; i++) {

if (i % 2) {

// Mark

rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS;

Serial.print(" m");

}

else {

// Space

rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS;

Serial.print(" s");

}

Serial.print(rawCodes[i - 1], DEC);

}

Serial.println("");

}

else {

if (codeType == NEC) {

Serial.print("Received NEC: ");

if (results->value == REPEAT) {

// Don't record a NEC repeat value as that's useless.

Serial.println("repeat; ignoring.");

return;

}

}

else if (codeType == SONY) {

Serial.print("Received SONY: ");

}

else if (codeType == RC5) {

Serial.print("Received RC5: ");

}

else if (codeType == RC6) {

Serial.print("Received RC6: ");

}

else {

Serial.print("Unexpected codeType ");

Serial.print(codeType, DEC);

Serial.println("");

}

Serial.println(results->value);

codeValue = results->value;

codeLen = results->bits;

}

}

void sendCode(int repeat) {

if (codeType == NEC) {

if (repeat) {

irsend.sendNEC(REPEAT, codeLen);

Serial.println("Sent NEC repeat");

}

else {

irsend.sendNEC(codeValue, codeLen);

Serial.print("Sent NEC ");

Serial.println(codeValue, HEX);

}

}

else if (codeType == SONY) {

irsend.sendSony(codeValue, codeLen);

Serial.print("Sent Sony ");

Serial.println(codeValue, HEX);

}

else if (codeType == RC5 || codeType == RC6) {

if (!repeat) {

// Flip the toggle bit for a new button press

toggle = 1 - toggle;

}

// Put the toggle bit into the code to send

codeValue = codeValue & ~(1 << (codeLen - 1));

codeValue = codeValue | (toggle << (codeLen - 1));

if (codeType == RC5) {

Serial.print("Sent RC5 ");

Serial.println(codeValue, HEX);

irsend.sendRC5(codeValue, codeLen);

}

else {

irsend.sendRC6(codeValue, codeLen);

Serial.print("Sent RC6 ");

Serial.println(codeValue, HEX);

}

}

else if (codeType == UNKNOWN /* i.e. raw */) {

// Assume 38 KHz

irsend.sendRaw(rawCodes, codeLen, 38);

Serial.println("Sent raw");

}

}

int lastButtonState;

void loop() {

// If button pressed, send the code.

int buttonState = digitalRead(BUTTON_PIN);

if (lastButtonState == HIGH && buttonState == LOW) {

Serial.println("Released");

irrecv.enableIRIn(); // Re-enable receiver

}

if (buttonState) {

Serial.println("Pressed, sending");

digitalWrite(STATUS_PIN, HIGH);

sendCode(lastButtonState == buttonState);

digitalWrite(STATUS_PIN, LOW);

delay(50); // Wait a bit between retransmissions

}

else if (irrecv.decode(&results)) {

digitalWrite(STATUS_PIN, HIGH);

storeCode(&results);

irrecv.resume(); // resume receiver

digitalWrite(STATUS_PIN, LOW);

}

lastButtonState = buttonState;

}

Step 7: Program 2

#include

int RECV_PIN = A5;

int BUTTON_PIN = 12;

int STATUS_PIN = 9;

IRrecv irrecv(RECV_PIN);

IRsend irsend;

decode_results results;

void setup()

{Keyboard.begin();

Serial.begin(9600);

irrecv.enableIRIn(); // Start the receiver

pinMode(BUTTON_PIN, INPUT);

pinMode(STATUS_PIN, OUTPUT);

digitalWrite(STATUS_PIN,LOW);

}

// Storage for the recorded code

int codeType = -1; // The type of code

unsigned long codeValue; // The code value if not raw

unsigned int rawCodes[RAWBUF]; // The durations if raw

int codeLen; // The length of the code

int toggle = 0; // The RC5/6 toggle state

// Stores the code for later playback

// Most of this code is just logging

void storeCode(decode_results *results) {

codeType = results->decode_type;

int count = results->rawlen;

if (codeType == NEC) {

Serial.print("Received NEC: ");

if (results->value == REPEAT) {

// Don't record a NEC repeat value as that's useless.

Serial.println("repeat; ignoring.");

return;

}

}

Serial.println(results->value, HEX);

Serial.println(results->value);

codeValue = results->value;

codeLen = results->bits;

if( codeValue==3724611569)//play

{ Keyboard.write(0x70);}

else if( codeValue==3724611580)//play/pause

{ Keyboard.write(0x20);}

else if( codeValue==3724611540)//mute

{ Keyboard.write(0x6D);}

else if( codeValue==3724611568)//stop

{ Keyboard.write(0x73);}

else if( codeValue==3724611526 )//volume up

{ Keyboard.press(0x80);

Keyboard.press(0xDA);

delay(15);

Keyboard.releaseAll();}

else if( codeValue==3724611558 )//volume down

{ Keyboard.press(0x80);

Keyboard.press(0xD9);

delay(15);

Keyboard.releaseAll();}

else if( codeValue==3724611520)//forward

{ Keyboard.press(0x81);

Keyboard.press(0xD7);

Keyboard.releaseAll();}

else if( codeValue==3724611552 )//backward

{ Keyboard.press(0x81);

Keyboard.press(0xD8);

Keyboard.releaseAll();}

else if( codeValue==3724611574)//speedup

{ Keyboard.write(0x5D);}

else if( codeValue==3724611541)//speed down

{ Keyboard.write(0x5B);}

}

int lastButtonState;

void loop() {

// If button pressed, send the code.

if (irrecv.decode(&results)) {

digitalWrite(STATUS_PIN, HIGH);

storeCode(&results);

irrecv.resume(); // resume receiver

digitalWrite(STATUS_PIN, LOW);

}

}