Tuesday, February 26, 2013

Parts list & notes

Some notes on the circuit board...In order to make the circuit board one layer (plus the one jumper), I removed any unused pins on the ICs...but I removed these pins on the SOCKETS, not the ICs. This makes removing/reinstalling ICs easy without having to modify them. Just pay attention to orientation :)

Also, if you don't want to pay for the DRV134PA drivers, you can actually request a sample of 1-3 of them from Texas Instruments for free! :D

Partlist












Exported from Seth Saab Interface PTH CU3242.brd at 2/26/2013 9:13:58 AM






EAGLE Version 6.4.0 Copyright (c) 1988-2013 CadSoft







Assembly variant:











Part Value Package Library Position (mm) Orientation







C1 470nF C025-025X050 rcl (49.25 19.25) R0
C2 .1uF C025-025X050 rcl (50.5 12) R90
C6 0.1uF C025-025X050 rcl (72.665 17.455) MR270
C7 100nF C025-025X050 rcl (28.6 10.5) MR270
C8 100nF C025-025X050 rcl (31.95 16.4) MR270
C9 1uF E2,5-5 resistor (43.44 17.98) MR0
C10 1uF E2,5-5 resistor (29.9 22.4) MR0
C11 10uF C025-030X050 rcl (9.985 35.045) MR180
C12 10uF C025-030X050 rcl (10.015 49.675) MR0
C13 10uF C025-030X050 rcl (9.82 15.045) MR180
C14 10uF C025-030X050 rcl (9.93 30.175) MR0
C15 10uF E2,5-5 resistor (26 47.875) MR180
C16 10uF E2,5-5 resistor (29.875 28.75) MR0
C17 100nF C025-025X050 rcl (31.95 10.5) MR270
C18 100nF C025-025X050 rcl (28.6 16.4) MR270
C19 1uF E2,5-5 resistor (43.44 25.265) MR0
C20 1uF E2,5-5 resistor (33.645 34.405) MR0
CANBUS 1X02 pinhead (25.395 56.215) MR180
D1 1N4007-01 D01B diodes (54 19.125) R0
FTDI 22-27-2061-06 6410-06 con-molex (60.775 13.245) MR0
GND 1X01 pinhead (13.765 55.755) MR0
IC1 SN65HVD251P DIL08 ti-can-seth (25.255 64.585) MR180
IC2 MCP2515-E/P DIL18 mcp2515-seth (47.58 61.465) MR180
IC3 MEGA8-P DIL28-3-SETH atmel-seth (56.485 40.15) MR0
IC4 7805 78XXS v-reg (53.965 22.605) MR180
LED1 LED5MM led (70.75 50) MR0
LED2 LED5MM led (70.75 58) MR0
LED3 LED5MM led (61.25 30.25) R180
L_IN 1X01 pinhead (16.515 49.815) MR0
L_OUT 1X02 pinhead (4.8 42.045) MR90
N1 LTC1144 DIP08L-SETH ic-seth (27.35 39.365) MR180
PWR_IN 1X02 pinhead (43.305 12.71) MR0
R1 330R 0207/10 rcl (60.25 50) MR0
R2 10K 0207/10 rcl (67.665 24.895) MR180
R3 330R 0207/10 rcl (63 53.5) MR0
R4 10K 0207/2V rcl (38.5 53.5) R180
R5 10K 0204/7 rcl (18.125 64.625) R90
R6 330R 0207/2V rcl (55.25 30.24) R180
RX 1X01 pinhead (62 18.75) MR0
R_IN 1X01 pinhead (16.45 31.315) MR0
R_OUT 1X02 pinhead (4.88 22.705) MR90
TX 1X01 pinhead (64.625 18.75) R0
U$1 DRV134PA DIL08 BurrBrownAudioParts (12.555 42.19) MR180
U$2 DRV134PA DIL08 BurrBrownAudioParts (12.47 22.69) MR180
U$3 RESONATORPTH RESONATOR-PTH SparkFun-3-2-07 (47.25 31.875) MR0
U$5 RESONATORPTH RESONATOR-PTH SparkFun-3-2-07 (52.75 70.25) MR180

Tuesday, February 19, 2013

Wiring

I kinda forgot to update on my wiring...

This first diagram is how I have the connector wired where the original CD changer connector used to be. I have an 8-pin molex connector here now, just extra I had laying around. I think this connector is actually too small for the wiring in the car, but it's working so far. I would probably suggest a larger connector, with larger pins to accomodate the wire size better.


I decided to use an ethernet cable to make all the connections modular. One end of the ethernet cable goes to the front of the car, the other to the trunk. I cut off one end of the ethernet cable to make routing it easier, and then I crimped on a 5-pin Molex connector like the 8-pin above. I have an RJ45 receptacle that's wired to my iPod dock connector, which of course plugs into my iPod/iPhone.

I used the schematics here to determine what pins I needed off the iPod.

Inside the iPod connector, I put a 500K ohm resistor from 21 to ground to allow the iPod to accept serial communication so we can control the iPod, and I *THINK* I put a 10K ohm resistor from 5V in to both 25 and 27 (USB D+ and D-); this should put 2V on those pins, making the iPod draw 500mA to charge. Notice there is a switch inline with the power adapter, so I can turn off the charger at will (there's engine noise when the charger is on).
Also, I *MIGHT* have the iPod TX/RX lines swapped...I've gotten so confused with all the revisions of this damn thing that I think I might have them swapped. Not a big deal, it's easy to change them.

This schematic is a basic overview of the wiring involved from the iSaabAux board to the car and to the iPod. Not shown is the DB25 connectors I used to go from inside the case to the outside. You can use whatever you want of course, so that's not mandatory.

Monday, February 18, 2013

Newest hardware

Here are some pictures of my latest version of the iSaabAux input. I'm going to get an old female DB25 molded plug & replace this one without a housing, but this one works for now.
I cut a hole in the side of this enclosure for the 25 pin connector; it seemed like the best way to get all 18 wires outside the box.



Thursday, February 14, 2013

Here are the schematic & board files (EagleCad) so you can make your own iSaabAux board.


Schematic
Board file

I'm going to use this enclosure, a Bud Industries CU-3242-MB.

Wednesday, February 13, 2013

Newest update

Ok, a lot's changed since my last update.

I've added some things, deleted some things, but everything is working better than before. The new code below incorporates iPod control via the steering wheel (next track, previous track, random & shuffle toggles), and cleaner code. I had attempted to get text to scroll across the SID, but I guess that was too much information because nothing would display at all. Maybe in a future update. I have the working code to make the SID scroll text on a work bench, but it doesn't operate the same way in the car; probably too many CAN messages or something.


// ----------------------------------------------
// SECUDUINO
// http://secuduino.blogspot.com/
// By Igor Real
// 16/05/2011
//
// Saab CDC Changer Emulator
// http://BlueSaab.blogspot.com/
// By Seth Evans
// 23 Jan 2013
// ----------------------------------------------

#include <CAN.h>

int cdbutton = 0;
int toggleshuffle = 1;
int CDCcmd[] = {
  0xE0,0x00,0x3F,0x31,0xFF,0xFF,0xFF,0xD0};
int playipod[] = {
  0xFF,0x55,0x04,0x02,0x00,0x00,0x01,0xF9};
int stopipod[] = {
  0xFF,0x55,0x04,0x02,0x00,0x00,0x02,0xF8};
int next[] = {
  0xFF,0x55,0x03,0x02,0x00,0x08,0xF3};
int prev[] = {
  0xFF,0x55,0x03,0x02,0x00,0x10,0xEB};
int shuffle[] = {
  0xFF,0x55,0x04,0x02,0x00,0x00,0x80,0x7A};
int repeat[] = {
  0xFF,0x55,0x05,0x02,0x00,0x00,0x00,0x01,0xF8};
int buttonRelease[] = {
  0xFF,0x55,0x03,0x02,0x00,0x00,0xFB};

void setup() {
  // set up CAN
  CAN.begin(47);  // Saab I-Bus is 47.619kbps
  Serial.begin(9600);
  //cdbutton = 0;
  //toggleshuffle = 1;
  CAN_TxMsg.header.rtr=0;     // this value never changes
  CAN_TxMsg.header.length=8;  // this value never changes
  // not sure if this is needed; pauses program before it loops
  delay(2000);
}

void loop() {
  // CDC code needs sent every second or less so all loops
  // running added together need to take less than 1000ms
  // but no more or the car won't "see" the CDC
  CDC();
  for (int i = 0; i <= 800; i++) {
    if (CAN.CheckNew()) {
      CAN_TxMsg.data[0]++;
      CAN.ReadFromDevice(&CAN_RxMsg);
      //PrintBus();
      if (CAN_RxMsg.id==0x3C0) {
        if (CAN_RxMsg.data[0]==0x80) {
          switch (CAN_RxMsg.data[1]) {
          case 0x24:
            cdbutton = 1;
            //Serial.println("CDC");
            for (int j = 0; j < 9; j++) {
              Serial.write(byte(playipod[j]));
            }
            break;
          case 0x14:
            cdbutton = 0;  
            for (int j = 0; j < 9; j++) {
              Serial.write(byte(stopipod[j]));
            }
            //Serial.println("Radio");
            break;
          }
          delay(3);
          //Serial.println("Release");
          for (int i = 0; i < 8; i++) {
            Serial.write(byte(buttonRelease[i]));
          }
        }
      }
      if (CAN_RxMsg.id==0x290) {
        if (CAN_RxMsg.data[0]==0x80) {
          if (cdbutton == 1) {
            switch (CAN_RxMsg.data[2]) {
            case 0x10:
              //Serial.println("Next");
              for (int j = 0; j < 8; j++) {
                Serial.write(byte(next[j]));
              }
              break;
            case 0x08:
              //Serial.println("Prev");
              for (int k = 0; k < 8; k++) {
                Serial.write(byte(prev[k]));
              }
              break;
            case 0x04:
              if (toggleshuffle > 3) {
                toggleshuffle = 1;
              }
              switch (toggleshuffle) {
              case 1:
                for (int j = 0; j < 10; j++) {
                  Serial.write(byte(repeat[j]));
                }
                break;
              case 2:
                for (int j = 0; j < 10; j++) {
                  Serial.write(byte(repeat[j]));
                }
                break;
              case 3:
                for (int j = 0; j < 10; j++) {
                  Serial.write(byte(repeat[j]));
                }
                for (int j = 0; j < 9; j++) {
                  Serial.write(byte(shuffle[j]));
                }
                break;
              }
              toggleshuffle++;
              break;
            }
            delay(3);
            //Serial.println("Release");
            for (int i = 0; i < 8; i++) {
              Serial.write(byte(buttonRelease[i]));
            }
          }
        }
      }
    }
    delay(1);
  }
  if (cdbutton==1) {
    //Serial.println("iPod ON");
    iPodOn();
  }
  else {
    Serial.println("iPod OFF");
    //iPodOff();
    //delay(400);
  }
}

void CDC() {
  CAN_TxMsg.id=0x3C8;     // CD Changer
  for (int c = 0; c < 8; c++) {
    CAN_TxMsg.data[c]=CDCcmd[c];
  }
  CAN.send(&CAN_TxMsg);
  /*CAN_TxMsg.id=0x3C8;     // CD Changer
   CAN_TxMsg.data[0]=0xE0;
   CAN_TxMsg.data[1]=0x00;
   CAN_TxMsg.data[2]=0x3F; // all 6 discs inserted
   CAN_TxMsg.data[3]=0x31; // playing , disc 1
   CAN_TxMsg.data[4]=0xFF;
   CAN_TxMsg.data[5]=0xFF;
   CAN_TxMsg.data[6]=0xFF;
   CAN_TxMsg.data[7]=0xD0; // married "OK" code
   CAN.send(&CAN_TxMsg);
   */
}

void iPodOn() {
  // This loop takes 50ms
  CAN_TxMsg.id=0x328;     // SID audio text
  CAN_TxMsg.data[0]=0x42; // message 2
  CAN_TxMsg.data[1]=0x96;
  CAN_TxMsg.data[2]=0x02; // Row 2
  CAN_TxMsg.data[3]=0x20; // _
  CAN_TxMsg.data[4]=0x69; // i
  CAN_TxMsg.data[5]=0x53; // S
  CAN_TxMsg.data[6]=0x61; // a
  CAN_TxMsg.data[7]=0x61; // a
  CAN.send(&CAN_TxMsg);
  delay(10);

  CAN_TxMsg.data[0]=0x01; // message 1
  CAN_TxMsg.data[3]=0x62; // b
  CAN_TxMsg.data[4]=0x20; // _
  CAN_TxMsg.data[5]=0x41; // A
  CAN_TxMsg.data[6]=0x75; // u
  CAN_TxMsg.data[7]=0x78; // x
  CAN.send(&CAN_TxMsg);
  delay(10);

  CAN_TxMsg.data[0]=0x00; // message 0
  CAN_TxMsg.data[3]=0x20; // _
  CAN_TxMsg.data[4]=0x20; // _
  CAN_TxMsg.data[5]=0x20; //
  CAN_TxMsg.data[6]=0x20; //
  CAN_TxMsg.data[7]=0x20; //
  CAN.send(&CAN_TxMsg);
  delay(10);

  CAN_TxMsg.id=0x348;     // audio text control
  CAN_TxMsg.data[0]=0x11;
  CAN_TxMsg.data[1]=0x02; // Row 2
  CAN_TxMsg.data[2]=0x05;
  CAN_TxMsg.data[3]=0x18; // priority 18?
  CAN_TxMsg.data[4]=0x00;
  CAN_TxMsg.data[5]=0x00;
  CAN_TxMsg.data[6]=0x00;
  CAN_TxMsg.data[7]=0x00;
  CAN.send(&CAN_TxMsg);
  delay(10);

  CAN_TxMsg.id=0x368;     // SID text priority
  CAN_TxMsg.data[0]=0x02; // Row 2
  CAN_TxMsg.data[1]=0x18; // priority 18?
  CAN_TxMsg.data[2]=0x00;
  CAN_TxMsg.data[3]=0x00;
  CAN_TxMsg.data[4]=0x00;
  CAN_TxMsg.data[5]=0x00;
  CAN_TxMsg.data[6]=0x00;
  CAN_TxMsg.data[7]=0x00;
  CAN.send(&CAN_TxMsg);
  delay(10);
}

void iPodOff() {
  // I don't think this code is needed at all...
  CAN_TxMsg.id=0x368;     // turn off the SID (SPA) text
  CAN_TxMsg.data[0]=0x02;
  CAN_TxMsg.data[1]=0x19;
  CAN_TxMsg.data[2]=0x00;
  CAN_TxMsg.data[3]=0x00;
  CAN_TxMsg.data[4]=0x00;
  CAN_TxMsg.data[5]=0x00;
  CAN_TxMsg.data[6]=0x00;
  CAN_TxMsg.data[7]=0x00;
  CAN.send(&CAN_TxMsg);
  delay(10);
}

void PrintBus() {
  if (CAN_RxMsg.id==0x290) {
    Serial.print(CAN_RxMsg.id,HEX);
    Serial.print(";");
    for (int i = 0; i < 8; i++) {
      Serial.print(CAN_RxMsg.data[i],HEX);
      Serial.print(";");
    }
  }
}