Skip to content
Jason Joyner
Jason Joyner

Manufacturing Engineer

  • Home
  • Resume
  • Contact
Jason Joyner

Manufacturing Engineer

February 11, 2022February 11, 2022

OBDII Information Display

Introduction

As an automotive enthusiast with an interest in hobbyist electronics, I’ve been wanting to learn more about how the modern car works. The natural beginner project in this area is a simple OBDII display that can show data from the car’s ECU, such as the vehicle speed in MPH or engine speed in RPM.

Set Up

Hardware Used

  • Arduino Uno
  • CAN Bus Shield from SeedStudio
  • OBDII to DB9 Extension Cable
  • 1.3″ 128×64 OLED I2C Display

Software Libraries

  • arduino-CAN
  • arduino-OBD2

Wiring

The set up of this project is very simple. The CAN bus shield sits on top of the Arduino Uno. This shield provides connectivity to the vehicle, via the OBDII port in the driver’s footwell.

The OLED display is then connected to the Arduino Uno as a typical I2C device.

  • VCC to VCC
  • GND to GND
  • SCL to Analog Pin 4
  • SDA to Analog Pin 5

Programming

The first step is to declare the libraries needed. For connectivity to the vehicle, the CAN.h and OBD2.h libraries written by Sandeep Mistry will be used. For outputting text to the OLED display, the Adafruit_GFX.h and Adafruit_SSD1306.h libraries will be used.

#include <CAN.h>                                      //CAN Bus Communication
#include <OBD2.h>                                     //For vehicle data from ECU
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Next, we will declare the constants for the PIDs we plan to request from the vehicle. A PID is an on-board diagnostic Parameter ID, and is a code that is used to request data from the vehicle. These are defined by SAE standard J1979. These constants are defined in an enum within the OBD2.h library.

// array of PID's to print values of
const int PIDS[] = {
  ENGINE_RPM,
  VEHICLE_SPEED,
};

We then define our CAN network speed, and set up the display. Followed by variables to store the values received from the vehicle.

//CAN Network Speed Constant
#define CAN_500KBPS                             16

// Reset pin not used but needed for library
#define OLED_RESET                              4
Adafruit_SSD1306 display(OLED_RESET);
#define SCREEN_REFRESH_DELAY                    1000

//Global variables
int    current_Displayed_Speed_MPH = 0;            //Current speed displayed on gauge
int    current_Displayed_RPM = 0;                  //Current RPM reading displayed on gauge

Next we can start writing the functions. The first is the setup function. This will initialize the OLED display, write a header line to the screen, and attempt to connect to the vehicle via the CAN bus.

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  // initialize OLED with I2C addr 0x3C
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

  while (!Serial);
  // Clear the display
  display.clearDisplay();

  // Set up to write to display
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0,0);

  display.println(F("OBD2 Key Stats"));
  display.display();
  delay(SCREEN_REFRESH_DELAY);

  // Attempt to connect to vehicle CAN bus
  while (true) {
    display.clearDisplay();
    display.print(F("Attempting to connect to OBD2 CAN bus ... "));
    display.display();
    delay(SCREEN_REFRESH_DELAY);

    if (!OBD2.begin()) {
      display.clearDisplay();
      display.println(F("failed!"));
      display.display();

      delay(SCREEN_REFRESH_DELAY);
    } else {
      display.clearDisplay();
      display.println(F("success"));
      display.display();
      break;
    }
  }

  Serial.println();

} //end function setup

In our loop function, the Arduino requests the current speed of the vehicle, converts that to miles per hour from the kilometers per hour the vehicle responds with, and requests the engine speed in RPM. These values are then stored in the variables we already created.

void loop() {
            
   //Update RPM value
  float current_RPM = OBD2.pidRead(ENGINE_RPM);                 //Request RPM from ECU
  current_Displayed_RPM = current_RPM;

  //Update speed value
  float current_Speed = OBD2.pidRead(VEHICLE_SPEED);            //Request speed from ECU, returns speed in km/h
  current_Speed = current_Speed / 1.609344;                     //Convert to mph
  current_Displayed_Speed_MPH = current_Speed;

  //Update display
  delay(SCREEN_REFRESH_DELAY);
  UpdateDisplay();
  display.display();

} //end function loop

The loop function then calls the UpdateDisplay() function to write these values to the screen.

void UpdateDisplay() {

    display.clearDisplay();
    display.setTextColor(WHITE);
    display.setTextSize(1);

    display.setCursor(0,0);
    display.print("OBDII Key Stats: ");

    display.setCursor(0,10);
    display.print("Current Speed:  ");
    display.print(current_Displayed_Speed_MPH);
    display.print(" MPH");

    display.setCursor(0,20);
    display.print("Current RPM:    ");
    display.print(current_Displayed_RPM);
    display.print(" RPM");
  
} //end function UpdateDisplay

Summary

This was a fun little project to learn how to use the OBD2 library. The library contains PIDs for a whole range of vehicle sensor data and can be used as part of much larger projects. Eventually I intend to expand on this and use this library for future projects and vehicle modding.

Project Files

OBD2_Reader_Example.ino (github.com)

Arduino Electrical

Post navigation

Previous post
Next post

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  • GitHub
  • LinkedIn
  • Thingiverse

About Me

I am engineer located in Northern Indiana who is always tinkering in his spare time. Professionally, I manage large projects in manufacturing with a focus in the automotive industry.  As I don’t often get a chance to do much design work for my employers, this blog is a place for me to document my personal projects and share my knowledge.

©2023 Jason Joyner | WordPress Theme by SuperbThemes