Loading...
 

8192 ALDL

ALDL

#include <NewSoftSerial.h>
NewSoftSerial mySerial(2, 3);
const int rxControl=5;
bool inSync=false;
bool inMode1=false;
int mdelay=3350;

const int dataStreamSize=69;
unsigned char dataStream[dataStreamSize];

#define Bit_Set(port,bit_num) (port = port | (0x01 << bit_num))
#define Bit_Clear(port,bit_num) (port = port & ~(0x01 << bit_num))


void setup() {
 pinMode(rxControl,OUTPUT);
 digitalWrite(rxControl,LOW);
 mySerial.begin(57600);
 Serial.begin(8192);
}

void loop() {
 sendMode1();
 displayDataStream();
 
}

int sendMode1(void) {
 
 //Check if we are already synchronized. If not, wait for ecu to send 0xF0 probe
 //The delay takes a little bit of working out. 
 //(@16MHz 3389 works for AVR C, 3353 works for Arduino Serial)
 //
 if (inSync == false) {
   Bit_Clear(PORTD,rxControl);
   while (Serial.read() != 0xF0) {}
   Bit_Set(PORTD,rxControl);
   delayMicroseconds(mdelay);
 }
 
 //Send commands to ECU for mode 1
 Bit_Set(PORTD,rxControl);
 Serial.print(0xF0,BYTE);
 Serial.print(0x57,BYTE);
 Serial.print(0x01,BYTE);
 Serial.print(0x00,BYTE);
 Serial.print(0xB8,BYTE);
 Bit_Clear(PORTD,rxControl);
 
 //Start Reading Data. To save time, only read first 5 bytes.
 //If we are not in sync, we do not read the probe messages.
 for (int i=0; i < 5; i++) {
   while(!Serial.available()) {}
   dataStream[i] = Serial.read();
 }
 
 //The ECU will send a 0xF0 and 0x95 and 0x01 to indicate it is in mode 1
 //Different hardware moves this by a byte or two.
 if (!((dataStream[1] == 0xF0 && dataStream[2] == 0x95) || (dataStream[2] == 0xF0 && dataStream[3] == 0x95))) {
   Serial.flush();
   inSync = false;
   mdelay = mdelay + 1;
   return 3;
 }
 
 //Read the rest of the data stream if the first 5 bytes are ok.
 for (int i=5; i < dataStreamSize; i++) {
   while (!Serial.available()) {}
   dataStream[i] = Serial.read();
 }
 
 //check for 0xF0 and 0x95, this can probably be removed due to earlier check
 if (dataStream[2] == 0xF0 && dataStream[3] == 0x95) {
   inSync = true;
   return 1;
 } else {
   if (inSync == false) {
     mdelay = mdelay +1;
   }
   inSync = false;
   return 0;
 }
   
}

void displayDataStream(void) {
 for (int j=2; j < dataStreamSize; j++) {
     mySerial.print(dataStream[j],HEX);
 }
 mySerial.println();
 mySerial.print(mdelay);
 mySerial.print("\t");
 if (inSync) {
   mySerial.print("inSync\t");
   byte a = calcCheckSum(2);
   if (a != 0) {
     mySerial.print(a,HEX);
     mySerial.print("\t");
   }
 }
 mySerial.println(millis());
}

byte calcCheckSum(int dss) {
	//Pass the dataStreamStart(dss) as argument.
	byte checkSum=0;
	for (int cc=dss; cc < dataStreamSize; cc++) {
		checkSum += dataStream[cc];
	}
	return checkSum;
}




beginMode1 3361
dataStream copied to dataStreamp
F095124EB02004343130000006500800808A8A5F5FEDEFFB1D42DA78000882B5300000000000208081106F1D2020540240FF
3361    inSync  9578
checkSync failed!
beginMode1 3362
dataStream copied to dataStreamp
F095124EB02004343130000006500800808A8A5F5FEDEFFB1D43D979000882B5300000000000208081106F1D2020540240FE
3362    inSync  15183
checkSync failed!
beginMode1 3363




F055BB0000000000000000000000000000000000000000000000000000000000000000
3353    15696
F095124EB0200434313000000000800808A8A5F5FEFEFFB1D43D970002802B53000000000002080811001F424E054010056
3353    inSync  15997
F095124EB0200434313000000000800808A8A5F5FEFEFFB1D43D900005902B53000000000002080811001F424E0540112ED
3353    inSync  16116
F095124EB0200434313000000000800808A8A5F5FEFEFFB1D43D90000B1C2B53000000000002080811001F424E05401105D
3353    inSync  16234
F095124EB0200434313000000000800808A8A5F5FEFEFFB1D43D90000B1C2B53000000000002080811001F424E05401125B
3353    inSync  16352




#include <NewSoftSerial.h>
NewSoftSerial mySerial(2, 3);
const int rxControl=5;
bool inSync=false;
bool inMode1=false;
int dsCounter=0;
int mdelay=3360;

const int dataStreamSize=69;
unsigned char dataStream[dataStreamSize];
unsigned char dataStreamp[dataStreamSize];

#define Bit_Set(port,bit_num) (port = port | (0x01 << bit_num))
#define Bit_Clear(port,bit_num) (port = port & ~(0x01 << bit_num))


void setup() {
  pinMode(rxControl,OUTPUT);
  digitalWrite(rxControl,LOW);
  mySerial.begin(57600);
  Serial.begin(8192);
  beginMode1();
}

void loop() {
  //sendMode1();
  if (Serial.available() > 5 && dsCounter == 0) {
    for (int i=0; i < 5; i++) {
      dataStream[i] = Serial.read();
      dsCounter++;
    }
    if (!checkSync()) {
      beginMode1();
    }
  }
  if (inSync) {
    if (Serial.available() >= dataStreamSize - dsCounter) {
      for (int i=dsCounter; i < dataStreamSize; i++) {
        dataStream[i] = Serial.read();
        dsCounter++;
      }
      byte a = calcCheckSum(2);
      if (a == 0) {
        for (int i=0; i < dataStreamSize; i++) {
          dataStreamp[i] = dataStream[i];
          dataStream[i] = 0;
        }
        mySerial.println("dataStream copied to dataStreamp");
        dsCounter = 0;
        displayDataStream();
      } else {
        inSync = false;
        mySerial.print("failed checksum: ");
        mySerial.println(a,HEX);
        displayDataStream2();
        beginMode1();        
      } //checksum
    } //Serial.available
    //displayDataStream();
  } //(inSync)
  //displayDataStream();
  
}

int checkSync(void) {
  if ((dataStream[1] == 0xF0 && dataStream[2] == 0x95) || (dataStream[2] == 0xF0 && dataStream[3] == 0x95)) {
    inSync = true;
    return 1;
  } else {
    mySerial.println("checkSync failed!");
    Serial.flush();
    inSync = false;
    mdelay = mdelay + 1;
    return 0;
  }
}

void beginMode1(void) {
  Serial.flush();
  dsCounter=0;
  mySerial.print("beginMode1 ");
  //for (int i=0; i < dataStreamSize; i++) {
  //  dataStream[i]=0;
  //}
  mySerial.println(mdelay);
  
  if (inSync == false) {
    Bit_Clear(PORTD,rxControl);
    while (Serial.read() != 0xF0) {}
    Bit_Set(PORTD,rxControl);
    delayMicroseconds(mdelay);
  }
  
  //Send commands to ECU for mode 1
  Bit_Set(PORTD,rxControl);
  Serial.print(0xF0,BYTE);
  Serial.print(0x57,BYTE);
  Serial.print(0x01,BYTE);
  Serial.print(0x00,BYTE);
  Serial.print(0xB8,BYTE);
  Bit_Clear(PORTD,rxControl);

}  

void displayDataStream(void) {
  for (int j=2; j < dataStreamSize; j++) {
      mySerial.print(dataStreamp[j],HEX);
  }
  mySerial.println();
  mySerial.print(mdelay);
  mySerial.print("\t");
  if (inSync) {
    mySerial.print("inSync\t");
  }
  mySerial.println(millis());
}

void displayDataStream2(void) {
  for (int j=2; j < dataStreamSize; j++) {
    mySerial.print(j);
    mySerial.print(":");
      mySerial.print(dataStream[j],HEX);
      mySerial.print(" ");
  }
  mySerial.println();
  mySerial.print(mdelay);
  mySerial.print("\t");
  if (inSync) {
    mySerial.print("inSync\t");
  }
  mySerial.println(millis());
}

byte calcCheckSum(int dss) {
	//Pass the dataStreamStart(dss) as argument.
	byte checkSum=0;
	for (int c=dss; c < dataStreamSize; c++) {
		checkSum += dataStream[c];
	}
	return checkSum;
}



* 8192 Baud Asynchronous Communications With a P6 Processor
General Description. 
The  8192  Baud data stream used by more advanced GM ECM's, (Type P4, P6 and P66) up to OBD II. The OBD II system is a CAN network, the  communications protocol defined by  statute.
The 8192 GM data format is asynchronous serial data the same as your PC is capable of processing, The 8192 baud rate is non-standard, but you can set the PC to a close enough so that the PC will accommodate the error.
The GM system is a master/slave system. Thus feature allows the vehicle to have multiple computers on line and avoids collisions between talker.. 
The user must initiate a short message to inform the receiving device that information is being requested. This message must conform to a specific format, describing the requested information as a block.
To Establish diagnostic communications between a P6 or P66  ECM or PCM and an outside computer do the following:
    * Mode 0 request, this clears any other communications such as the body computer, (dash board) , ABS brakes Etc.
    * Mode 1 request, This is a request for the diagnostic data stream, generally 60+ bytes of parametric data.
* 


    * MODE 0,  ALDL REQUEST:
* MESSAGE ID  = $F4 
* MESSAGE LENGTH = $56 
* MODE = $00 
* SUM CHECK		•	

* 
 
    * The ECM/PCM Will Reply:
* MESSAGE ID  = $F4 
* MESSAGE LENGTH = $56 
* MODE = $00 
* SUM CHECK		•	


    * MODE 1,  Data REQUEST:
* MESSAGE ID  = $F4 
* MESSAGE LENGTH = $57 
* MODE = $01 
* MESSAGE  = $00 
* SUM CHECKor
F45701B3
 
		•	

    * Note: 
1. The sum check is the complement of the message. When the incoming message is added it 
will always have a LSB of $FF
2. The message length is always $56 + the actual count of data bytes, in this case 1 byte.

* 
 
    * The ECM/PCM Will Reply:
* MESSAGE ID  = $F4 
* MESSAGE LENGTH = $95 
* MODE  = $01 
* data byte 1 
*                   x 
*                   x 
* data byte 63 
* SUM CHECK		•	


 
    * To get another update the user must send another Mode 1 Request.
* 



Possible data Reading Schemes: 
The commercial scan tools generally use a 6800 series Motorola processor to decode and display the data. These commercial systems also convert the output to a standard serial data  rate that is readable by a PC. The problem with all of this is it becomes a "kluge" of cables to set all of this up and the data format may not be what you want.
A more attractive method would be to eliminate the real time display part and have a small Microprocessor, (PIC Chip) translate the data and store it in a flash memory chip. I have found it very difficult to read and interpret data while driving, particularly if I'm using the data to do a tune up. I prefer looking at the results on my desk top and in some cases graphing them in order to calculate new values.
Other Communications Features: 
The serial communications has several modes Typically: 
 
    * Mode 2, Dump 60 bytes of memory starting with a user defined address.
    * Mode 3, dump of any 8 user defined address's
    * Mode 4, Controller mode, User may change AFR, Spark, TCC etc.
    * Mode 10, Clear diagnostic errors, (clear codes)
* 



An example of Mode 2: 
 
    * To Execute a Mode 2, Transmit the following message:
*  MESSAGE ID   = $F4 
* MESSAGE LENGTH = $58 
* MODE = $02 
* Address MSB 
* Address LSB 
* CHECKSUM		•	


 
    * The ECM/PCM Will Reply:
* MESSAGE ID  = $F4 
* MESSAGE LENGTH = $96 
* MODE = $02 
* data 1 
*     x 
*     x 
* data 64 
* SUM CHECK		•	

 . 



An example of Mode 3, 
 
    * To Execute a Mode 3, Transmit the following message:
*  MESSAGE ID   = $F4 
* MESSAGE LENGTH = $65 
* MODE = $03 
* Address 1 MSB 
* Address 1 LSB 
*       x 
*       x 
* Address 8, MSB 
* Address 8, LSB 
* CHECKSUM		•	


 
    * The ECM/PCM Will Reply:
* MESSAGE ID  = $F4 
* MESSAGE LENGTH = $63 
* MODE = $03 
* data 1 
*     x 
*     x 
* data 8 
* SUM CHECK		•	


An example of Mode 10,  "Clear Error Mode": 
 
    * To Execute a Mode 10, Transmit the following message:
*  MESSAGE ID   = $F4 
* MESSAGE LENGTH = $56 
* MODE = $0A 
* CHECKSUM		•	


  
 
    * The ECM/PCM Will Reply:
* MESSAGE ID  = $F4 
* MESSAGE LENGTH = $56 
* MODE = $0A 
* SUM CHECK		•