Show Posts
Pages: [1]
1  Using Arduino / Networking, Protocols, and Devices / Re: OBD-II help (J1850 PWM) on: February 05, 2013, 06:31:26 am
Changed the init loop to this:

Code:
  do
  {
    Serial1.print("0100\r");
    delay(1000);
    getResponse();    //This is only called once since the echo has been turned off using ATE0\r
    while(gotResponse == false){}
    Serial.print("0100 Response:  ");
    Serial.print(rxData[0]);Serial.print(rxData[1]);Serial.print(rxData[3]);Serial.print(rxData[4]);Serial.print(rxData[6]);Serial.print(rxData[7]); Serial.print(rxData[9]);Serial.print(rxData[10]);
    Serial.println("");
  }
  while(ELM_CHECK_RESPONSE("0100", rxData)!=0);

And added gotResponse = false here:

Code:
else{
        //Get the new character from the Serial port.
        inChar = Serial1.read();
        //Add the new character to the string, and increment the index variable.
        rxData[rxIndex++]=inChar;
        gotResponse = false;
      }

Still no difference, there must be something else going on?
2  Using Arduino / Networking, Protocols, and Devices / Re: OBD-II help (J1850 PWM) on: February 04, 2013, 07:28:26 am
OK, i've changed the code a bit, but it doesn't seem to make any difference, what am i missing?

Code:
//This is a character buffer that will store the data from the serial port
char rxData[20];
char rxIndex=0;

//Variables to hold the speed and RPM data.
int vehicleSpeed=0;
int vehicleRPM=0;

boolean gotResponse = false;

void setup(){

  Serial1.begin(9600);
  Serial.begin(9600);   //This is for the serial debug

  //Wait for a little while before sending the reset command to the OBD-II-UART
  delay(1500);
  //Reset the OBD-II-UART
  Serial1.print("ATWS\r");
  //Wait for a bit before starting to send commands after the reset.
  delay(1000);
 
  // turn echo off
  Serial1.print("ATE0\r");
 
  // send 01 00 until we are connected
  do
  {
    Serial1.print("0100\r");
    delay(1000);
    getResponse();    //This is only called once since the echo has been turned off using ATE0\r
    Serial.print("0100 Response:  ");
    Serial.print(rxData[0]);Serial.print(rxData[1]);Serial.print(rxData[3]);Serial.print(rxData[4]);Serial.print(rxData[6]);Serial.print(rxData[7]); Serial.print(rxData[9]);Serial.print(rxData[10]);
    Serial.println("");
  }
  while(ELM_CHECK_RESPONSE("0100", rxData)!=0);
 
  gotResponse = false;
   
  Serial1.print("ATDPN\r");  //Shows the protocol
  getResponse();
  Serial.print("Protocol: ");Serial.print(rxData[0]);Serial.print(rxData[1]);Serial.println("");
  // str[0] should be 'A' for automatic
  // set header to talk directly to ECU#1
  if(rxData[1]=='1')  // PWM
    Serial1.print("ATSHE410F1\r");
  else if(rxData[1]=='2')  // VPW
    Serial1.print("ATSHA810F1\r");
  else if(rxData[1]=='3')  // ISO 9141
    Serial1.print("ATSH6810F1\r");
  else if(rxData[1]=='6')  // CAN 11 bits
    Serial1.print("ATSH7E0\r");
  else if(rxData[1]=='7')  // CAN 29 bits
    Serial1.print("ATSHDA10F1\r");
}

void printSpeed(){
  //Convert the string data to an integer
  vehicleSpeed = strtol(&rxData[6],0,16);
 
  Serial.print("SPEED: ");
  Serial.print(vehicleSpeed);
  Serial.print(" km/h");
  Serial.println(" ");

  gotResponse = false;
}

void printRpm(){
  //Convert the string data to an integer
  //NOTE: RPM data is two bytes long, and delivered in 1/4 RPM from the OBD-II-UART
  vehicleRPM = ((strtol(&rxData[6],0,16)*256)+strtol(&rxData[9],0,16))/4;

  //Print the rpm data to debug serial window
  Serial.print("RPM: ");
  Serial.print(vehicleRPM);
  Serial.println(" ");
 
  gotResponse = false;
}

void loop(){
  //Query the OBD-II-UART for the Vehicle Speed
  Serial1.print("010D\r");   
  delay(20);
  //Get the response from the OBD-II-UART board. We get two responses
  //because the OBD-II-UART echoes the command that is sent.
  //We want the data in the second response.
  getResponse();

  while(gotResponse == false){
    // Loop until getResponse() is done
  }
  printSpeed();

  //Print the speed data to debug serial window
 
  delay(20);
 
  //Query the OBD-II-UART for the Vehicle rpm
  Serial1.println("010C\r");
  delay(20);
  //Get the response from the OBD-II-UART board
  getResponse();
 
  while(gotResponse == false){
    // Loop until getResponse() is done
  }
  printRpm();
 
  //Give the OBD bus a rest
  delay(5000);
}

byte ELM_CHECK_RESPONSE(const char *cmd, char *str)
{
  // cmd is something like "010D"
  // str should be "41 0D blabla"
  if(cmd[0]+4 != rxData[0]
    || cmd[1]!= rxData[1]
    || cmd[2]!= rxData[3]
    || cmd[3]!= rxData[4])
    return 1;

  return 0;  // no error
}

void getResponse(void){
  char inChar=0;
  //Keep reading characters until we get a carriage return
  while(inChar != '\r'){
    //If a character comes in on the serial port, we need to act on it.
    if(Serial1.available() > 0){
      //Start by checking if we've received the end of message character ('\r').
      if(Serial1.peek() == '\r'){
        //Clear the Serial buffer
        inChar=Serial1.read();
        //Put the end of string character on our data string
        rxData[rxIndex]='\0';
        //Reset the buffer index so that the next character goes back at the beginning of the string.
        rxIndex=0;
        gotResponse = true;
      }
      //If we didn't get the end of message character, just add the new character to the string.
      else{
        //Get the new character from the Serial port.
        inChar = Serial1.read();
        //Add the new character to the string, and increment the index variable.
        rxData[rxIndex++]=inChar;
      }
    }
  }
}
3  Using Arduino / Networking, Protocols, and Devices / Re: OBD-II help (J1850 PWM) on: February 02, 2013, 11:21:10 am
OK, i've tried to remove all Serial.flush() from the code, but that doesn't seem to do anything.

Here is some output from the serial monitor if that helps anyone:

Code:
0100 Response:  ATS
0100 Response:  TS
0100 Response:  TS
0100 Response: EL32 v.3
0100 Response:  L32 v.3
0100 Response: >AE0 v.3
0100 Response: OKE0 v.3
0100 Response:  KEO v.3
0100 Response: >4 0 B 3
0100 Response:  4 0 B 3
0100 Response: >4 0 B 3
0100 Response:  4 0 B 3
0100 Response: 44 0 B 3
0100 Response:  4 0 B 3
0100 Response: >4 0 B 3
0100 Response:  4 0 B 3
0100 Response: >4 0 B 3
0100 Response:  4 0 B 3
0100 Response: >4 0 B 3
0100 Response:  4 0 B 3
0100 Response: 4100BE3E
Protocol:  1
SPEED: 190 km/h
RPM: 12175
SPEED: 190 km/h
RPM: 12175
SPEED: 190 km/h
RPM: 12175
SPEED: 190 km/h
RPM: 12175
SPEED: 13 km/h
RPM: 832
SPEED: 12 km/h
RPM: 799
SPEED: 15 km/h
RPM: 1439
SPEED: 0 km/h
RPM: 0
SPEED: 12 km/h
RPM: 832
SPEED: 13 km/h
RPM: 799
SPEED: 12 km/h
RPM: 768
SPEED: 12 km/h
RPM: 832
SPEED: 13 km/h
RPM: 832
SPEED: 13 km/h
RPM: 832
SPEED: -14465 km/h
RPM: 1311
SPEED: 13 km/h
RPM: 832
SPEED: 13 km/h
RPM: 67
SPEED: 1 km/h
RPM: 768
SPEED: 1 km/h
RPM: 960
SPEED: 13 km/h
RPM: 832
SPEED: 13 km/h
RPM: 832
SPEED: 12 km/h
RPM: 832
SPEED: 13 km/h
RPM: 1311
SPEED: 13 km/h
RPM: 832
SPEED: 13 km/h
RPM: 799
SPEED: 13 km/h
RPM: 863
SPEED: 15 km/h
RPM: 67
SPEED: 13 km/h
RPM: 835
SPEED: -10369 km/h
RPM: -8225
SPEED: 12 km/h
RPM: 960
SPEED: 15 km/h
RPM: 8159
SPEED: 3199 km/h
RPM: 768
SPEED: 13 km/h
RPM: 832
SPEED: 127 km/h
RPM: 832
SPEED: 13 km/h
RPM: 768
SPEED: 215 km/h
RPM: 13760
SPEED: 12 km/h
RPM: 67
SPEED: 13 km/h
RPM: 832
SPEED: 13 km/h
RPM: 832
SPEED: 12 km/h
RPM: 67
SPEED: 1 km/h
RPM: 832
SPEED: 13 km/h
RPM: 0
SPEED: 0 km/h
RPM: 768
SPEED: 127 km/h
RPM: 67
SPEED: 13 km/h
RPM: 832
SPEED: 12 km/h
RPM: 832
SPEED: 13 km/h
RPM: 832
SPEED: 13 km/h
RPM: 768
SPEED: 12 km/h
RPM: -8225
SPEED: 1 km/h
RPM: 835
SPEED: 13 km/h
RPM: 960
SPEED: 13 km/h
RPM: 832
SPEED: 13 km/h
RPM: 832
SPEED: -14465 km/h
RPM: 960
SPEED: 13 km/h
RPM: 832
SPEED: 12 km/h
RPM: 832
SPEED: 13 km/h
RPM: 832
SPEED: 13 km/h
RPM: 768
SPEED: 12 km/h
RPM: -8225
SPEED: 10 km/h
RPM: 640
SPEED: 0 km/h
RPM: 0
SPEED: 0 km/h
RPM: 0
SPEED: 0 km/h
RPM: 0
SPEED: 0 km/h
RPM: 0
SPEED: 0 km/h
RPM: 0
SPEED: 0 km/h
RPM: 0
SPEED: 0 km/h
RPM: 0
SPEED: 0 km/h
RPM: 0
SPEED: 0 km/h
RPM: 0
SPEED: 218 km/h
RPM: 13954
4  Using Arduino / Networking, Protocols, and Devices / Re: OBD-II help (J1850 PWM) on: February 01, 2013, 04:31:14 am
1.0.1 and i've tried both on an UNO and a Mega 2560.
5  Using Arduino / Networking, Protocols, and Devices / OBD-II help (J1850 PWM) on: January 31, 2013, 04:19:32 pm
Hi,

I'm trying to make an OBD2 interface using the OBD-II uart from Sparkfun, but i'm having a bit of trouble getting the right data. I'm using the following code which i found in this thread http://arduino.cc/forum/index.php?PHPSESSID=3547d5fc432e994f1fb017ce82ddaa30&topic=111827.0

Code:
//This is a character buffer that will store the data from the serial port
char rxData[20];
char rxIndex=0;

//Variables to hold the speed and RPM data.
int vehicleSpeed=0;
int vehicleRPM=0;

void setup(){

  Serial1.begin(9600);
  Serial.begin(9600);   //This is for the serial debug

  //Wait for a little while before sending the reset command to the OBD-II-UART
  delay(1500);
  //Reset the OBD-II-UART
  Serial1.print("ATWS\r");
  //Wait for a bit before starting to send commands after the reset.
  delay(1000);
 
  // turn echo off
  Serial1.print("ATE0\r");
 
  // send 01 00 until we are connected
  do
  {
    Serial1.print("0100\r");
    delay(1000);
    getResponse();    //This is only called once since the schoecho has been turned off using ATE0\r
    Serial.print("0100 Response:  ");
    Serial.print(rxData[0]);Serial.print(rxData[1]);Serial.print(rxData[3]);Serial.print(rxData[4]);Serial.print(rxData[6]);Serial.print(rxData[7]); Serial.print(rxData[9]);Serial.print(rxData[10]);
    Serial.println("");
  }
  while(ELM_CHECK_RESPONSE("0100", rxData)!=0);
   
  Serial1.flush();
   
  Serial1.print("ATDPN\r");  //Shows the protocol
  getResponse();
  Serial.print("Protocol: ");Serial.print(rxData[0]);Serial.print(rxData[1]);Serial.println("");
  // str[0] should be 'A' for automatic
  // set header to talk directly to ECU#1
  if(rxData[1]=='1')  // PWM
    Serial1.print("ATSHE410F1\r");
  else if(rxData[1]=='2')  // VPW
    Serial1.print("ATSHA810F1\r");
  else if(rxData[1]=='3')  // ISO 9141
    Serial1.print("ATSH6810F1\r");
  else if(rxData[1]=='6')  // CAN 11 bits
    Serial1.print("ATSH7E0\r");
  else if(rxData[1]=='7')  // CAN 29 bits
    Serial1.print("ATSHDA10F1\r");
 
  //Delete any data that may be in the serial port before we begin.
  Serial1.flush();

}


void loop(){
  //Delete any data that may be in the serial port before we begin. 
  Serial1.flush();

  Serial1.print("010D\r");    //Query the OBD-II-UART for the Vehicle Speed

  //Get the response from the OBD-II-UART board. We get two responses
  //because the OBD-II-UART echoes the command that is sent.
  //We want the data in the second response.
  getResponse();

  //Convert the string data to an integer
  vehicleSpeed = strtol(&rxData[6],0,16);

  //Print the speed data to debug serial window
  Serial.print("SPEED: ");
  Serial.print(vehicleSpeed);
  Serial.print(" km/h");
  Serial.println(" ");
 
  delay(20);
 
  //Delete any data that may be left over in the serial port.
  Serial1.flush();

  //Query the OBD-II-UART for the Vehicle rpm
  Serial1.println("010C\r");
  //Get the response from the OBD-II-UART board
  getResponse();

  //Convert the string data to an integer
  //NOTE: RPM data is two bytes long, and delivered in 1/4 RPM from the OBD-II-UART
  vehicleRPM = ((strtol(&rxData[6],0,16)*256)+strtol(&rxData[9],0,16))/4;

  //Print the rpm data to debug serial window
  Serial.print("RPM: ");
  Serial.print(vehicleRPM);
  Serial.println(" ");

  //Give the OBD bus a rest
  delay(50);
 
}


byte ELM_CHECK_RESPONSE(const char *cmd, char *str)
{
  // cmd is something like "010D"
  // str should be "41 0D blabla"
  if(cmd[0]+4 != rxData[0]
    || cmd[1]!= rxData[1]
    || cmd[2]!= rxData[3]
    || cmd[3]!= rxData[4])
    return 1;

  return 0;  // no error
}


void getResponse(void){
  char inChar=0;
  //Keep reading characters until we get a carriage return
  while(inChar != '\r'){
    //If a character comes in on the serial port, we need to act on it.
    if(Serial1.available() > 0){
      //Start by checking if we've received the end of message character ('\r').
      if(Serial1.peek() == '\r'){
        //Clear the Serial buffer
        inChar=Serial1.read();
        //Put the end of string character on our data string
        rxData[rxIndex]='\0';
        //Reset the buffer index so that the next character goes back at the beginning of the string.
        rxIndex=0;
      }
      //If we didn't get the end of message character, just add the new character to the string.
      else{
        //Get the new character from the Serial port.
        inChar = Serial1.read();
        //Add the new character to the string, and increment the index variable.
        rxData[rxIndex++]=inChar;
      }
    }
  }
}

My car ('02 Ford Focus) uses the J1850-PWM protocol and the code seems to initialize fine and returns the right protocol, but when i ask for live data, i just get some random numbers. Speed jumps between 0 and 13 km/h and rpm can go from 0 to 19 to 832 and sometimes even displays higher or negtive values, bot with and without the engine running.

I have spent a lot of time googling the problem and looking through the elm327 datasheet, but so far i haven't found anything that works.

I have also tried loading the OBDuino code, but that only seems to be working with the ISO-9141 protocol.

If anyone has any code or just pointers on how to get this to work with the J1850-PWM protocol i would be very happy to hear from you, as i'm starting to get a bit frustrated.

/Jakob
Pages: [1]