Decoding Your Car’s Language: Getting Started with OBD Scanner 2 and ISO 9141 Protocol

For automotive DIY enthusiasts and professionals alike, accessing your vehicle’s diagnostic data is crucial for maintenance and repair. OBD-II (On-Board Diagnostics II) scanners are the key to unlocking this information, allowing you to read trouble codes, monitor engine performance, and much more. If you’re venturing into the world of vehicle diagnostics, particularly with older vehicles or specific systems, understanding protocols like ISO 9141 is essential. This article dives into a practical experience of successfully using an Obd Scanner 2 Iso 9141 setup with Arduino, offering insights and a working code example to get you started.

Understanding the ISO 9141 Protocol

ISO 9141 is one of the several communication protocols used in OBD-II systems. Predominantly found in older European and Asian vehicles, it’s characterized by its use of asynchronous serial communication. While newer vehicles often utilize CAN (Controller Area Network) protocols, ISO 9141 remains relevant for accessing diagnostics in a significant portion of the car parc. When selecting an OBD scanner 2, compatibility with ISO 9141 is a key specification to check if you are working with vehicles that utilize this protocol.

The Breakthrough: Soft Serial Example for OBD2 ISO 9141

Many enthusiasts, when starting with OBD scanner 2 ISO 9141 and Arduino, encounter challenges in establishing a reliable connection. Numerous code snippets and library attempts might fall short, leading to frustration. The turning point often lies in utilizing the right example code and understanding the nuances of serial communication with OBD-II protocols.

In this successful endeavor, the solution was found within the examples provided by the iwanders/OBD9141 Arduino library. Specifically, the ISO9141_rreader_softserial.ino example, located within the library’s examples under the OBD9141 folder, proved to be the key. This example, designed for ‘Soft Serial’ communication, worked almost “straight off” and provided a solid foundation for further customization.

Key Tweaks for a Working OBD Scanner 2 ISO 9141 Setup

While the example code provided a great starting point, a few tweaks were necessary to ensure optimal performance and compatibility, especially when not using specific transceiver chips.

Irrelevant EN_PIN Code

The original example code was designed with the SN65HVDA100 transceiver chip in mind. This is evident in the code lines defining EN_PIN = 10 and the subsequent pinMode and digitalWrite commands related to it. For setups not utilizing this specific chip, this section of code becomes irrelevant. However, importantly, its presence does not hinder the functionality of the code and can be safely left as is or removed without affecting the communication.

AltSoftSerial for Arduino Nano and Similar Boards

For Arduino Nano and potentially other Arduino boards, the use of an alternative serial driver library like AltSoftSerial is crucial. This is because these boards typically have only one hardware serial port, which is usually reserved for communication with your computer via USB. To simultaneously communicate with the OBD scanner 2 ISO 9141 interface, a second serial line is required. AltSoftSerial provides this capability by using software to emulate a second serial port on different digital pins of the Arduino. The example code correctly utilizes AltSoftSerial, assigning pins 8 and 9 for receiving (RX) and transmitting (TX) data to the OBD-II interface, respectively.

Serial Monitor Speed

Ensure that the Serial Monitor speed in the Arduino IDE matches the baud rate used in your code. The example code might default to 9600 baud, but often a faster rate like 115200 baud, as used in the provided code, is preferable for quicker data transfer and responsiveness. Always verify and adjust this setting for proper communication and data display.

Addressing PID Request Issues with Delays

Initially, during testing, only some of the requested PIDs (Parameter IDs) were successfully read. Specifically, when requesting “Throttle, RPM, & Speed,” only two out of the three values would appear on the Serial Monitor, often the first and third, but sporadically. Changing the order of PIDs didn’t resolve the issue; the second requested PID consistently failed to return data.

The solution was to introduce a small delay between consecutive PID requests. Adding a 50ms delay after each obd.getCurrentPID command proved to be the fix. This suggests that the ISO 9141 protocol, or the vehicle’s ECU implementation, requires a brief pause between diagnostic requests. Without this delay, subsequent requests might be sent too rapidly and ignored by the car’s system.

By implementing these delays, all requested PIDs started returning data reliably, demonstrating the importance of timing in OBD-II communication, especially with protocols like ISO 9141.

Working Code Example for OBD Scanner 2 ISO 9141 with Arduino

Here’s the complete Arduino code that successfully reads data from an OBD scanner 2 ISO 9141 interface, incorporating the crucial 50ms delays:

#include "Arduino.h"
#include "AltSoftSerial.h"
#include "OBD9141.h"

#define RX_PIN 8       // connect to transceiver Rx
#define TX_PIN 9       // connect to transceiver Tx
#define EN_PIN 10      // pin will be set high (connect to EN pin of SN65HVDA100) - Irrelevant if not using this chip

AltSoftSerial altSerial;
OBD9141 obd;

void setup() {
  Serial.begin(115200);
  delay(2000);
  pinMode(EN_PIN, OUTPUT);
  digitalWrite(EN_PIN, HIGH); // enable the transceiver IC - Irrelevant if not using this chip

  obd.begin(altSerial, RX_PIN, TX_PIN);
}

void loop() {
  Serial.println("Looping");
  bool init_success = obd.init();
  Serial.print("init_success:");
  Serial.println(init_success);

  if (init_success) {
    bool res;
    while (1) {
      // FORMAT: obd.getCurrentPID =>> (address, number of bytes)

      res = obd.getCurrentPID(0x11, 1); // Throttle Position
      if (res) {
        Serial.print("Result 0x11 (Throttle): ");
        Serial.println(obd.readUint8() / 2.55); // 100/255 x data (or A / 2.55) = 0% to 100%
      }
      delay(50);

      res = obd.getCurrentPID(0x0F, 1); // Air Intake Temperature
      if (res) {
        Serial.print("Result 0x0F (Air Intake Temp): ");
        Serial.println(obd.readUint8() - 40);  // Temp = data -40
      }
      delay(50);

      res = obd.getCurrentPID(0x05, 1); // Engine Coolant Temperature
      if (res) {
        Serial.print("Result 0x05 (Engine coolant temperature): ");
        Serial.println(obd.readUint8() - 40);  // Temp = data -40
      }
      delay(50);

      res = obd.getCurrentPID(0x0C, 2); // RPM
      if (res) {
        Serial.print("Result 0x0C (RPM): ");
        Serial.println(obd.readUint16() / 4); // RPM = (256*A + B) / 4 - Formula from OBD-II PIDs
      }
      delay(50);

      res = obd.getCurrentPID(0x0D, 1); // Vehicle Speed
      if (res) {
        Serial.print("Result 0x0D (Speed): ");
        Serial.println(obd.readUint8());     // Speed = data (1:1 with data in km/h or mph depending on vehicle)
      }

      Serial.println();
      delay(200);
    }
  }
  delay(3000);
}

This code initializes the OBD9141 library with AltSoftSerial, sets up serial communication, and then enters a loop to continuously request and display data for Throttle position, Air Intake Temperature, Engine Coolant Temperature, RPM, and Vehicle Speed. Each PID request is followed by a 50ms delay to ensure reliable data retrieval.

Data Accuracy and Further Verification

While this setup successfully retrieves data from the OBD scanner 2 ISO 9141 interface, the accuracy of the returned values and their interpretation requires careful attention. The code includes comments referencing formulas based on the Wikipedia OBD-II PIDs page, which is a valuable resource for understanding PID data interpretation.

For instance, the formula for Engine Coolant Temperature (PID 0x05) is A - 40, where ‘A’ is the raw data byte. Similarly, RPM (PID 0x0C) uses the formula (256*A + B) / 4 for the two returned bytes A and B. While initial tests showed plausible RPM readings, further verification is essential, especially for other PIDs and different vehicle models.

Specifically, in the example data logs, the Air Intake Temperature reading of 27°C appeared higher than the ambient temperature of 19°C, even before engine startup. This suggests a potential need for calibration or a “fudge factor” to align the readings with real-world values. Similarly, vehicle speed data requires a road test to confirm its accuracy against the vehicle’s speedometer or GPS measurements.

Conclusion: Progress in OBD2 ISO 9141 Diagnostics

This journey demonstrates a successful step forward in interfacing with OBD scanner 2 ISO 9141 systems using Arduino. By leveraging the Soft Serial example, implementing necessary tweaks like delays between PID requests, and understanding data interpretation, you can effectively access valuable diagnostic information from your vehicle. Further investigation and verification are always recommended to ensure the accuracy of the data and to fine-tune your setup for specific vehicle models and diagnostic needs. This progress opens up exciting possibilities for DIY automotive diagnostics and custom vehicle data monitoring projects.

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 *