I finally finished my first complete Arduino project. I built an IR Receiver that listens to the Xbox remote, and turns it on when the display button is pressed, or turns it off when the 0 button is held down. It is a perfect for Xbox Media Center.
I used an ATmega48 for the chip just because it is cheap, and the program size is small. I made my own custom core for it by just going through all the Arduino core files and changing any reference to the ATmega168 to the ATmega48. It could probably be done a lot better by just adding my if defined statements. The ATmega 48 utilizes its internal oscillator running at 8 mhz. It gets its power from the Xbox's +5 volt stand by line. When it receives the code for the display button on the remote, it checks to make sure the system is off, and then uses a transistor to pull the power button low. When 0 is held down for 4 seconds, it also pulls the power button low through the transistor to turn the system off. After either action occurs, the program will not respond to button presses for 4 seconds, just to make sure the hard drive isn't damaged.
Internal Picture with chip shown in dead bug style:
External Picture showing the hole for the IR receiver module to poke through:
Schematic:
The schematic is based on several different sources:
http://diy.sickmods.net/Our_Products/XERC_2/Build_It/
http://xirremote.tripod.com/
For guides on the power supply pinout:
http://diy.sickmods.net/Tutorials/Xbox1/Power_Supply_Pinouts/
The remote protcol seems to be based on the RCA protocol:
I used a Sharp GP1UD277XK as the IR Receiver, as it works with the 56.8k carrier pulse:
http://document.sharpsma.com/files/gp1ud27xk_series.pdf
I based the majority of the code on David Cuartielles's work found in this topic:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1176098434
#define power_sense_pin 7
#define power_pin 8
#define ir_pin 9
#define start_bit 3500
#define bin_1 1750
#define bin_0 0
void setup()
{
pinMode(ir_pin, INPUT);
digitalWrite(ir_pin, HIGH);
pinMode(power_pin, OUTPUT);
digitalWrite(power_pin, LOW);
pinMode(power_sense_pin, INPUT);
}
void loop()
{
int key = getIRKey(); //Fetch the key
if ((key == 1322) && (!digitalRead(power_sense_pin)))
{
digitalWrite(power_pin, HIGH);
delay(1000);
digitalWrite(power_pin, LOW);
delay(4000);
}
if ((key == 1328) && (digitalRead(power_sense_pin)))
{
delay(4000);
if ((key == 1328) && (digitalRead(power_sense_pin)))
{
digitalWrite(power_pin, HIGH);
delay(1000);
digitalWrite(power_pin, LOW);
delay(4000);
}
}
}
int getIRKey()
{
int data[12];
int data2[12];
while(pulseIn(ir_pin, LOW) < start_bit)
{}
while(pulseIn(ir_pin, HIGH) < start_bit)
{}
data[0] = pulseIn(ir_pin, HIGH); //Start measuring bits, I only want low pulses
data[1] = pulseIn(ir_pin, HIGH);
data[2] = pulseIn(ir_pin, HIGH);
data[3] = pulseIn(ir_pin, HIGH);
data[4] = pulseIn(ir_pin, HIGH);
data[5] = pulseIn(ir_pin, HIGH);
data[6] = pulseIn(ir_pin, HIGH);
data[7] = pulseIn(ir_pin, HIGH);
data[8] = pulseIn(ir_pin, HIGH);
data[9] = pulseIn(ir_pin, HIGH);
data[10] = pulseIn(ir_pin, HIGH);
data[11] = pulseIn(ir_pin, HIGH);
data2[0] = pulseIn(ir_pin, HIGH); //Start measuring bits, I only want low pulses
data2[1] = pulseIn(ir_pin, HIGH);
data2[2] = pulseIn(ir_pin, HIGH);
data2[3] = pulseIn(ir_pin, HIGH);
data2[4] = pulseIn(ir_pin, HIGH);
data2[5] = pulseIn(ir_pin, HIGH);
data2[6] = pulseIn(ir_pin, HIGH);
data2[7] = pulseIn(ir_pin, HIGH);
data2[8] = pulseIn(ir_pin, HIGH);
data2[9] = pulseIn(ir_pin, HIGH);
data2[10] = pulseIn(ir_pin, HIGH);
data2[11] = pulseIn(ir_pin, HIGH);
for(int i=0;i<=11;i++)
{ //Parse them
if(data[i] > bin_1)
data[i] = 1;
else if(data[i] > bin_0)
data[i] = 0;
else
data[i] = 2; //Flag the data as invalid; I don't know what it is!
if(data2[i] > bin_1)
data2[i] = 1;
else if(data2[i] > bin_0)
data2[i] = 0;
else
data2[i] = 2;
}
for(int i=0;i<=11;i++)
{
if(data[i] > 1)
return -1; //Return -1 on invalid data
if(data2[i] > 1)
return -1;
}
int result = 0;
int result2 = 0;
int seed = 1;
for(int i=11;i>=0;i--)
{
if(data[i] == 1)
result += seed;
seed = seed * 2;
}
seed = 1;
for(int i=11;i>=0;i--)
{
if(data2[i] == 1)
result2 += seed;
seed = seed * 2;
}
if ( (result + result2) != 4095 ) // Inverse is invalid
return -1;
return result; //Return key number
}