When you are looking at the connections from the Arduino, the serial communication is bright green (only the TX is being used), the SPI communication is orange, and the accelerometer is yellow. The resistors above the accelerometer are converting +5v to +3.3v(10k from +5v, and 15k to ground). The USB communication is on the right (+5v(pin23), D-(pin25), D+(pin27), Ground(pin 15)) and in some pictures there +5v on pin 23 and a 100kohmn resistor from pin 25 to +5v and from pin 27 to ground—this is so the ipod charges off the circuit. In order for the ipod to show up in itunes, these resistors on the data pins must be removed. The first picture is the pinout for the ipodBreakout (from p.405 iPhone Hacks by David Jurick, Adam & Damien Stolarz):
(updated 6/22/11)
/*
ipod_controller_main
This code controls an ipod embedded in a moving installation, such that sound only plays with the ipod is moving
TX and RX pins on the Arduino are connected to pins 12 and 13 of PodBreakout
Ipod serial communication only has volume control on mode 2, but since lots of ipods don't accept this mode, playback
is done through mode 4, and fading volume is handled by a digital potentiometer (DS1801).
+5v is connected to pin 14
Pins 1, 4, 7, 10, 11 are connected to ground
pin 6 LeftIn
pin 5 LeftOut
pin 9 RightIn
pin 8 RightOut
The SPI circuit looks like this:
Arduino 10--- (SS) DS1801 pin 3
Arduino 11--- (RX) DS1801 pin 12
Arduino 13--- (CLK) DS1801 pin 13
the X,Y,Z pins of an accelerometer are connected to analog 3, 4, 5
Jeff Aaron Bryant, June 2011
*/
//serial commands for ipod
byte wake [] ={0xFF, 0x55, 0x03, 0x02, 0x00, 0x04, 0xF7}; //wakeup
byte mode_4 [] = {0xFF, 0x55, 0x03, 0x00, 0x01, 0x04, 0xF8}; //switch to mode 4
byte playlist [] = {0xFF, 0x55, 0x07, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0xCD}; //startlist
byte play_pause [] = {0xFF, 0x55, 0x04, 0x04, 0x00, 0x29, 0x01, 0xCE}; //play_pause
byte skip [] = {0xFF, 0x55, 0x04, 0x04, 0x00, 0x29, 0x03, 0xCC}; //skip
byte back [] = {0xFF, 0x55, 0x04, 0x04, 0x00, 0x29, 0x04, 0xCB}; //back
//sizes
int wakeLength = sizeof(wake);
int mode_4Length = sizeof(mode_4);
int playlistLength =sizeof(playlist);
int play_pauseLength = sizeof(play_pause);
int skipLength = sizeof(skip);
int backLength = sizeof(back);
// include the SPI library
#include <SPI.h>
// set pin 10 as the slave select for the digital pot(DS1801)
int SS = 10;
int mute = 64;
int loud = 63;
int soft = 0;
void setup(){
Serial.begin(9600);
//startup ipod
for (int i=0; i< wakeLength; i++){ //wakeup
Serial.print(wake[i],BYTE);
}
Serial.println(" WAKE");
for (int i=0; i< mode_4Length; i++){ //mode 4
Serial.print(mode_4[i],BYTE);
}
Serial.println(" MODE_4");
// set the slaveSelectPin as an output:
pinMode (SS, OUTPUT);
// initialize SPI:
SPI.setBitOrder(LSBFIRST);
SPI.setDataMode(SPI_MODE0);
SPI.setClockDivider(SPI_CLOCK_DIV128);
SPI.begin();
delay(10);
setVolume(mute);
}
void loop(){
accelerometer();
ipodCommands();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//accelerometer
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int x, y, z;
int tilt= 0;
int lastTilt= 0;
int diff= 0;
int stillness= 8;
int moving= 0;
int slowing =0;
void accelerometer(){
if (moving == 1 && slowing ==0){ delay (3000);}
if (moving == 1 && slowing ==1){ delay (500);}
if (moving == 0){ delay (200);}
x =analogRead(5);
y =analogRead(4);
z =analogRead(3);
Serial.print(" X=");
Serial.print(x);
Serial.print(" Y=");
Serial.print(y);
Serial.print(" Z=");
Serial.print(z);
tilt= x + y + z;
diff= tilt-lastTilt;
if (tilt != lastTilt && abs(diff)> 8 && abs(diff)< 400) {
Serial.print(" MOVING!!! ");
Serial.print(diff);
moving= 1;
lastTilt = tilt;
stillness= 0;
slowing = 0;
}
else {
stillness++;
if (stillness< 7){
Serial.print(" ...slowing... ");
Serial.print(diff);
slowing = 1;
} else{
Serial.print(" STOPPED ");
Serial.print(diff);
moving= 0;
slowing= 0;
lastTilt=tilt;
}
}
Serial.println();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//ipodCommands
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int state= 0;
int lastState= 0;
int startup= 0;
void ipodCommands(){
state= moving;
if (state != lastState){
switch (state){
case 1: if (startup ==0){
for (int i=0; i< playlistLength; i++){ //start playlist at the beginning
Serial.print(playlist[i],BYTE);
}
Serial.println(" Startlist");
for (int i = soft; i <= 10; i++) { //turn up volume
setVolume(i);
delay(10);
}
for (int i = 10; i <= 63; i++) {
setVolume(i);
delay(250);
}
startup++;
lastState = state;
break;
} else{
for (int i=0; i< play_pauseLength; i++){ //pause
Serial.print(play_pause[i],BYTE);
}
Serial.println(" PLAY");
for (int i = soft; i <= 10; i++) { //turn up volume
setVolume(i);
delay(10);
}
for (int i = 10; i <= 63; i++) {
setVolume(i);
delay(250);
}
lastState= state;
break;
case 0: for (int i = loud; i >= 15; i--) { //turn down volume
setVolume(i);
delay(10);
}
for (int i = 15; i >= 0; i--) {
setVolume(i);
delay(50);
}
for (int i=0; i< play_pauseLength; i++){ //pause
Serial.print(play_pause[i],BYTE);
}
Serial.println(" PAUSE");
delay (1000);
setVolume(mute); //mute
for (int i=0; i< skipLength; i++){ //skip
Serial.print(skip[i],BYTE);
}
Serial.println(" SKIP");
delay (500);
lastState= state;
break;
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//setVolume
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setVolume(int level) {
digitalWrite(SS,HIGH);
SPI.transfer(level); //pot 0
SPI.transfer(level); //pot 1
digitalWrite(SS,LOW);
}