I might buy this bluetooth module and throw it in my setup & see how it sounds...it's cheap, less than $20 shipped...
http://www.elecfreaks.com/store/audio-bluetooth-speaker-modulebc05b-p-435.html
I'll post if I buy it & let everyone know how it sounds.
My buddy has been trying to convince me to disassemble an old Airport Express (the wall-wart type, not the AppleTV type) and use the guts as the audio source; sounds good, but it's big as hell.
Friday, October 12, 2012
Thursday, October 11, 2012
Possible New Name
So, the Belkin F8Z492TTP device SUCKS. The sound quality is so shitty, it's amazing. I wired a 3.5mm plug inside my box so I can plug a line directly into the sound system, or through the bluetooth dongle. The sound quality is night & day. The direct connect almost sounds too bass-y, but with the shitty Belkin module, there are no mids. It sounds metallic and hollow like you're listening to your music from a boombox in a hallway.
Hence the name change...I could maybe buy a different bluetooth module (I was looking at the Logitech 980-000540; it has great reviews for sound quality, but it's big as shit), but another problem I've noticed is the lack of "auto reconnect" that these bluetooth devices (don't) have. It's kind of a PITA to have to reselect and connect to the damn thing each & everytime you want to use it.
So for the meantime, I've changed the SID to display "iSaab Aux". It's more generic but still gets the point across.
Code for the SID change is below.
// ----------------------------------------------
// SECUDUINO
// http://secuduino.blogspot.com/
// By Igor Real
// 16/05/2011
//
// Saab CDC Changer Emulator
// http://BlueSaab.blogspot.com/
// By Seth Evans
// 5 Oct 2012
// ----------------------------------------------
#include <CAN.h>
int cdbutton;
void setup() {
// set up CAN
CAN.begin(47); // Saab I-Bus is 47.619kbps
Serial.begin(115200);
cdbutton = 0;
CAN_TxMsg.header.rtr=0; // this value never changes
CAN_TxMsg.header.length=8; // this value never changes
}
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();
if (cdbutton==1) {
Serial.println("iPod ON");
iPodOn();
}
else {
Serial.println("iPod OFF");
//iPodOff();
//delay(400);
}
for (int i = 0; i <= 900; i++) {
delay(1);
// this loop takes 850ms
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");
break;
case 0x14:
cdbutton = 0;
Serial.println("Radio");
break;
}
}
}
}
}
}
void CDC() {
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 0ms
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]=0x69; // i
CAN_TxMsg.data[4]=0x53; // S
CAN_TxMsg.data[5]=0x61; // a
CAN_TxMsg.data[6]=0x61; // a
CAN_TxMsg.data[7]=0x62; // b
CAN.send(&CAN_TxMsg);
delay(10);
CAN_TxMsg.data[0]=0x01; // message 1
CAN_TxMsg.data[3]=0x20; // _
CAN_TxMsg.data[4]=0x41; // A
CAN_TxMsg.data[5]=0x75; // u
CAN_TxMsg.data[6]=0x78; // x
CAN_TxMsg.data[7]=0x20; // _
CAN.send(&CAN_TxMsg);
delay(10);
CAN_TxMsg.data[0]=0x00; // message 0
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);
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==0x3C0) {
Serial.print(CAN_RxMsg.id,HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[0],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[1],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[2],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[3],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[4],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[5],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[6],HEX);
Serial.print(";");
Serial.println(CAN_RxMsg.data[7],HEX);
}
}
Hence the name change...I could maybe buy a different bluetooth module (I was looking at the Logitech 980-000540; it has great reviews for sound quality, but it's big as shit), but another problem I've noticed is the lack of "auto reconnect" that these bluetooth devices (don't) have. It's kind of a PITA to have to reselect and connect to the damn thing each & everytime you want to use it.
So for the meantime, I've changed the SID to display "iSaab Aux". It's more generic but still gets the point across.
Code for the SID change is below.
// ----------------------------------------------
// SECUDUINO
// http://secuduino.blogspot.com/
// By Igor Real
// 16/05/2011
//
// Saab CDC Changer Emulator
// http://BlueSaab.blogspot.com/
// By Seth Evans
// 5 Oct 2012
// ----------------------------------------------
#include <CAN.h>
int cdbutton;
void setup() {
// set up CAN
CAN.begin(47); // Saab I-Bus is 47.619kbps
Serial.begin(115200);
cdbutton = 0;
CAN_TxMsg.header.rtr=0; // this value never changes
CAN_TxMsg.header.length=8; // this value never changes
}
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();
if (cdbutton==1) {
Serial.println("iPod ON");
iPodOn();
}
else {
Serial.println("iPod OFF");
//iPodOff();
//delay(400);
}
for (int i = 0; i <= 900; i++) {
delay(1);
// this loop takes 850ms
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");
break;
case 0x14:
cdbutton = 0;
Serial.println("Radio");
break;
}
}
}
}
}
}
void CDC() {
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 0ms
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]=0x69; // i
CAN_TxMsg.data[4]=0x53; // S
CAN_TxMsg.data[5]=0x61; // a
CAN_TxMsg.data[6]=0x61; // a
CAN_TxMsg.data[7]=0x62; // b
CAN.send(&CAN_TxMsg);
delay(10);
CAN_TxMsg.data[0]=0x01; // message 1
CAN_TxMsg.data[3]=0x20; // _
CAN_TxMsg.data[4]=0x41; // A
CAN_TxMsg.data[5]=0x75; // u
CAN_TxMsg.data[6]=0x78; // x
CAN_TxMsg.data[7]=0x20; // _
CAN.send(&CAN_TxMsg);
delay(10);
CAN_TxMsg.data[0]=0x00; // message 0
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);
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==0x3C0) {
Serial.print(CAN_RxMsg.id,HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[0],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[1],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[2],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[3],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[4],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[5],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[6],HEX);
Serial.print(";");
Serial.println(CAN_RxMsg.data[7],HEX);
}
}
Friday, October 5, 2012
Photos!
Here are a few I took
This view is the opposite angle, trying to view the Secuduino board on the very bottom. |
All finished??
So I rearranged some code to more efficiently check for the radio/cdc selection, as well as not flood the bus with CDC messages. So now the code runs the CDC command every 900 or 950ms depending if the SID is displaying text.
The SID also displays the text cleaner, either because I'm using 348 and 368 messages, or because I'm sending them with priority 18 (I think). I think the CDC is normally priority 19, so anything lower than that is a higher priority. I don't want to completely take over the SID in case an alert from the car pops up, so anything lower than 19 should work. Currently, the SID will alternate flashing "BlueSaab" and "CD1 PLAY" a few times back and forth, then eventually "BlueSaab" will "win" and stay steady. Seems to be pretty steady, and my turn signals seem to be working, so I don't think the bus is overloaded :)
// ----------------------------------------------
// SECUDUINO
// http://secuduino.blogspot.com/
// By Igor Real
// 16/05/2011
//
// Saab CDC Changer Emulator
// http://BlueSaab.blogspot.com/
// By Seth Evans
// 5 Oct 2012
// ----------------------------------------------
#include <CAN.h>
int cdbutton;
void setup() {
// set up CAN
CAN.begin(47); // Saab I-Bus is 47.619kbps
Serial.begin(115200);
cdbutton = 0;
CAN_TxMsg.header.rtr=0; // this value never changes
CAN_TxMsg.header.length=8; // this value never changes
}
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();
if (cdbutton==1) {
Serial.println("iPod ON");
iPodOn();
}
else {
Serial.println("iPod OFF");
//iPodOff();
//delay(400);
}
for (int i = 0; i <= 900; i++) {
delay(1);
// this loop takes 900ms
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");
break;
case 0x14:
cdbutton = 0;
Serial.println("Radio");
break;
}
}
}
}
}
}
void CDC() {
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]=0x42; // B
CAN_TxMsg.data[4]=0x6C; // l
CAN_TxMsg.data[5]=0x75; // u
CAN_TxMsg.data[6]=0x65; // e
CAN_TxMsg.data[7]=0x53; // S
CAN.send(&CAN_TxMsg);
delay(10);
CAN_TxMsg.data[0]=0x01; // message 1
CAN_TxMsg.data[3]=0x61; // a
CAN_TxMsg.data[4]=0x61; // a
CAN_TxMsg.data[5]=0x62; // b
CAN_TxMsg.data[6]=0x00; // _
CAN_TxMsg.data[7]=0x00; // _
CAN.send(&CAN_TxMsg);
delay(10);
CAN_TxMsg.data[0]=0x00; // message 0
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);
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==0x3C0) {
Serial.print(CAN_RxMsg.id,HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[0],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[1],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[2],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[3],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[4],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[5],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[6],HEX);
Serial.print(";");
Serial.println(CAN_RxMsg.data[7],HEX);
}
}
The SID also displays the text cleaner, either because I'm using 348 and 368 messages, or because I'm sending them with priority 18 (I think). I think the CDC is normally priority 19, so anything lower than that is a higher priority. I don't want to completely take over the SID in case an alert from the car pops up, so anything lower than 19 should work. Currently, the SID will alternate flashing "BlueSaab" and "CD1 PLAY" a few times back and forth, then eventually "BlueSaab" will "win" and stay steady. Seems to be pretty steady, and my turn signals seem to be working, so I don't think the bus is overloaded :)
// ----------------------------------------------
// SECUDUINO
// http://secuduino.blogspot.com/
// By Igor Real
// 16/05/2011
//
// Saab CDC Changer Emulator
// http://BlueSaab.blogspot.com/
// By Seth Evans
// 5 Oct 2012
// ----------------------------------------------
#include <CAN.h>
int cdbutton;
void setup() {
// set up CAN
CAN.begin(47); // Saab I-Bus is 47.619kbps
Serial.begin(115200);
cdbutton = 0;
CAN_TxMsg.header.rtr=0; // this value never changes
CAN_TxMsg.header.length=8; // this value never changes
}
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();
if (cdbutton==1) {
Serial.println("iPod ON");
iPodOn();
}
else {
Serial.println("iPod OFF");
//iPodOff();
//delay(400);
}
for (int i = 0; i <= 900; i++) {
delay(1);
// this loop takes 900ms
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");
break;
case 0x14:
cdbutton = 0;
Serial.println("Radio");
break;
}
}
}
}
}
}
void CDC() {
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]=0x42; // B
CAN_TxMsg.data[4]=0x6C; // l
CAN_TxMsg.data[5]=0x75; // u
CAN_TxMsg.data[6]=0x65; // e
CAN_TxMsg.data[7]=0x53; // S
CAN.send(&CAN_TxMsg);
delay(10);
CAN_TxMsg.data[0]=0x01; // message 1
CAN_TxMsg.data[3]=0x61; // a
CAN_TxMsg.data[4]=0x61; // a
CAN_TxMsg.data[5]=0x62; // b
CAN_TxMsg.data[6]=0x00; // _
CAN_TxMsg.data[7]=0x00; // _
CAN.send(&CAN_TxMsg);
delay(10);
CAN_TxMsg.data[0]=0x00; // message 0
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);
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==0x3C0) {
Serial.print(CAN_RxMsg.id,HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[0],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[1],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[2],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[3],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[4],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[5],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[6],HEX);
Serial.print(";");
Serial.println(CAN_RxMsg.data[7],HEX);
}
}
Thursday, October 4, 2012
New Diagram
Here's the updated diagram for the entire setup. I was actually able to cram ALL 4 boards into one small box, about 4" x 2" x 1" !!! I have 2 connectors, one that connects to the CDC connector, and the other is simply the Arduino programming port so I don't have to open the box up to edit the firmware/program.
Hardware = finished; Software = eh...
So I got the inverter chip (TC962EPA) which inverts any input from +3 to +18V and wired it up so it's giving the Saablin board the -12V for the OpAmps....it works great! The ground loop isolator made the sound quiet, and a little hollow, and seemed to miss some lows (although it shouldn't have according to the specs). Rass' Saablin board with the opamps sounds a little hollow, but the lows came back, and overall, it sounds wonderful :)
Rass' website here: http://saablin.net/
Rass' Saablin Balanced Audio circuit board: http://saablin.net/node/10
BatchPCB board for order: https://www.batchpcb.com/product_info.php?products_id=31438&check=04c8d356c127174ce72449dcbc8523ce
Rass' website here: http://saablin.net/
Rass' Saablin Balanced Audio circuit board: http://saablin.net/node/10
BatchPCB board for order: https://www.batchpcb.com/product_info.php?products_id=31438&check=04c8d356c127174ce72449dcbc8523ce
I still need to update my entire diagram to replace the dual ground loop isolator & replace it with Rass' Saablin board.
As for the software....it still has the display glitch that flickers "BlueSaab" with "CD1 Play".
// ----------------------------------------------
// SECUDUINO
// http://secuduino.blogspot.com/
// By Igor Real
// 16/05/2011
//
// Saab CDC Changer Emulator
// http://BlueSaab.blogspot.com/
// By Seth Evans
// 4 Oct 2012
// ----------------------------------------------
#include <CAN.h>
int cdbutton;
void setup() {
// set up CAN
CAN.begin(47); // Saab I-Bus is 47.619kbps
Serial.begin(115200);
cdbutton = 0;
CAN_TxMsg.header.rtr=0; // this value never changes
CAN_TxMsg.header.length=8; // this value never changes
}
void loop() {
CDC();
delay(5);
if (CAN.CheckNew()) {
CAN_TxMsg.data[0]++;
CAN.ReadFromDevice(&CAN_RxMsg);
//PrintBus();
if (CAN_RxMsg.id==0x3C0) {
//CDC();
//delay(5);
if (CAN_RxMsg.data[0]==0x80) {
switch (CAN_RxMsg.data[1]) {
case 0x24:
cdbutton = 1;
Serial.println("CDC");
break;
case 0x14:
cdbutton = 0;
Serial.println("Radio");
break;
//case default:
} // end of switch case
//else if (CAN_RxMsg.data[0]==0x80 && CAN_RxMsg.data[1]==0x14)
}
}
}
if (cdbutton==1) {
//CDC();
//delay(5);
iPodOn();
}
else {
iPodOff();
}
}
void CDC() {
CAN_TxMsg.id=0x6A2; //
CAN_TxMsg.data[0]=0x32;
CAN_TxMsg.data[1]=0x00;
CAN_TxMsg.data[2]=0x00;
CAN_TxMsg.data[3]=0x16; //
CAN_TxMsg.data[4]=0x01;
CAN_TxMsg.data[5]=0x02;
CAN_TxMsg.data[6]=0x00;
CAN_TxMsg.data[7]=0x00; //
CAN.send(&CAN_TxMsg);
delay(5);
CAN_TxMsg.id=0x3C8; // CD Changer
CAN_TxMsg.data[0]=0xE0;
CAN_TxMsg.data[1]=0x00;
CAN_TxMsg.data[2]=0x3F;
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() {
CAN_TxMsg.id=0x328; // SID audio text
CAN_TxMsg.data[0]=0x42;
CAN_TxMsg.data[1]=0x96;
CAN_TxMsg.data[2]=0x02;
CAN_TxMsg.data[3]=0x42; // B
CAN_TxMsg.data[4]=0x6C; // l
CAN_TxMsg.data[5]=0x75; // u
CAN_TxMsg.data[6]=0x65; // e
CAN_TxMsg.data[7]=0x53; // S
CAN.send(&CAN_TxMsg);
delay(5);
CAN_TxMsg.data[0]=0x01;
CAN_TxMsg.data[3]=0x61; // a
CAN_TxMsg.data[4]=0x61; // a
CAN_TxMsg.data[5]=0x62; // b
CAN_TxMsg.data[6]=0x00; // _
CAN_TxMsg.data[7]=0x00; // _
CAN.send(&CAN_TxMsg);
delay(5);
CAN_TxMsg.data[0]=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(5);
CAN_TxMsg.id=0x368; // enable the SID (audio) 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(5);
}
void iPodOff() {
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(";");
Serial.print(CAN_RxMsg.data[0],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[1],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[2],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[3],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[4],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[5],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[6],HEX);
Serial.print(";");
Serial.println(CAN_RxMsg.data[7],HEX);
}
}
Tuesday, October 2, 2012
Maybe it STILL needs tweaking....
So after work today, the display went blank, except for small blips of "BlueSaab", so it's working somewhat...more tweaking tomm!
Smooth display
I think I finally got the SID to display "BlueSaab" without flickering now. I don't know why, but I'm using the 348 ID to say "1102FF1900000000" after I send the "BlueSaab" text...I thought that 348 command would turn the text off, but I guess it turned off the "CD1 PLAY" text!
I still have 2 issues...
1, the Arduino has problems where it will miss my button press to go to the CDC or Radio, thereby still displaying "BlueSaab" (or not, depending on your intended source). Several cycles through the sources (easiest with the SRC button on the steering wheel) will usually catch whatever source you need, and match the SID to it.
2, If playing BlueSaab and you turn the radio off, the SID still displays "BlueSaab". This is remedied by turning the head unit back on, switching to Radio, and turning the radio off. The sound turns off, but the SID does not. It's still something with the Arduino not catching button clicks. I may have to add an "If/Then" or "switch" to catch the power down mode & turn off the SID.
New code!
// ----------------------------------------------
// SECUDUINO
// http://secuduino.blogspot.com/
// By Igor Real
// 16/05/2011
//
// Saab CDC Changer Emulator
// Seth Evans
// 2 Oct 2012
// ----------------------------------------------
#include <CAN.h>
int cdbutton;
void setup() {
// set up CAN
CAN.begin(47); // Saab I-Bus is 47.619kbps
Serial.begin(115200);
cdbutton = 0;
CAN_TxMsg.header.rtr=0; // this value never changes
CAN_TxMsg.header.length=8; // this value never changes
}
void loop() {
CDC();
delay(5);
if (CAN.CheckNew()) {
CAN_TxMsg.data[0]++;
CAN.ReadFromDevice(&CAN_RxMsg);
//PrintBus();
if (CAN_RxMsg.id==0x3C0) {
//CDC();
//delay(5);
if (CAN_RxMsg.data[0]==0x80) {
switch (CAN_RxMsg.data[1]) {
case 0x24:
cdbutton = 1;
Serial.println("CDC");
break;
case 0x14:
cdbutton = 0;
Serial.println("Radio");
break;
//case default:
} // end of switch case
//else if (CAN_RxMsg.data[0]==0x80 && CAN_RxMsg.data[1]==0x14)
}
}
}
if (cdbutton==1) {
//CDC();
//delay(5);
iPodOn();
}
else {
iPodOff();
}
}
void CDC() {
CAN_TxMsg.id=0x6A2; //
CAN_TxMsg.data[0]=0x32;
CAN_TxMsg.data[1]=0x00;
CAN_TxMsg.data[2]=0x00;
CAN_TxMsg.data[3]=0x16; //
CAN_TxMsg.data[4]=0x01;
CAN_TxMsg.data[5]=0x02;
CAN_TxMsg.data[6]=0x00;
CAN_TxMsg.data[7]=0x00; //
CAN.send(&CAN_TxMsg);
delay(5);
CAN_TxMsg.id=0x3C8; // CD Changer
CAN_TxMsg.data[0]=0xE0;
CAN_TxMsg.data[1]=0x00;
CAN_TxMsg.data[2]=0x3F;
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() {
CAN_TxMsg.id=0x328; // SID audio text
CAN_TxMsg.data[0]=0x42;
CAN_TxMsg.data[1]=0x96;
CAN_TxMsg.data[2]=0x02;
CAN_TxMsg.data[3]=0x42; // B
CAN_TxMsg.data[4]=0x6C; // l
CAN_TxMsg.data[5]=0x75; // u
CAN_TxMsg.data[6]=0x65; // e
CAN_TxMsg.data[7]=0x53; // S
CAN.send(&CAN_TxMsg);
delay(5);
CAN_TxMsg.data[0]=0x01;
CAN_TxMsg.data[3]=0x61; // a
CAN_TxMsg.data[4]=0x61; // a
CAN_TxMsg.data[5]=0x62; // b
CAN_TxMsg.data[6]=0x00; // _
CAN_TxMsg.data[7]=0x00; // _
CAN.send(&CAN_TxMsg);
delay(5);
CAN_TxMsg.data[0]=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(5);
CAN_TxMsg.id=0x348; // enable the SID (audio) text?
CAN_TxMsg.data[0]=0x11;
CAN_TxMsg.data[1]=0x02;
CAN_TxMsg.data[2]=0xFF;
CAN_TxMsg.data[3]=0x19;
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(5);
}
void iPodOff() {
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(";");
Serial.print(CAN_RxMsg.data[0],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[1],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[2],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[3],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[4],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[5],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[6],HEX);
Serial.print(";");
Serial.println(CAN_RxMsg.data[7],HEX);
}
}
I still have 2 issues...
1, the Arduino has problems where it will miss my button press to go to the CDC or Radio, thereby still displaying "BlueSaab" (or not, depending on your intended source). Several cycles through the sources (easiest with the SRC button on the steering wheel) will usually catch whatever source you need, and match the SID to it.
2, If playing BlueSaab and you turn the radio off, the SID still displays "BlueSaab". This is remedied by turning the head unit back on, switching to Radio, and turning the radio off. The sound turns off, but the SID does not. It's still something with the Arduino not catching button clicks. I may have to add an "If/Then" or "switch" to catch the power down mode & turn off the SID.
New code!
// ----------------------------------------------
// SECUDUINO
// http://secuduino.blogspot.com/
// By Igor Real
// 16/05/2011
//
// Saab CDC Changer Emulator
// Seth Evans
// 2 Oct 2012
// ----------------------------------------------
#include <CAN.h>
int cdbutton;
void setup() {
// set up CAN
CAN.begin(47); // Saab I-Bus is 47.619kbps
Serial.begin(115200);
cdbutton = 0;
CAN_TxMsg.header.rtr=0; // this value never changes
CAN_TxMsg.header.length=8; // this value never changes
}
void loop() {
CDC();
delay(5);
if (CAN.CheckNew()) {
CAN_TxMsg.data[0]++;
CAN.ReadFromDevice(&CAN_RxMsg);
//PrintBus();
if (CAN_RxMsg.id==0x3C0) {
//CDC();
//delay(5);
if (CAN_RxMsg.data[0]==0x80) {
switch (CAN_RxMsg.data[1]) {
case 0x24:
cdbutton = 1;
Serial.println("CDC");
break;
case 0x14:
cdbutton = 0;
Serial.println("Radio");
break;
//case default:
} // end of switch case
//else if (CAN_RxMsg.data[0]==0x80 && CAN_RxMsg.data[1]==0x14)
}
}
}
if (cdbutton==1) {
//CDC();
//delay(5);
iPodOn();
}
else {
iPodOff();
}
}
void CDC() {
CAN_TxMsg.id=0x6A2; //
CAN_TxMsg.data[0]=0x32;
CAN_TxMsg.data[1]=0x00;
CAN_TxMsg.data[2]=0x00;
CAN_TxMsg.data[3]=0x16; //
CAN_TxMsg.data[4]=0x01;
CAN_TxMsg.data[5]=0x02;
CAN_TxMsg.data[6]=0x00;
CAN_TxMsg.data[7]=0x00; //
CAN.send(&CAN_TxMsg);
delay(5);
CAN_TxMsg.id=0x3C8; // CD Changer
CAN_TxMsg.data[0]=0xE0;
CAN_TxMsg.data[1]=0x00;
CAN_TxMsg.data[2]=0x3F;
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() {
CAN_TxMsg.id=0x328; // SID audio text
CAN_TxMsg.data[0]=0x42;
CAN_TxMsg.data[1]=0x96;
CAN_TxMsg.data[2]=0x02;
CAN_TxMsg.data[3]=0x42; // B
CAN_TxMsg.data[4]=0x6C; // l
CAN_TxMsg.data[5]=0x75; // u
CAN_TxMsg.data[6]=0x65; // e
CAN_TxMsg.data[7]=0x53; // S
CAN.send(&CAN_TxMsg);
delay(5);
CAN_TxMsg.data[0]=0x01;
CAN_TxMsg.data[3]=0x61; // a
CAN_TxMsg.data[4]=0x61; // a
CAN_TxMsg.data[5]=0x62; // b
CAN_TxMsg.data[6]=0x00; // _
CAN_TxMsg.data[7]=0x00; // _
CAN.send(&CAN_TxMsg);
delay(5);
CAN_TxMsg.data[0]=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(5);
CAN_TxMsg.id=0x348; // enable the SID (audio) text?
CAN_TxMsg.data[0]=0x11;
CAN_TxMsg.data[1]=0x02;
CAN_TxMsg.data[2]=0xFF;
CAN_TxMsg.data[3]=0x19;
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(5);
}
void iPodOff() {
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(";");
Serial.print(CAN_RxMsg.data[0],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[1],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[2],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[3],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[4],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[5],HEX);
Serial.print(";");
Serial.print(CAN_RxMsg.data[6],HEX);
Serial.print(";");
Serial.println(CAN_RxMsg.data[7],HEX);
}
}
Subscribe to:
Posts (Atom)