Connecting Arduino to iPhone/iPod serial

Hi,
Both me and my friend have iPod touch's he managed to break his data pin using 6V so i would look at reducing the power somehow. better idea is to get bluetooth Arduino and using an iPhone to control it.
He had his iPod touch repaired for $50 Au

Thanks for the advice and warning Cybot.

Does the IPhone SDK allows access to the serial port ? If yes, that's the best news of the month ^^

I know that if you jailbreak you can use Java or Python to interface with the slot, my friend managed to figure this out after wringing a simple python program to capture the data being transfered when he used a remote control with it. :wink:
But as far as the SDK i doubt it as apple didn't even allow you to change the brightness of the screen.

I was doing some research on this when I first got my Arduino, and here's a link to the best info I found on the topic: (bah, see next post)

It looks like she's essentially taking a third-party remote, cutting it open, and then just using the wires leading to the iPod and connecting them to her Arduino. I think she's lifting the traces off of the circuit board, I assume she could have in fact just cut off the remote board and used the wires leading to it.

She mentions that it works fine with her atmega8 version, but has problems with the newer atmega168 versions, so just a heads up. I really want to try to get a project like this up and running on a 168 Arduino, but the lack of an iPod is proving to be a bit of a setback :smiley:

Got a 3G working with an old connector but my 5G iPod isn't playing ball,

Thanks for posting the link to Rosie's code pjamestx, I've used it for my tests!

Does anyone know what codes the device actually sends to the ipod from the ipod radio receiver ? im looking at using my ipod with my large antenna and using the Arduino as an amp

I did this with my ipod touch jailbreaked 2.0.2. Hardware wise I used a cable from :http://www.rush2112.net/mkportal/modules/oscommerce/product_info.php?products_id=34&osCsid=623417921d61d5ff5d81100e93fc1cf6, although they used to just sell the ipod to 8-din cable. Tx from ipod goes straight into Arduino, While Rx goes through 1k resistor(3.3v). Software wise I have accomplished three different things:

  1. Using Minicom from the Cydia installer to talk like a terminal.

  2. Use a GPSShield from Ladyada to get NMEA GPS data into xGPS, also found in Cydia.

  3. Used Iphone/Python and this:tsb.py - a telnet to serial bridge as a Wifi Serial port, through which I could control a simple servo robot with this: Wifi Robot - JBProjects.net

If you would like me to elaborate on any of these, just ask. It was a little while ago, but I can still try and help.

We happend to prepared some iPod breakout, if they would be helpful: http://www.seeedstudio.com/depot/ipodext-assembled-version-breakout-for-ipod-p-148.html
:slight_smile:

Easty: Glad the link helped. What version of the Arduino are you using? I figured I'd get back in touch with her if someone got it working on a 168.

seeedstudio: Cool, I'd come across those in your store before but had forgotten all about them. Looks like they'd be about the same price as chopping up a third-party remote, and way easier to use.

pjamestx, I'm using the 168 and Rosie's issue could be the same reason I'm having some odd behaviour! I'll keep you posted but to be honest I'm trying but I'm getting to the edge of my knowledge with all this! Turning LEDs on and off is one thing but serial comms isn't something I've attempted before, nothing like keeping it simple! ::slight_smile:

My next thought is to get an LCD display hooked up so I can check what's being sent (the project will need one in the end anyway)

I've ordered the correct connector now so I won't have to use the one I've recycled from an old Firewire cable (the connections are a nightmare to solder to as they've been cut off and are about 0.5mm!)

Success!

I've managed to get the Arduino and iPod communicating and can play/pause, skip forward and back, move forward and back through tacks and change the volume (iPod mode 2),

This is the code I'm using, a bit scruffy, sorry!

/*---------------------------------------------------
Controls an iPod through the dock connector's serial interface.
-----------------------------------------------------

Tx (output 1) ---[1k]-------------iPod pin13 Rx
                         |   -----iPod pin21 Accessory
                         |   |
                         |   |
                        --- ---
                         2k  1m
                        --- ---
                         |   |
                         |   |
Gnd-------------------------------iPod pin11 Ground

                        +5v
                         |
                         |
                        ---
                        2k2
                        ---
                         |
                         |
analog inputs 0-4 --------------/switch/--- 0v

-----------------------------------------------------
v0.3 - Added switches code
-----------------------------------------------------
v0.2 - Added DEBUG mode
Added the DEBUG switch to be able to read the output without having an iPod connected.
-----------------------------------------------------
v0.1 - Initial code
iPod mode 2 (simple iPod remote) only.
-----------------------------------------------------
Resources used:
      
http://www.rosiedaniel.com/search/label/ipod

http://stud3.tuwien.ac.at/~e0026607/ipod_remote/ipod_ap.html
      http://instruct1.cit.cornell.edu/courses/ee476/FinalProjects/s2007/awr8_asl45/awr8_asl45/index.html
      http://ipodlinux.org/wiki/Apple_Accessory_Protocol
      http://pinouts.ru/Devices/ipod_pinout.shtml
-----------------------------------------------------
Mode 2 Commands
Command             |Purpose
-----------------------------------------------------
0x00 0x00            |Button Released
0x00 0x01            |Play
0x00 0x02            |Vol+
0x00 0x04            |Vol-
0x00 0x08            |Skip>
0x00 0x10            |Skip<
0x00 0x20            |Next Album
0x00 0x40            |Previous Album
0x00 0x80            |Stop
-----------------------------------------------------
*/

//Debug switch
//boolean DEBUG = true;                             //Send serial output in HEX with other formatting
boolean DEBUG = false;                          //Send serial output in BYTE for iPod connection

//Variables for the buttons
int buttonPins[] = {14, 15, 16, 17, 18};          //Array containing the pins the buttons are connected to
int numberOfButtons = 5;                          //The number of buttons connected
boolean buttonStates[]={false,false,false,false,false};    //Arrays for storing button information in
int buttonPresent[]={HIGH,HIGH,HIGH,HIGH,HIGH};    //Arrays for storing buttons states in
int buttonPrevious[]={HIGH,HIGH,HIGH,HIGH,HIGH};       // "
long time;                                        //To keep track of the time for debouncing
int debounce = 200;                               //The debounce delay (from the last button push to the next)

//Define commands for iPod mode 2
byte switchMode2[] =             {0xFF, 0x55, 0x03, 0x00, 0x01, 0x02, 0xFA};
byte buttonRelease =             0x00;
byte PlayPause2 =            0x01;
byte VolUp2 =                  0x02;
byte VolDown2 =                  0x04;
byte SkipForward2 =            0x08;
byte SkipBack2 =            0x10;
byte NextAlbum2 =            0x20;
byte PreviousAlbum2 =            0x40;
byte Stop2 =                    0x80;

void setup ()
{
  //Start the serial connection
  beginSerial(19200);
  
  //Setup the buttons
  for (int i=0; i<numberOfButtons; i++)
  {
    pinMode(buttonPins[i], INPUT);
  }
  
  //Switch to mode 2 (simple ipod remote mode)
  if (DEBUG){Serial.print("Mode 2: ");}
  for (int i = 0; i < 7; i++) {
    if (DEBUG)
    {
      Serial.print(switchMode2[i],HEX);
      Serial.print(" ");
    }else{
      Serial.print(switchMode2[i],BYTE);
    }
  }
  if (DEBUG){Serial.println();}
}      

void loop ()
{
  //Loop through the amount of buttons
  for (int button=0; button<numberOfButtons; button++)
  {
    //Update the present state of the button
    buttonPresent[button] = digitalRead(buttonPins[button]);
    //If the button state has changed and the debounce duration has passed
    //The debounce period will work for all buttons. This means it will stop different buttons being pressed
    // within the debounce period but this shouldn't be too much of an issue.
    if (buttonPresent[button] != buttonPrevious[button] && millis() - time > debounce)
    {
      //If the button is pressed...
      if (buttonPresent[button] == LOW)
      {
        //Update the button's state in the array
        buttonStates[button] = true;
        if (DEBUG){Serial.print("Button: ");Serial.print(button);Serial.print("  Pressed   ");}
        //Update the time the last button was pressed
        time = millis();
        //Depending on what buttons been pressed send a command
        switch (button)
        {
        case 0:
          sendCommand(VolDown2);
          break;
        case 1:
          sendCommand(VolUp2);
          break;
        case 2:
          sendCommand(SkipBack2);
          break;
        case 3:
          sendCommand(PlayPause2);
          break;
        case 4:
          sendCommand(SkipForward2);
          break;
        }
      //If the button is not pressed...
      }else{
        //Update the button's state in the array
        buttonStates[button] = false;
        if (DEBUG){Serial.print("Button: ");Serial.print(button);Serial.print("  Released  ");}
        //Send the button release command
        sendCommand(buttonRelease);
      }
      //Update the button's previous state in the array
      buttonPrevious[button] = buttonPresent[button];
    }

  }
}

void sendCommand(byte cmd)
{
  //Create a checksum for the command
  byte cs = checkSum(0x03, 0x02, 0x00, cmd, 0x00);
  //Create a bytes to be sent array
  byte bytes[] = {0xFF, 0x55, 0x03, 0x02, 0x00, cmd, cs};
  if (DEBUG){Serial.print("Command: ");Serial.print(cmd, HEX);Serial.print("  ");}
  //Send the bytes
  for (int i = 0; i < 7; i++)
  {
    if (DEBUG)
    {
      Serial.print(bytes[i], HEX);
      Serial.print(" ");
    }else{
      Serial.print(bytes[i], BYTE);
    }
  }
  if (DEBUG){Serial.println("");}
}

int checkSum(byte len, byte mode, byte command1, byte command2, byte parameter)
{
  byte checksum = 0x100 - ((len + mode + command1 + command2 + parameter) & 0xFF);
  return checksum;
}

I've made some advances with Advanced iPod Remote mode (mode 4) as well but no luck in getting text returned as yet. There's also no volume control that I can find in mode 4 which would mean I'd need some more circuitry...

Hi, what model ipod are you controlling with this. thanks

I've used a 5th generation (the one with video).

I've lent my girlfriend's 3rd generation to a friend but will test that when it gets back!

just finished building it, works perfect with ipod 6G Classic

what did you use to connect to the ipod did you use the one that comes with it when you buy it?

I bought a couple of connectors from here:

http://home.swipnet.se/ridax/connector.htm

With my eyesight and fat soldering iron they are tough to solder to, I should have gone with the breakout board seeedstudio recommended earlier in the thread to start with! :wink:

i used a cheap 99p ipod cable, they only come with 4 pins for usb charging. but you can easily pull the pins and move them.

Sounds interesting... and cheap!

Where did you get that from?

there from the 99p shop. they have similar ones on ebay very cheap.