- Fri May 11, 2012 3:09 pm
#144336
Here's a more thorough piece of diagnostic code. It should wait longer btw display changes and should show the number of characters received by the Arduino. I still want to see the OBD controller send back the correct responses to the ATZ and ATSP0 commands. It appears we're seeing them echoed which, if true, indicates good comm back and forth btw the OBDII and Arduino. That's to say the voltage levels are correct and the Tx/Rx lines aren't swapped. Then we have to prove the two are actually talking to each other and then prove the OBDII is talking to the car.
One step at a time.
One step at a time.
Code: Select all
#include <LiquidCrystal.h>
#define LCD_RS 4
#define LCD_ENABLE 5
#define LCD_DATA1 7
#define LCD_DATA2 8
#define LCD_DATA3 12
#define LCD_DATA4 13
LiquidCrystal lcd(LCD_RS, LCD_ENABLE, LCD_DATA1, LCD_DATA2, LCD_DATA3, LCD_DATA4);
#define ContrastPin 6
#define BrightnessPin 9
//This is a character buffer that will store the data from the serial port
char rxData[20];
byte rxIndex=0;
//Variables to hold the speed and RPM data.
int vehicleSpeed=0;
int vehicleRPM=0;
void setup(){
//Both the Serial LCD and the OBD-II-UART use 9600 bps.
Serial.begin(9600);
//Delete any data that may be in the serial port before we begin.
delay (100);
Serial.flush();
//Init and clear the old data from the LCD.
lcd.begin(16, 2);
lcd.clear();
// Put a Hello World message on the LCD.
lcd.print(" Initializing ");
delay (1000);
lcd.setCursor(0, 1);
lcd.print(" Reseting OBDII ");
delay (2000); // allow user time to look towards OBDII LEDs
//Reset the OBD-II-UART
Serial.println("ATZ");
// Show both responses - if any
getResponse(); // get first response
// Show what came back.
lcd.clear();
// Now show what are we doing.
lcd.print("Reset response");
lcd.setCursor(0, 1);
if(rxIndex)
{
lcd.print("rxIndex1 = ");
lcd.print(rxIndex);
delay (2000);
lcd.setCursor(0, 1);
lcd.print(" "); // erase prior response
lcd.print(rxData); // should be cmd echo ??
// lcd.print(" Got a message");
}
else
{
lcd.print("no response #1");
}
delay (2000); // wait just long enough for user to see 1st response
// Now get 2nd real response ??
getResponse();
lcd.setCursor(0, 1);
lcd.print(" "); // erase prior response
if(rxIndex)
{
lcd.print("rxIndex2 = ");
lcd.print(rxIndex);
delay (2000);
lcd.setCursor(0, 1);
lcd.print(" "); // erase prior response
lcd.print(rxData); // should be ELM ...
// lcd.print(" Got a message");
}
else
{
lcd.print("no response #2");
}
delay (5000); // wait long enough for user to see responses
//Now command the OBDII to auto-detect the proper protocol as done in example 1.
Serial.println("ATSP0");
// Again show both responses - if any
getResponse();
// Show what came back.
lcd.clear();
lcd.print("Auto protocol");
lcd.setCursor(0, 1);
if(rxIndex)
{
lcd.print("rxIndex3 = ");
lcd.print(rxIndex);
delay (2000);
lcd.setCursor(0, 1);
lcd.print(" "); // erase prior response
lcd.print(rxData); // should be cmd echo ?
// lcd.print(" Got a message");
}
else
{
lcd.print("no response #3");
}
delay (2000); // wait just long enough for user to see 1st response
// Now get 2nd real response ??
getResponse();
lcd.setCursor(0, 1);
lcd.print(" "); // erase prior response
if(rxIndex)
{
lcd.print("rxIndex4 = ");
lcd.print(rxIndex);
delay (2000);
lcd.setCursor(0, 1);
lcd.print(" "); // erase prior response
lcd.print(rxData); // should say OK
// lcd.print(" Got a message");
}
else
{
lcd.print("no response #4");
}
delay (5000); // wait long enough for user to see responses
//Hoping the above worked, now put the speed header on the first row.
lcd.clear();
lcd.print("Speed: ");
//Put the RPM header on the second row.
lcd.setCursor(0, 1);
lcd.print("RPM: ");
//Wait for a bit before starting to send commands after the reset.
delay(2000);
}
void loop(){
//Delete any data that may be in the serial port before we begin.
Serial.flush();
//Set the cursor in the position where we want the speed data.
lcd.setCursor(7, 0);
//Write over the old speed data, and then reset the cursor position.
lcd.print(" "); // need 8 spaces for speed data per old code
lcd.setCursor(7, 0);
//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
if(rxIndex) // test to see if anything was received from OBDII
{
vehicleSpeed = strtol(&rxData[6],0,16);
//Print the speed data to the lcd
lcd.print(vehicleSpeed);
}
else
{
lcd.print("No data");
}
delay(100);
//Delete any data that may be left over in the serial port.
Serial.flush();
//Move the serial cursor to the position where we want the RPM data.
lcd.setCursor(5, 1);
//Clear the old RPM data, and then move the cursor position back.
lcd.print(" "); // need 10 spaces for RPM data ?
lcd.setCursor(5, 1);
//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
if(rxIndex) // test to see if anything was received from OBDII
{
vehicleRPM = ((strtol(&rxData[6],0,16)*256)+strtol(&rxData[9],0,16))/4;
//Print the rpm data to the lcd
lcd.print(vehicleRPM);
}
else
{
lcd.print("No data");
}
//Give the OBD bus a rest
delay(300);
}
//The getResponse function collects incoming data from the UART into the rxData buffer
// and only exits when a carriage return character is seen. Once the carriage return
// string is detected, the rxData buffer is null terminated (so we can treat it as a string)
// and the rxData index is reset to 0 so that the next string can be copied.
void getResponse(void){
char inChar=0;
rxIndex=0;
unsigned long TimeIn = millis();
//Keep reading characters until we get a carriage return or time out
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;
}
}
if (millis() - TimeIn > 1000) // wait 1 sec for some kind of response
{
break;
}
}
}