Arduino Uno breadboard setup with OBD2 UART adapter and LCD screen for car diagnostics project.
Arduino Uno breadboard setup with OBD2 UART adapter and LCD screen for car diagnostics project.

Troubleshooting Your Arduino OBD2 TTL Adapter Connection for Car Diagnostics

Are you diving into the world of DIY car diagnostics with an Arduino, an OBD2 UART adapter, and a TTL serial connection? Many enthusiasts are leveraging the power of Arduino to tap into their car’s data, displaying real-time information like RPM, speed, and coolant temperature on a custom dashboard. This guide addresses a common challenge faced by beginners: getting static or unchanging readings from your OBD2 connection despite a seemingly correct setup.

The goal is to read live data from your car’s OBD2 port using an Arduino Uno, a Sparkfun OBDII UART adapter, and display it on an LCD screen. The initial setup involves wiring the OBD2 adapter to the Arduino and using example code to fetch and display parameters like RPM and speed.

However, a frequent roadblock occurs when the Arduino seems to capture initial values – perhaps RPM and speed readings from when the car was last running – but fails to update these values in real-time, even after starting the engine. This article will explore troubleshooting steps and potential solutions to get your Arduino OBD2 project streaming live car data.

Identifying the Problem: Static OBD2 Data with Arduino

The core issue is that the Arduino is displaying seemingly fixed values for parameters like RPM and speed. Instead of reflecting the current engine state, the readings remain stagnant, suggesting a failure in continuous data acquisition from the OBD2 port.

The user initially wired their Sparkfun OBDII UART adapter to an Arduino Uno as follows:

  • OBD TX -> Arduino RX
  • OBD RX -> Arduino TX
  • OBD GND -> Arduino GND

They adapted example code to display RPM and speed on a DFRobot_RGBLCD screen. The code sends commands “010D” (speed) and “010C” (RPM) to the OBD2 adapter and processes the responses.

#include <softwareserial.h>
#include "DFRobot_RGBLCD.h"

const int colorR = 255;
const int colorG = 0;
const int colorB = 0;

DFRobot_RGBLCD lcd(16,2);  //16 characters and 2 lines of show char

char rxData[20];
char rxIndex=0;
int vehicleSpeed=0;
int vehicleRPM=0;

void setup() {
  lcd.init();
  lcd.setRGB(colorR, colorG, colorB);
  Serial.begin(9600);
  lcd.clear();

  lcd.setCursor(0,0);
  lcd.print("Hiz: ");
  lcd.setCursor(0,1);
  lcd.print("Devir: ");
  delay(1500);

  Serial.println("ATZ"); // Reset OBD adapter
  delay(2000);
  Serial.flush();
}

void loop() {
  Serial.println("010D"); // Request vehicle speed
  getResponse();
  getResponse();
  vehicleSpeed = strtol(&rxData[6],0,16);
  lcd.setCursor(4,0);
  lcd.print(vehicleSpeed);
  lcd.print(" km/h");
  delay(100);
  Serial.flush();

  Serial.println("010C"); // Request engine RPM
  getResponse();
  getResponse();
  vehicleRPM = ((strtol(&rxData[6],0,16)*256)+strtol(&rxData[9],0,16))/4;
  lcd.setCursor(6,1);
  lcd.print(vehicleRPM);
  delay(100);
}

void getResponse(void){
  char inChar=0;
  while(inChar != 'r'){
    if(Serial.available() > 0){
      if(Serial.peek() == 'r'){
        inChar=Serial.read();
        rxData[rxIndex]='';
        rxIndex=0;
      }
      else{
        inChar = Serial.read();
        rxData[rxIndex++]=inChar;
      }
    }
  }
}

Despite this setup, the displayed RPM and speed values remained constant, even after starting the car.

Validating the OBD2 Adapter with a TTL Adapter

To isolate the problem, the user wisely tested the OBD2 UART adapter independently using a Waveshare USB FTDI (TTL) adapter and a serial terminal program (Tera Term). This is a crucial step in troubleshooting.

The TTL adapter was connected to the OBD2 adapter as follows:

  • OBD TX -> TTL RX
  • OBD RX -> TTL TX
  • OBD GND -> TTL GND

Connecting to the car’s OBD2 port and sending commands via Tera Term confirmed that the OBD2 adapter itself was functioning correctly and communicating with the car. Commands like ATZ, ATRV, ATSP0, 010C, and 010D yielded expected responses, including changing RPM values when the engine was started.

ATZ -- resetted card successfully
ATRV -- returned 12.4 V (battery voltage)
ATSP0 -- auto find and select car's protocol - OK
010C -- RPM (engine off) - 41 0C 00 00
010C -- RPM (engine idle) - 41 0C 10 F4 (approx. 1000 RPM)
010D -- speed (car stationary) - 41 00 00
010D -- speed (car stationary) - 41 00 00

This test definitively showed that the Sparkfun OBD2 UART adapter was capable of communicating with the car and providing live data. The issue, therefore, likely lies in the Arduino integration or code.

Potential Causes and Solutions for Static Data

Given that the OBD2 adapter works with a TTL serial connection, but not consistently with the Arduino, here are several areas to investigate:

  1. Serial Communication Issues:

    • Baud Rate Mismatch: Ensure the baud rate in your Arduino code (Serial.begin(9600)) matches the expected baud rate of the OBD2 UART adapter (typically 9600 or 115200 – check the adapter’s documentation).
    • SoftwareSerial Conflicts: If you are using SoftwareSerial for the OBD2 connection (though not apparent in the provided code snippet, it’s a common practice), it can sometimes be unreliable at higher baud rates or when other operations are happening simultaneously. Consider using the hardware serial port (pins 0 and 1) if possible, or optimize your code for SoftwareSerial.
    • Data Parsing Errors: Double-check the getResponse() function and the data parsing logic (strtol(&rxData[6],0,16)) to ensure it correctly extracts the numerical values from the OBD2 adapter’s responses. OBD2 responses have a specific format, and even minor deviations can cause parsing failures.
  2. Wiring and Connections:

    • Loose Connections: Carefully inspect all wiring connections between the Arduino, OBD2 adapter, and breadboard. Loose or intermittent connections can disrupt serial communication.
    • TX/RX Swap: While the user seems to have connected TX to RX and vice versa, it’s always worth double-checking. Incorrect TX/RX wiring will prevent communication.
    • Ground Loop Issues: In some cases, ground loop issues can interfere with serial communication. Ensure a solid and common ground connection between all components.
  3. Power Supply:

    • Insufficient Power: Although less likely with a simple UART adapter, ensure the Arduino and OBD2 adapter are receiving sufficient power. While the OBD2 port provides power, the adapter and Arduino combined might draw more current, especially if other peripherals are connected.
  4. Code Logic and Timing:

    • Serial.flush() Usage: The repeated use of Serial.flush() after each command and response might be causing unintended delays or data loss. Serial.flush() waits for the transmission of outgoing serial data to complete, which might not be necessary or beneficial in this receive-heavy scenario. Try removing or reducing the frequency of Serial.flush().
    • Response Handling: The getResponse() function waits for a carriage return (r). Ensure that the OBD2 adapter actually terminates its responses with r and not just a newline (n) or carriage return and newline (rn). You may need to adjust the getResponse() function accordingly or check the adapter’s documentation for response formatting.
    • Delay Issues: The delay(100) calls in the loop() function are short, but excessive delays in other parts of the code, or within libraries, could potentially cause the Arduino to miss incoming data.
  5. OBD2 Protocol and Initialization:

    • Protocol Auto-Detection: The ATSP0 command aims to auto-detect the car’s OBD2 protocol. While the TTL test was successful, ensure that the Arduino code also allows sufficient time for protocol negotiation after sending ATZ and before sending data requests like 010C and 010D. Adding delays after ATZ and potentially after the first data request might be necessary.
    • Vehicle Compatibility: While less probable given the TTL test success, verify that your car’s OBD2 protocol is fully compatible with the Sparkfun OBD2 UART adapter and the generic OBD2 PIDs (Parameter IDs) 010C and 010D.

Debugging Steps and Next Actions

To pinpoint the issue and achieve live OBD2 data streaming with your Arduino, consider these debugging steps:

  1. Simplify the Code: Start with the most basic code possible, focusing solely on reading RPM or speed. Remove LCD display code temporarily to rule out any potential conflicts. Use the Arduino Serial Monitor to observe the raw data coming from the OBD2 adapter.

  2. Increase Serial Debugging: Add Serial.print() and Serial.println() statements within your getResponse() function and data processing sections to monitor the raw serial data received by the Arduino. This will help you see exactly what the adapter is sending and identify any parsing issues.

  3. Adjust Delays: Experiment with slightly longer delays after Serial.println("ATZ") and before sending the first data request (010D or 010C). Also, try adding a short delay after sending each data request to allow the adapter time to respond fully.

  4. Verify Baud Rate: Double-confirm the correct baud rate for your OBD2 UART adapter and ensure it is consistently set in your Arduino code (Serial.begin()).

  5. Check Response Termination: Use the serial monitor to inspect the raw responses from the OBD2 adapter. Determine if responses are terminated with r, n, or rn and adjust the getResponse() function accordingly.

  6. Re-examine Wiring: Carefully re-check and, if possible, remake all wiring connections to ensure they are secure and correct.

By systematically working through these troubleshooting steps and focusing on serial communication, wiring, and code logic, you should be able to identify the root cause of the static data issue and get your Arduino OBD2 project displaying real-time car diagnostics information.

[

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

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