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.
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
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.
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?
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.
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.
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 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.