Back

OBD_II

Loading views...

OBD-II

Category: Automotive

Overview

OBD-II (On-Board Diagnostics II) is a standardized vehicle diagnostic system mandatory in US vehicles since 1996 and EU vehicles since 2001. It provides access to engine and emissions data via standardized diagnostic trouble codes (DTCs), parameter IDs (PIDs), and multiple protocol options including CAN, ISO 9141, and J1850.

1. Theory & Fundamentals

  • Connector: 16-pin OBD-II DLC (Data Link Connector), typically under dashboard
  • Protocols: ISO 15765-4 (CAN), ISO 14230-4 (KWP2000), ISO 9141-2, SAE J1850 PWM/VPW
  • CAN OBD-II: Dominant since 2008 (all US vehicles); functional address 0x7DF, response 0x7E8
  • Service modes: Mode 01–0A defined by SAE J1979
  • PIDs: Parameter IDs; hundreds defined; ECU responds to supported ones
  • ELM327: Chip translating OBD-II protocols to simple AT commands (used in scan tools)

2. Frame / Packet Structure

CAN OBD-II request (using ISO-TP):
  11-bit CAN ID: 0x7DF (functional broadcast to all ECUs)
  Data: [Length] [Service Mode] [PID] [00 00 00 00]
  Example - Request engine RPM (Mode $01, PID $0C):
  0x7DF | 02 01 0C 00 00 00 00 00

CAN OBD-II response from ECU (e.g., engine ECU):
  11-bit CAN ID: 0x7E8 (ECU 1 response)
  Data: [Length] [Mode+0x40] [PID] [Data bytes]
  Example RPM response:
  0x7E8 | 04 41 0C 1A F8 00 00 00
  RPM = (0x1AF8) / 4 = 1726 RPM

Mode $03 - Read DTCs:
  Request: 02 03 00 00 00 00 00 00
  Response: 06 43 [count] [DTC1 MSB] [DTC1 LSB] [DTC2 MSB] [DTC2 LSB]
  DTC format: P0300 = Powertrain, B1234 = Body, C0456 = Chassis, U1789 = Network

3. Protocol Mechanics

  • ISO-TP (ISO 15765-2): Transport protocol for OBD-II over CAN; handles multi-frame messages
  • Single Frame (SF): PCI type 0, up to 7 bytes; most OBD-II requests fit here
  • First Frame + Consecutive Frame: For responses > 7 bytes (many DTCs)
  • Flow Control: Receiver sends FC frame to control transmission rate
  • Functional address: 0x7DF reaches all ECUs; physical 0x7E0–0x7E7 targets specific ECU

4. Hardware Implementation

  • OBD-II to CAN: Any CAN transceiver + CAN peripheral (STM32, Arduino CAN shield)
  • ELM327 module: USB/Bluetooth/Wi-Fi; handles all protocol complexity via AT commands
  • SN65HVD230 CAN transceiver + STM32 CAN: DIY OBD-II reader
  • OBD-II connector: Available as plug-in breakout boards
  • Power: Pin 16 = battery+; Pin 4/5 = GND; always powered

5. Register-Level / Configuration

// Send OBD-II PID request over CAN
void OBD_Request(uint8_t mode, uint8_t pid) {
    CAN_TxHeaderTypeDef hdr = {
        .StdId = 0x7DF, .DLC = 8, .IDE = CAN_ID_STD
    };
    uint8_t data[8] = {0x02, mode, pid, 0,0,0,0,0};
    uint32_t mailbox;
    HAL_CAN_AddTxMessage(&hcan, &hdr, data, &mailbox);
}

// Parse RPM response
uint16_t OBD_ParseRPM(uint8_t *resp) {
    // Response bytes: [04][41][0C][A][B]
    return ((resp[3] << 8) | resp[4]) / 4;
}

// Usage
OBD_Request(0x01, 0x0C); // Request RPM
// Wait for 0x7E8 response, parse

6. Driver / Software Development

// Using ELM327 AT commands (UART based)
void ELM_Init(void) {
    UART_Send("ATZ
");    delay_ms(1000); // Reset
    UART_Send("ATE0
");   WaitPrompt();   // Echo off
    UART_Send("ATL0
");   WaitPrompt();   // Linefeeds off
    UART_Send("ATSP0
");  WaitPrompt();   // Auto protocol
    UART_Send("ATH0
");   WaitPrompt();   // Headers off
}
float ELM_GetRPM(void) {
    UART_Send("010C
"); // Mode 01, PID 0C
    char resp[20]; ReadLine(resp, 20);
    // Parse hex: "1AF8" → 0x1AF8 / 4
    uint16_t raw = strtol(resp, NULL, 16);
    return raw / 4.0f;
}

7. Debugging & Testing

  • OBD-II app (Torque Pro, Car Scanner): Bluetooth ELM327 + phone
  • SavvyCAN: CAN bus analyzer with OBD-II decode
  • Wireshark SocketCAN: Linux CAN interface + OBD-II dissector
  • Common issues: Protocol not matching vehicle; CAN filter blocking 0x7E8; wrong PID scaling

8. Real-World Applications

  1. Diagnostic scan tools (emissions check, fault reading)
  2. Fleet management telematics
  3. Real-time fuel economy display
  4. Insurance "black box" telematics dongles
  5. Performance data logging (track days)

9. Advanced Topics & Edge Cases

  • UDS (ISO 14229): Extended diagnostics beyond OBD-II; ECU programming
  • Enhanced PIDs: Manufacturer-specific PIDs (Mode 21 or 22)
  • CAN ID scan: Some vehicles use non-standard addresses
  • OBD-II on heavy vehicles: J1939/ISOBUS instead
  • OBD3: Real-time wireless reporting to authorities (proposed, not widespread)

10. Standards & Variants

Standard Protocol Notes
ISO 15765-4 CAN Mandatory US 2008+; EU 2003+
ISO 14230-4 KWP2000 1996–2007 vehicles
ISO 9141-2 K-line European/Asian 1996–2004
SAE J1850 PWM 1-wire Ford vehicles
SAE J1850 VPW 1-wire GM vehicles

💡 Practical Examples

Example 1: Read multiple PIDs

float rpm   = OBD_GetRPM();     // PID 0x0C
float speed = OBD_GetSpeed();   // PID 0x0D (km/h)
float coolant = OBD_GetCoolant(); // PID 0x05 (°C, A-40)
float throttle = OBD_GetThrottle(); // PID 0x11 (%, A*100/255)

Example 2: Read and clear DTCs

OBD_Request(0x03, 0x00); // Mode 03: Read DTCs
// Parse response: P0300 = random misfire, etc.
OBD_Request(0x04, 0x00); // Mode 04: Clear DTCs and MIL

Example 3: Supported PIDs query

OBD_Request(0x01, 0x00); // Supported PIDs 01-20
// Response bitmask shows which PIDs ECU supports

🧪 Practice Questions

Beginner

  1. What is the OBD-II connector called?
  2. What CAN ID is used for OBD-II functional requests?
  3. What does Mode $01 return?
  4. What is a DTC?
  5. What is the ELM327 chip?

Intermediate

  1. Calculate engine RPM from OBD-II response bytes A=0x1A, B=0xF8.
  2. Implement a CAN-based OBD-II request/response driver.
  3. How does ISO-TP handle OBD-II responses larger than 7 bytes?
  4. Write a function to read all supported Mode $01 PIDs.
  5. What is the difference between Mode 01 and Mode 02?

Advanced

  1. Build a complete OBD-II data logger to SD card at 10 Hz.
  2. Implement ISO-TP (ISO 15765-2) from scratch for OBD-II.
  3. Design a telematics device: OBD-II + GPS + LTE-M.
  4. Access manufacturer-specific enhanced PIDs (Mode $22).
  5. Implement UDS session to access ECU diagnostic services.

Hands-on Projects

  1. OBD Display: ELM327 + STM32 + LCD showing RPM, speed, fuel.
  2. Data Logger: Log 10 PIDs to SD card at 1Hz; analyze with Python.
  3. DTC Scanner: Read fault codes, decode them, display descriptions.

Checklist

  • [ ] Understand OBD-II mode and PID structure
  • [ ] Send CAN OBD-II request (0x7DF)
  • [ ] Parse response from 0x7E8
  • [ ] Implement PID scaling formulas
  • [ ] Read all Mode $01 PIDs
  • [ ] Read and clear DTCs (Mode 03/04)
  • [ ] Interface with ELM327 via AT commands
  • [ ] Implement ISO-TP for multi-frame responses
  • [ ] Build real OBD-II data logger
  • [ ] Access enhanced manufacturer PIDs