Pages

Wednesday, December 15, 2010

Arduino Tivo Remote Extender

About a year ago I needed the ability to control my Tivo S3 from another room. Originally I purchased some cheap IR Extender from Radio Shack and tried it. After toying around with it I knew that a off-shelf product was going to be useless.

So I developed my own solution:

After doing some reading I knew the Tivo S3/HD (newer ones probably as well) have a telnet server running on the Tivo that allows 3rd party apps to control the Tivo.

To test this, all you need to do is open a Telnet client, connect to your Tivo's IP using port 31339 and then you could start sending out commands to the Tivo like the following:

IRCODE TIVO
IRCODE LIVETV
IRCODE UP

With this in mind, I knew there was the ability to control the Tivo using an ethernet device.

Previously I had played around with Arduino . This is a microcontroller which you can program to control your I/O's on the device. This device also supports an Ethernet Sheild which would allow me to communicate with the Tivo's Telnet server. Next I needed a IR receiver for this to work, after Googling I found this receiver on SparkFun.

Here is the hardware:


Now comes the fun part: the software:

#include

#include
#include
#include
#include

#include

byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = {
192, 168, 0, 213 }; // Device IP
byte server[] = {
192, 168, 0, 134 }; // Tivo

Client client(server, 31339);

int RECV_PIN = 3;
IRrecv irrecv(RECV_PIN);
decode_results results;
decode_results resultslast;
unsigned long firetime;

void setup()
{
irrecv.enableIRIn(); // Start the receiver
Ethernet.begin(mac, ip);
Serial.begin(9600);
pinMode(6, OUTPUT);
pinMode(5, OUTPUT);

}

void sndcmd(char data[]) {
resultslast = results;

if (millis() - firetime >= 150) {

if (client.connect()) {
client.println(data);
}
else
{
client.stop();
delay(50);
if (client.connect()) {
client.println(data);
}
}

firetime = millis();

}
}

void loop() {
analogWrite(5, 15);

if (irrecv.decode(&results)) {

Serial.println(results.value, HEX);
// Serial.println("-----");

if (results.value == 0xFFFFFFFF) {
results = resultslast;
}

switch (results.value) {

case 0xA10CD00F: //Tivo Button (cheapo remote)
sndcmd("IRCODE TIVO");
break;

case 0xA10C500F: //Tivo Button (nice remote)
sndcmd("IRCODE TIVO");
break;
case 0xA10C8807: //LiveTV Button
sndcmd("IRCODE LIVETV");
break;

case 0xA10CC807: //Info Button
sndcmd("IRCODE DISPLAY");
break;

case 0xA10C6C03: //Guide Button
sndcmd("IRCODE GUIDE");
break;

case 0xA10C2807: //Select Up Button
sndcmd("IRCODE UP");
break;

case 0xA10C6807: //Select Down Button
sndcmd("IRCODE DOWN");
break;

case 0xA10CE807: //Select Left Button
sndcmd("IRCODE LEFT");
break;

case 0xA10CA807: //Select Right Button
sndcmd("IRCODE RIGHT");
break;

case 0xA10C9807: //Select Button
sndcmd("IRCODE SELECT");
break;

case 0xA10C1807: //Thumbs Down
sndcmd("IRCODE THUMBSDOWN");
break;

case 0xA10C5807: //Thumbs Up
sndcmd("IRCODE THUMBSUP");
break;

case 0xA10C7807: //Channel Up
sndcmd("IRCODE CHANNELUP");
break;

case 0xA10CF807: //Channel Down
sndcmd("IRCODE CHANNELDOWN");
break;

case 0xA10C040B: //Record
sndcmd("IRCODE RECORD");
break;

case 0xA10C840B: //Play
sndcmd("IRCODE PLAY");
break;

case 0xA10CC40B: //Pause
sndcmd("IRCODE PAUSE");
break;

case 0xA10CA40B: //Slow
sndcmd("IRCODE SLOW");
break;

case 0xA10C440B: //Reverse
sndcmd("IRCODE REVERSE");
break;

case 0xA10C240B: //Forward
sndcmd("IRCODE FORWARD");
break;

case 0xA10CE40B: //Advance
sndcmd("IRCODE ADVANCE");
break;

case 0xA10C640B: //Replay
sndcmd("IRCODE REPLAY");
break;

case 0xA10C140B: //Num 1
sndcmd("IRCODE NUM1");
break;

case 0xA10C940B: //Num 2
sndcmd("IRCODE NUM2");
break;

case 0xA10C540B: //Num 3
sndcmd("IRCODE NUM3");
break;

case 0xA10CD40B: //Num 4
sndcmd("IRCODE NUM4");
break;

case 0xA10C340B: //Num 5
sndcmd("IRCODE NUM5");
break;

case 0xA10CB40B: //Num 6
sndcmd("IRCODE NUM6");
break;

case 0xA10C740B: //Num 7
sndcmd("IRCODE NUM7");
break;

case 0xA10CF40B: //Num 8
sndcmd("IRCODE NUM8");
break;

case 0xA10C0C03: //Num 9
sndcmd("IRCODE NUM9");
break;

case 0xA10C8C03: //Num 0
sndcmd("IRCODE NUM0");
break;

case 0xA10CCC03: //Enter
sndcmd("IRCODE ENTER");
break;

case 0xA10C4C03: //Clear
sndcmd("IRCODE CLEAR");
break;

default:
resultslast = results;
break;

}

irrecv.resume(); // Receive the next value
}

}

I used this IR library I found on the net from Ken Shirriff. Basically it has the ability to capture the keys pressed from the Tivo Remote and returns a integer (ex. 0xA10C4C03). Each button fires a different integer. With this I mapped out each command, then connect to the Tivo and pass the proper Telnet command.

Below you can find a YouTube video of the device in action:







Monday, December 13, 2010

New Web Site

Just got done moving the web site from GoDaddy over to Blogger. The performance of the new site should be significantly better.

I'll be adding more content soon.

Wednesday, December 15, 2010

Arduino Tivo Remote Extender

About a year ago I needed the ability to control my Tivo S3 from another room. Originally I purchased some cheap IR Extender from Radio Shack and tried it. After toying around with it I knew that a off-shelf product was going to be useless.

So I developed my own solution:

After doing some reading I knew the Tivo S3/HD (newer ones probably as well) have a telnet server running on the Tivo that allows 3rd party apps to control the Tivo.

To test this, all you need to do is open a Telnet client, connect to your Tivo's IP using port 31339 and then you could start sending out commands to the Tivo like the following:

IRCODE TIVO
IRCODE LIVETV
IRCODE UP

With this in mind, I knew there was the ability to control the Tivo using an ethernet device.

Previously I had played around with Arduino . This is a microcontroller which you can program to control your I/O's on the device. This device also supports an Ethernet Sheild which would allow me to communicate with the Tivo's Telnet server. Next I needed a IR receiver for this to work, after Googling I found this receiver on SparkFun.

Here is the hardware:


Now comes the fun part: the software:

#include

#include
#include
#include
#include

#include

byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = {
192, 168, 0, 213 }; // Device IP
byte server[] = {
192, 168, 0, 134 }; // Tivo

Client client(server, 31339);

int RECV_PIN = 3;
IRrecv irrecv(RECV_PIN);
decode_results results;
decode_results resultslast;
unsigned long firetime;

void setup()
{
irrecv.enableIRIn(); // Start the receiver
Ethernet.begin(mac, ip);
Serial.begin(9600);
pinMode(6, OUTPUT);
pinMode(5, OUTPUT);

}

void sndcmd(char data[]) {
resultslast = results;

if (millis() - firetime >= 150) {

if (client.connect()) {
client.println(data);
}
else
{
client.stop();
delay(50);
if (client.connect()) {
client.println(data);
}
}

firetime = millis();

}
}

void loop() {
analogWrite(5, 15);

if (irrecv.decode(&results)) {

Serial.println(results.value, HEX);
// Serial.println("-----");

if (results.value == 0xFFFFFFFF) {
results = resultslast;
}

switch (results.value) {

case 0xA10CD00F: //Tivo Button (cheapo remote)
sndcmd("IRCODE TIVO");
break;

case 0xA10C500F: //Tivo Button (nice remote)
sndcmd("IRCODE TIVO");
break;
case 0xA10C8807: //LiveTV Button
sndcmd("IRCODE LIVETV");
break;

case 0xA10CC807: //Info Button
sndcmd("IRCODE DISPLAY");
break;

case 0xA10C6C03: //Guide Button
sndcmd("IRCODE GUIDE");
break;

case 0xA10C2807: //Select Up Button
sndcmd("IRCODE UP");
break;

case 0xA10C6807: //Select Down Button
sndcmd("IRCODE DOWN");
break;

case 0xA10CE807: //Select Left Button
sndcmd("IRCODE LEFT");
break;

case 0xA10CA807: //Select Right Button
sndcmd("IRCODE RIGHT");
break;

case 0xA10C9807: //Select Button
sndcmd("IRCODE SELECT");
break;

case 0xA10C1807: //Thumbs Down
sndcmd("IRCODE THUMBSDOWN");
break;

case 0xA10C5807: //Thumbs Up
sndcmd("IRCODE THUMBSUP");
break;

case 0xA10C7807: //Channel Up
sndcmd("IRCODE CHANNELUP");
break;

case 0xA10CF807: //Channel Down
sndcmd("IRCODE CHANNELDOWN");
break;

case 0xA10C040B: //Record
sndcmd("IRCODE RECORD");
break;

case 0xA10C840B: //Play
sndcmd("IRCODE PLAY");
break;

case 0xA10CC40B: //Pause
sndcmd("IRCODE PAUSE");
break;

case 0xA10CA40B: //Slow
sndcmd("IRCODE SLOW");
break;

case 0xA10C440B: //Reverse
sndcmd("IRCODE REVERSE");
break;

case 0xA10C240B: //Forward
sndcmd("IRCODE FORWARD");
break;

case 0xA10CE40B: //Advance
sndcmd("IRCODE ADVANCE");
break;

case 0xA10C640B: //Replay
sndcmd("IRCODE REPLAY");
break;

case 0xA10C140B: //Num 1
sndcmd("IRCODE NUM1");
break;

case 0xA10C940B: //Num 2
sndcmd("IRCODE NUM2");
break;

case 0xA10C540B: //Num 3
sndcmd("IRCODE NUM3");
break;

case 0xA10CD40B: //Num 4
sndcmd("IRCODE NUM4");
break;

case 0xA10C340B: //Num 5
sndcmd("IRCODE NUM5");
break;

case 0xA10CB40B: //Num 6
sndcmd("IRCODE NUM6");
break;

case 0xA10C740B: //Num 7
sndcmd("IRCODE NUM7");
break;

case 0xA10CF40B: //Num 8
sndcmd("IRCODE NUM8");
break;

case 0xA10C0C03: //Num 9
sndcmd("IRCODE NUM9");
break;

case 0xA10C8C03: //Num 0
sndcmd("IRCODE NUM0");
break;

case 0xA10CCC03: //Enter
sndcmd("IRCODE ENTER");
break;

case 0xA10C4C03: //Clear
sndcmd("IRCODE CLEAR");
break;

default:
resultslast = results;
break;

}

irrecv.resume(); // Receive the next value
}

}

I used this IR library I found on the net from Ken Shirriff. Basically it has the ability to capture the keys pressed from the Tivo Remote and returns a integer (ex. 0xA10C4C03). Each button fires a different integer. With this I mapped out each command, then connect to the Tivo and pass the proper Telnet command.

Below you can find a YouTube video of the device in action:







Monday, December 13, 2010

New Web Site

Just got done moving the web site from GoDaddy over to Blogger. The performance of the new site should be significantly better.

I'll be adding more content soon.