Thursday, April 19, 2007

I have iPod Mojo

I've been working on this project since October, first for my pcomp final project and then all semester for Project Development Studio. The difficult thing is that, although I've learned a lot along the way, I've really had nothing to show for my efforts. The ipod never responded to any commands I sent it, so I had no way of knowing if I was making progress or not. Until now.

Friday night I figured out one problem -- I was trying to send the serial data over the wrong wire. Then earlier this week, I was reading online somewhere that you can't just send a command to the ipod without also sending it a "button release" command afterward. So today in Tom's office, we sent the right code over the right wire, and it worked!!! I was hopping around Tom's office squealing, "Oh my god!!!" Seven months of work finally came to fruition today. I am so relieved and excited. Now I'll actually have something to show for my final project in Project Development Studio next Thursday and something to continue working with if I want. Tom helped me tremendously and most of the information I needed was online, but I actually solved this problem, even though it took seven months. I feel like this is my first real ITP accomplishment, and it feels damn good. I did something hard and didn't give up on it even though I really wanted to. So overall, today was really good for my sense of self-efficacy and mood.

Over the next week, I will be undertaking the task of documenting everything I did over the last seven months in an effort to provide a comprehensive resource for people interested in hacking an ipod remote.

Here's the code for Processing.

import processing.serial.*;

Serial ipod;
int buttonRelease[] = {
0xFF, 0x55, 0x03, 0x02, 0x00, 0x00,0xFB };

void setup() {
String[] serialPorts = Serial.list();
println(serialPorts);

ipod = new Serial(this, serialPorts[0], 19200);
}

void draw() {
background(0);
}

void keyReleased() {

switch (key) {
case 'f': // forward
sendCommand(0x08);
break;
case 'p': // play/pause
sendCommand(0x01);
break;
case 'b': // backward
sendCommand(0x10);
break;
case 'u': // vol up
sendCommand(0x02);
break;
case 'd': // vol down
sendCommand(0x04);
break;
case 'n': // next album
sendCommand(0x20);
break;
case 'v': // previous album
sendCommand(0x40);
break;
case 's': // next album
sendCommand(0x80);
break;
}
}


int checkSum(int len, int mode, int command1, int command2, int
parameter) {
int checksum = 0x100 - ((len + mode + command1 + command2+parameter) & 0xFF);
return checksum;
}
void serialEvent(Serial ipod) {
char inByte = char(ipod.read());
print(inByte);
}



void sendCommand(int cmd) {
int cs = checkSum(0x03, 0x02, 0x00, cmd, 0);
println(hex(cs));


int bytes[] = {
0xFF, 0x55, 0x03, 0x02, 0x00, cmd, cs };
for (int i = 0; i < bytes.length; i++) {
ipod.write(bytes[i]);
}
for (int i = 0; i < buttonRelease.length; i++) {
ipod.write(buttonRelease[i]);
}
}

3 comments:

Kelly said...

wow...much impressiveness...

Anonymous said...

wow I love you. :) lol.. thats awesome / I also saw your work on the MOUTH PIANO... (i guess itz more targeted for ppl with disabilities more than anything :)

hey i'de love to chat with ya about electronics / if your on facebook look me up. You can find me under the name "Silver Byte" montreal

Tonypascal said...

Hey, this is an interesting project. I am trying to make it work, but I can't figure out how you send information to you ipod, because when I connect it to the usb cable (I suppose this is how you do), it is detected by iTunes and there is this "don't disconnect" sign that appears ? do you use something like a virtual serial driver to command the iPod ?

Thank for the help