Arduino+LCD ELM327 OBD2 Reader V1.00

Arduino+LCD ELM327 OBD2 Reader V1.00

Postby MartinViljoen » Tue Oct 07, 2014 10:00 pm

Previously i created a thread on how to build a CAN-BUS Simulator http://techtinker.co.za/viewtopic.php?f=14&t=10
The reason I built it was so that i could generate real OBD2 PID data so it easier to develop an OBD2 Reader.

This is how I went about it.

I bought an ELM327 Scanner cable online , Cant remember from where but i bought it locally from a guy who sell auto stuff in Durban.
This particular ELM327 cable is very common and you get them in different flavors, USB, WIFI and Bluetooth, I selected the USB version because logic told me it was going to be easier to bypass the USB bridge chip, than it would be for Wifi or Bluetooth , But i think i'm wrong, anyway it doesn't matter this worked.

The very first thing i did was to remove the screws holding it together and hiding behind the sticker on it.

photo(2).JPG


I then after some trial and error found its serial pins and soldered wires to it which i'm connecting to an Arduino Nano's Serial pins TX/RX.

photo(4).JPG


I then built my project onto a bread board, figured out how to use the LCD and display values on it, also getting the serial communication to work took a while but i got it right.

photo(3).JPG


I also heavily relied on my OBD2 Simulator to get the data to read properly, the most pleasing part was when i connected the setup to my Jeep for the first time it actually worked!!!
photo 1(1).JPG

photo 2(1).JPG

photo 3(1).JPG


If you are interested, here is the Arduino Sketch for it.
You can add more OBD2 PIDs so that its able to read a whole lot more.
BTW, Apology for not giving a very detailed post and explaining more. I actually abandoned this project. I'm working on a new project the LCD used in this version is L2C and needs too many wires to the I/O pins of the LCD which creates a messy project also because its using so many wires i'm sacrificing too many I/O ports just for the LCD to my liking.
I recently received a nice I2C LCD Shield compatible with the Arduino UNO allowing me to keep all my I/O pins for future expansion.
Once i have it all working i will make another post of version 2 .


[EDIT] I have created a V2.00 of this which works much better, but hopefully the info in this thread gives you some extra perspective on the approach.
OBD2 Reader V2.00 - viewtopic.php?f=14&t=17

Code: Select all
/*
  LiquidCrystal Library - Hello World
 
 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.
 
 This sketch prints "Hello World!" to the LCD
 and shows the time.
 
  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * VDD 5V+
 * VSS = GND
 * V0 = Middle of potential meter
 * the other 2 pins of potensial meter goes to GND & 5V
 
 Backlight
 A = positive
 K = negative
 
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 
 
 */

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
//Declare Serial Read variables
int CmdCount=1;
byte inData;
char inChar;
String BuildINString="";
String DisplayString="";
long DisplayValue;
String SentMessage="";
int ByteCount=0;
long A;
int B;
int WorkingVal;
String WorkingString="";

//Declare Buttons
int RightButton=6;
int LeftButton=8;
int MenuID=0;

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.setCursor(0, 0);
  lcd.print("Welcome Martin      ");
  lcd.setCursor(0, 1);
  lcd.print("                    ");
  delay(1000);
  Retry:
  lcd.setCursor(0, 0);
  lcd.print("Connecting......    ");
  lcd.setCursor(0, 1);
  lcd.print("                    ");
  Serial.begin(38400);
 
  delay(500);
  //Send a test message to see if the ELM327 Chip is responding
  SentMessage = "ATI";
  Serial.println("ATI");delay(500);ReadData();
  if (BuildINString.substring(1,7)=="ELM327")
    {
      lcd.setCursor(0, 0);
      lcd.print("Welcome...            ");
      lcd.setCursor(0, 1);
      lcd.print("Connection OK         ");
      delay(1500);
    }
    else
    {
      lcd.setCursor(0, 0);
      lcd.print("Error             ");
      lcd.setCursor(0, 1);
      lcd.print("No Connection!         ");
      delay(1500);
      goto Retry;
    }
 
 
  pinMode(RightButton, INPUT);
  pinMode(LeftButton, INPUT);
  delay(1500);
}

void loop()
{
  digitalWrite(RightButton, HIGH);
  digitalWrite(LeftButton, HIGH);
  if (digitalRead(RightButton) != HIGH) {delay(300);MenuID++;}
  if (digitalRead(LeftButton) != HIGH) {delay(300);MenuID--;}
                                                                           
  if(MenuID<=0){MenuID=0;}
 
 
  if (MenuID==0){lcd.setCursor(0, 0);lcd.print("Coolant Temp    ");lcd.setCursor(0, 1);lcd.print(DisplayString);SentMessage = "01 05";Serial.println("01 05");delay(300);ReadData();}
  if (MenuID==1){lcd.setCursor(0, 0);lcd.print("IAT Temp        ");lcd.setCursor(0, 1);lcd.print(DisplayString);SentMessage = "01 0F";Serial.println("01 0F");delay(300);ReadData();}
  if (MenuID==2){lcd.setCursor(0, 0);lcd.print("Ambient Temp    ");lcd.setCursor(0, 1);lcd.print(DisplayString);SentMessage = "01 46";Serial.println("01 46");delay(300);ReadData();}
  if (MenuID==3){lcd.setCursor(0, 0);lcd.print("Throttle %      ");lcd.setCursor(0, 1);lcd.print(DisplayString);SentMessage = "01 11";Serial.println("01 11");delay(300);ReadData();}
  if (MenuID==4){lcd.setCursor(0, 0);lcd.print("CAT 1 Temp      ");lcd.setCursor(0, 1);lcd.print("Not Implemented ");}
  if (MenuID==5){lcd.setCursor(0, 0);lcd.print("CAT 2 Temp      ");lcd.setCursor(0, 1);lcd.print("Not Implemented ");}
  if (MenuID==6){lcd.setCursor(0, 0);lcd.print("CAT 3 Temp      ");lcd.setCursor(0, 1);lcd.print("Not Implemented ");}
  if (MenuID==7){lcd.setCursor(0, 0);lcd.print("CAT 4 Temp      ");lcd.setCursor(0, 1);lcd.print("Not Implemented ");}
  if (MenuID==8){lcd.setCursor(0, 0);lcd.print("RPM             ");lcd.setCursor(0, 1);lcd.print(DisplayString);SentMessage = "01 0C";Serial.println("01 0C");delay(300);ReadData();}
  if (MenuID==9){lcd.setCursor(0, 0);lcd.print("Vehicle Speed   ");lcd.setCursor(0, 1);lcd.print(DisplayString);SentMessage = "01 0D";Serial.println("01 0D");delay(300);ReadData();}
  if (MenuID==10){lcd.setCursor(0, 0);lcd.print("Air Flow Rate  ");lcd.setCursor(0, 1);lcd.print(DisplayString);SentMessage = "01 10";Serial.println("01 10");delay(300);ReadData();}
  if (MenuID==11){lcd.setCursor(0, 0);lcd.print("Barometric     ");lcd.setCursor(0, 1);lcd.print(DisplayString);SentMessage = "01 33";Serial.println("01 33");delay(300);ReadData();}
 
 
  if(MenuID>=11){MenuID=11;}
}

//Read Data and act accordingly
void ReadData()
{
  BuildINString=""; 
  while(Serial.available() > 0)
  {
    inData=0;
    inChar=0;
    inData = Serial.read();
    inChar=char(inData);
    BuildINString = BuildINString + inChar;
  }
 
  //if(BuildINString!=""){Serial.print(BuildINString);}
  BuildINString.replace(SentMessage,"");
  BuildINString.replace(">","");
  BuildINString.replace("OK","");
  BuildINString.replace("STOPPED","");
  BuildINString.replace("SEARCHING","");
  BuildINString.replace("NO DATA","");
  BuildINString.replace("?","");
  BuildINString.replace(",","");
  //Serial.print(BuildINString);
 
  //Check which OBD Command was sent and calculate VALUE
  //Calculate RPM I.E Returned bytes wil be 41 0C 1B E0
  if (SentMessage=="01 0C")
  {
    WorkingString = BuildINString.substring(7,9);
    A = strtol(WorkingString.c_str(),NULL,0);
    WorkingString = BuildINString.substring(11,13);
    B = strtol(WorkingString.c_str(),NULL,0);
   
   DisplayValue = ((A * 256)+B)/4;
   DisplayString = String(DisplayValue) + " rpm          ";
   lcd.setCursor(0, 1);
   lcd.print(DisplayString);
  }
  //Calculate Vehicle speed I.E Returned bytes wil be 41 0C 1B E0
  if (SentMessage=="01 0D")
  {
    WorkingString = BuildINString.substring(7,9);
    A = strtol(WorkingString.c_str(),NULL,0);

   DisplayValue = A;
   DisplayString = String(DisplayValue) + " km/h          ";
   lcd.setCursor(0, 1);
   lcd.print(DisplayString);
  }
 
  //Coolant Temp
  if (SentMessage=="01 05")
  {
    WorkingString = BuildINString.substring(7,9);
    A = strtol(WorkingString.c_str(),NULL,0);

   DisplayValue = A;
   DisplayString = String(DisplayValue) + " C            ";
   lcd.setCursor(0, 1);
   lcd.print(DisplayString);
  }
 
    //IAT Temp
  if (SentMessage=="01 0F")
  {
    WorkingString = BuildINString.substring(7,9);
    A = strtol(WorkingString.c_str(),NULL,0);

   DisplayValue = A;
   DisplayString = String(DisplayValue) + " C            ";
   lcd.setCursor(0, 1);
   lcd.print(DisplayString);
  }
 
  //Air flow Rate
  if (SentMessage=="01 10")
  {
    WorkingString = BuildINString.substring(7,9);
    A = strtol(WorkingString.c_str(),NULL,0);
    WorkingString = BuildINString.substring(11,13);
    B = strtol(WorkingString.c_str(),NULL,0);
   
   DisplayValue = ((A * 256)+B)/100;
   DisplayString = String(DisplayValue) + " g/s          ";
   lcd.setCursor(0, 1);
   lcd.print(DisplayString);
  }
 
  //Ambient Temp
  if (SentMessage=="01 46")
  {
    WorkingString = BuildINString.substring(7,9);
    A = strtol(WorkingString.c_str(),NULL,0);

   DisplayValue = A;
   DisplayString = String(DisplayValue) + " C            ";
   lcd.setCursor(0, 1);
   lcd.print(DisplayString);
  }
 
  //Throttle position
  if (SentMessage=="01 11")
  {
    WorkingString = BuildINString.substring(7,9);
    A = strtol(WorkingString.c_str(),NULL,0);

   DisplayValue = A;
   DisplayString = String(DisplayValue) + " %            ";
   lcd.setCursor(0, 1);
   lcd.print(DisplayString);
  }
  //Barometric pressure
  if (SentMessage=="01 33")
  {
    WorkingString = BuildINString.substring(7,9);
    A = strtol(WorkingString.c_str(),NULL,0);

   DisplayValue = A;
   DisplayString = String(DisplayValue) + " kpa            ";
   lcd.setCursor(0, 1);
   lcd.print(DisplayString);
  } 
}

You do not have the required permissions to view the files attached to this post.
Image
User avatar
MartinViljoen
 
Posts: 109
Joined: Mon Oct 06, 2014 5:23 pm
Location: Centurion South Africa

Return to OBD2 & CAN-BUS Projects

Who is online

Users browsing this forum: No registered users and 2 guests

cron