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]);
}
}

Friday, April 13, 2007

ipod AUD

Finally learned something useful about the ipod remote. The three wires I need are power, ground, and AUD. I removed L, R, and CON6, and the remote still worked beautifully. Previously I thought AUD would refer to "audio" and didn't expect it to impact the transmission of serial data. So for the past couple of weeks, I've been trying to send data over the CON6 line -- no wonder it didn't work.

Tuesday, April 10, 2007

Solar / Battery Powered Gas Sensors

In the latest version of our sensor circuits, we used 3 AA rechargeable batteries that were being topped off with solar power to power the sensor and XBee. We used the circuit Rob and Kate created to supplement the power of the Botanicalls project with solar panels.

Saturday, April 07, 2007

Gas Sensors

Tonight Christian and I played with our Figaro gas sensors and got good results with the 2602 (see Figaro datasheet). The 2602 senses the air contaminants emitted by cigarette smoke as well as odorous gases such as ammonia, hydrogen sulfide, and toluene. The sensor is actually fairly easy to wire - it just needs a variable resistor, connections to power and ground, and a connection to the arduino analog input. We used a potentiometer as our variable resistor, at the suggestion of the ITP sensor workshop page on gas sensors. The pot is connected to pin 2 of the sensors and the analog input pin 0 of arduino. We read values into Arduino with the following code:

int gasSensor = 0; // select input pin for gasSensor
int val = 0; // variable to store the value coming from the sensor

void setup() {
Serial.begin(9600);
}

void loop() {
val = analogRead(gasSensor); // read the value from the sensor
Serial.println( val );
delay(500);
}

Since one of the gases the 2602 is supposed to sense is ammonia, we bought some Lemon Ammonia from our friendly neighborhood Kmart (only $1.30 for 64 FL OZ - what a bargain!) and stuck the sensor near the top of the bottle. The readings in Arduino skyrocketed from around 90-100 to 590-600. We have yet to translate that into something meaningful, such as parts per million. Also, the values vary pretty radically depending on the resistance of the potentiometer.

Next on the to-do list is to hookup the 2442 sensor and get readings from it. Christian is working on getting the XBees to transmit the data from the sensors, and I'm going to try to power the Xbees and sensors from recharable batteries, which are in turn powered from solar panels.