OBDII to UART Issues

Hi everyone.

I am using an OBDII to UART device from Sparkfun: http://www.sparkfun.com/products/9555

My wiring is the same as this but I am not using a serial LCD. I am wiring it using the LiquidCrystal library.

My car is a Golf Mk4, year 1999.

The issue is I cannot get live data such as speed or RPM from the ECU. With everything connected to the OBDII port of the car and the Arduino powered with my laptop and the car switched on, I get 0 for speed no matter if I drive the car or not and always 832 for the RPM :~

Here is the code I am using:-

#include <LiquidCrystal.h>

LiquidCrystal lcd(26,28,30,32,34,36);

//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(){

  lcd.begin(4, 20);    

  Serial.begin(9600);
  
  //Clear the old data from the LCD.
  lcd.clear();
  
  //Put the speed header on the first row.
  lcd.setCursor(0,0);
  lcd.print("Speed: ");

  //Put the RPM header on the second row.
  lcd.setCursor(0,1);
  lcd.print("RPM: ");

  //Wait for a little while before sending the reset command to the OBD-II-UART
  delay(1500);

  //Reset the OBD-II-UART
  Serial.println("ATZ");

  //Wait for a bit before starting to send commands after the reset.  
  delay(2000);
  
  //Delete any data that may be in the serial port before we begin.
  Serial.flush();
}


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

  //Query the OBD-II-UART for the Vehicle Speed
  Serial.println("010D");
  //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();
  getResponse();
  //Convert the string data to an integer
  vehicleSpeed = strtol(&rxData[6],0,16);
  //Print the speed data to the lcd
  lcd.setCursor(10,0);
  lcd.print(vehicleSpeed);
  
  lcd.setCursor(16,0);
  lcd.print("km/h");
  delay(100);
  
  //Delete any data that may be left over in the serial port.
  Serial.flush();

  //Query the OBD-II-UART for the Vehicle rpm
  Serial.println("010C");
  //Get the response from the OBD-II-UART board
  getResponse();
  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 the lcd
  lcd.setCursor(10,1);
  lcd.print(vehicleRPM); 

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



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(Serial.available() > 0){
      //Start by checking if we've received the end of message character ('\r').
      if(Serial.peek() == '\r'){
        //Clear the Serial buffer
        inChar=Serial.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 = Serial.read();
        //Add the new character to the string, and increment the index variable.
        rxData[rxIndex++]=inChar;
      }
    }
  }
}

Any ideas at all? Anyone has had any experience with this at all?

I'm not proficient with OBD-II, but if the data returned is two bytes, why are you retrieving rxData[6] and rxData[9]? Shouldn't that be in rxData[0] and rxData[1]? The echo of your input is the one terminated by the CR? That would reset the rxData index.

And the code says nothing of a CR/LF returned after the two bytes from the ECU.

I've used the code form this page and modified it, since I'm not using a serial LCD.

http://www.sparkfun.com/tutorials/294

It's been a while but i made an lcd terminal for my Nissan, I don't know anything about the sparfun interface but a few pointers would be that the ignition needs to be ON, not at accessory position but on either with car running or not.

As far as the nissan went the ECU needed to be initaialised with by sending 0x0F, 0xFF, 0xFE to talk to the engine, Bytes are inverted and at RS232 levels, then I needed to send a read command say 0x0F(accept command), 0x0A(Battery Voltage), 0x02(send 2 bytes), I know the values are wrong but this is from memory, I can dig up the command refrence if you need

You can also say 0x0f(accept command), 0x0A(Battery voltage), 0x07(Speed), 0x08(RPM), 0x06(send 6 bytes).

I would guess that the sparkfun interface will do most of this for you, or whats the point in having it, My terminal was made using PIC18F877 and an homemade Nissan consult interface but the procedures are similar

I guess the first thing to do is get the sparkfun interface connected to your laptop and talk to the car with a terminal program then when you know the car is responding transfer the codes to arduino

BTW i just looked at the price of the sparkfun OBD-II UART, are they serious? I hate profiteering but if people are willing to pay that much good luck to them

Hope you get it working anyway

PID 0100 is not the vehicles speed, it's PID supported. PID 010C is the RPM but first of all, you haven't initialised your chip and you don't check, if your car support the PID. With PID 0100 you get 4 bytes which are a bit field having a 1 for PID supported or a 0 for PID not supported. You should read out that value. My Renault Trafic 2005 does only support error code readouts and nothing else (unfortunately) but my Honda Civic 2006 has almost all values available.

Take a look at the OBDuino project, it does the correct initialisation (for most OBD types) and shows you how to read the values.

Thank you all of you for your prompt and useful replies.

I have been trying to use a Terminal Emulator program to see what packets I get back from my car without any success.

I use the "Tera Term" on Windows 7, I successfully connect to my FTDI Basic, but when the emulator window appears, I cannot type anything.

I know this is an issue altogether, but would help to see what others have experienced or what terminal emulator they use.

Thanks.

I use a standard serial terminal (works without a problem), this is not depending on the PC software you use. Have you configured the correct baud rate? Did you cross the RX/TX lines?

I've also used the Arduino's serial monitor. When I type something and press enter, I don't get any packets back.

I have crossed the RX and TX lines also.

Ok,

With the Arduino's terimnal, baud rate set at 9600 and with "carriage return" set.

When I put ATZ I get this back:

ATZ

ELM327 v1.3a

When I put ATRV I get this back:

ATRV
12.8V

When I put ATSP0 I get this back:

ATSP0
OK

When I put 0100, however, I get this back:

0100
SEARCHING...
UNABLE TO CONNECT

Try the following

ATWS

ATDPN

0100

This resets the device and ask the used protocol. Keep in mind that you have your car's motor running or at least the key in the on position to enable the ECU, else you'll get always the mentioned error.

Thanks,

I will try it tomorrow.

I have always either had the key turned to ON or had the car running when testing everything :slight_smile:

Thanks.

When I do the above test I get:

0100
CAN ERROR

=(

And what's the output of the ATDPN command (I hope you got an "OK" to the ATWS)?

This is what I get:

ATWS

ELM327 v1.3a

ATDPN
A

0100
CAN ERROR

After the "A" (stands for automatic) there should be a digit from 1 to 7 showing which protocol is to be used with the ECU. Seems your car does not support OBD-II and is not compatible with ELM327 and clones.
Even my Renault Trafic does output stuff here although I don't get any interesting information out except the error codes (which fortunately it has none).

Do you have the possibility to check with a newer car (2005-)? Just to check if it's your car or your adapter.

Hi,

I am sure my car has OBDII, all the Golf MK4's have them.

I am can try tomorrow with my brother's 2004 BMW 3 series and his Jaguar XF 2008.

Thanks.

Just to check that too: How did you made the connection from the Sparkfun board to the OBD-II? Did you buy the cable or is it self-made? If self-made, what connections did you wire through?

I'm asking this because the different protocols supported by the Sparkfun board uses different pins on the OBD-II connector. If you missed one or if something other in the cabling is wrong, you probably get what you get too.

I bought an OBDII to DB9 cable from eBay. I have checked the pins and are exactly like this one:

However on the OBD connector, pin 5 is connected to pin 4. Pin 5 on the OBDII connector is not connected to pin 1 of the DB9 connector.

I think this goes OK. Do you know which of the pins are connected in your car? Often you can see it by looking at the connector and you don't have to measure. This way you might get an idea which protocol is used.

I don't know but can have a look.