A professional, high-performance Arduino/ESP32 library for vehicle diagnostics over K-Line — universal OBD-II (ISO 9141-2, ISO 14230-4/KWP2000) plus manufacturer-specific deep access for VAG KW1281, BMW DS2 and Opel KW82.
OBD2_KLine is a professional, high-performance library for vehicle diagnostics via K-Line, supporting ISO 9141-2, ISO 14230-4 / KWP2000, VAG KW1281, BMW DS2 and Opel KW82. Designed for Arduino, ESP32 and similar microcontrollers, it lets your device talk directly to a vehicle's ECU over the K-Line.
K-Line is a legacy protocol used in many European and Japanese vehicles built between ~1987 and 2010, especially before CAN became mandatory — making this library ideal for both generic OBD-II diagnostics and manufacturer-specific deep system access (VAG, BMW, Opel).
Confirm your car speaks K-Line by checking the OBD-II connector pins:
- ✅ Pin 7 connected → K-Line (ISO 9141 / ISO 14230). This library will work.
- ❌ Pins 6 & 14 connected → CAN bus. Use my OBD2 CAN Bus Library instead.
Example OBD-II connectors (left: K-Line with pin 7 · right: CAN with pins 6 & 14):
-
Universal compatibility — Arduino (Uno, Nano, Mega), ESP32 and other popular MCUs.
-
Six protocols, one API — the packet format is a setting, not a rewrite of your sketch.
Category Supported Protocols Universal OBD2 ISO 9141-2, ISO 14230-4 (KWP2000) VAG (VW/Audi/Seat/Škoda) KW1281 (legacy block protocol) BMW DS2 (Diagnostic System 2) Opel / Vauxhall KW82 Anything else Custom — define the framing yourself -
Flexible initialization — 5-Baud (Slow Init), Fast Init, ping and handshake-free modes, each selectable independently of the protocol.
-
Automatic detection — finds the protocol on its own when you do not yet know what the car speaks.
-
Handles the plumbing — headers, length bytes, checksums and handshake timings are built and verified for you.
-
Developer friendly — integrated debug output showing every byte on the bus.
Generic diagnostics defined by SAE J1979. No car-specific configuration needed — plug in and read:
| Mode | Description |
|---|---|
| 01 | Live data — real-time sensor values (RPM, coolant temp, speed, throttle, fuel trims…) |
| 02 | Freeze frame — the sensor snapshot stored when a fault appeared |
| 03 | Read stored Diagnostic Trouble Codes (DTCs) |
| 04 | Clear DTCs and reset the MIL |
| 05 | Oxygen sensor test results |
| 06 | On-board monitoring test results |
| 07 | Read pending Diagnostic Trouble Codes |
| 09 | Vehicle information — VIN, Calibration IDs, Calibration Verification Numbers |
DTCs come back as readable codes (P0123 style), and a supported-PID scan lets you ask the ECU
which PIDs it actually implements before requesting them.
The manufacturer protocols reach data and functions that generic OBD-II never exposes:
- Extended live data — manufacturer measurement blocks carrying far more channels than the standard PIDs, decoded into named values with real units (injection time, ignition advance, idle actuator steps, engine load, lambda, and so on). One request returns the whole block, so a dozen values cost a single message.
- Vehicle control & actuator tests — command the ECU to drive real hardware: MIL and service lamps, fuel pump relay, A/C relay, throttle actuator, tank vent valve, and per-cylinder ignition coil or injection cut-off.
- Full ECU identification — VIN, part number, supplier, hardware version, software number and engine code.
- ECU memory & flash reading — read the ECU's internal memory block by block across the whole flash range, streamed over the debug port so you can capture the dump to a file on your PC for analysis.
- Raw service access — send any manufacturer service by hand; the library still adds the header, length byte and checksum for you.
- Discovery tools — scan which identifiers an ECU answers and dump responses as offset tables, so you can map an ECU nobody has documented yet.
💡 Manufacturer-specific access is provided through ECU definition files. The generic OBD-II layer ships with the library; car-specific definitions (Opel Simtec 71 / Bosch M1.5.5 / Bosch ME7.5, BMW Bosch BMS 46 and others) are maintained separately — see the Contact section below.
Real-world throughput measured with this library:
| Protocol | Average responses per second |
|---|---|
| ISO 9141-2 | ~8–9 responses/sec |
| ISO 14230-4 | ~9–10 responses/sec |
🔎 Actual throughput varies with the ECU's internal processing time, the requested PID type and system latency.
- Open the Arduino IDE.
- Go to Sketch → Include Library → Manage Libraries…
- Search for "OBD2 K-Line".
- Click Install.
Download this repo as a .zip and add it via Sketch → Include Library → Add .ZIP Library…
Read Engine RPM, Coolant Temperature and Vehicle Speed. The library automatically handles different board architectures (AVR / ESP32):
#include "OBD2_KLine.h" // core: connection + protocol layer
#include "ecus/OBD2_Standard.h" // standard OBD2 diagnostics -> OBD2_KLine
OBD2_KLine KLine;
// Uno / Nano have no spare hardware serial, so they fall back to AltSoftSerial
// on its fixed pins (RX 8, TX 9). Every other board uses Serial1.
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
#include <AltSoftSerial.h>
AltSoftSerial altSerial;
#define OBD_SERIAL altSerial
#else
#define OBD_SERIAL Serial1
#endif
#define OBD_RX_PIN 5
#define OBD_TX_PIN 4
void setup() {
Serial.begin(115200);
KLine.setSerial(OBD_SERIAL);
KLine.setPins(OBD_RX_PIN, OBD_TX_PIN);
KLine.setDebug(Serial); // View communication logs
KLine.setProtocol(Automatic); // Automatic, ISO9141, ISO14230, KW1281, DS2, KW82, Custom
Serial.println("OBD2 System Starting...");
}
void loop() {
if (!KLine.isConnected() && !KLine.connect()) return;
float rpm = KLine.getLiveData(0x0C); // PID 0x0C: Engine RPM
float coolant = KLine.getLiveData(0x05); // PID 0x05: Coolant Temp
float speed = KLine.getLiveData(0x0D); // PID 0x0D: Vehicle Speed
Serial.print("RPM: "); Serial.println(rpm);
Serial.print("Temp: "); Serial.print(coolant); Serial.println(" C");
Serial.print("Speed: "); Serial.print(speed); Serial.println(" km/h");
}K-Line operates at different voltage/signal levels than microcontroller pins. These circuits provide level shifting and protection for safe, stable operation. Pick the approach that suits your project:
Simple, low-cost discrete-transistor interface for basic builds and prototyping. R6 is sized for 3.3V MCUs — for a 5V MCU, change R6 to 5.3 kΩ.
Uses a cheap comparator IC (e.g. LM393) for a clean digital level — better noise immunity and well-defined thresholds than the transistor design, at a slightly higher component count.
Purpose-built K-Line / ISO 9141 transceiver ICs (L9637D, MC33290, Si9241, SN65HVDA195, etc.) with built-in level shifting and protection — highest reliability, recommended for production-grade designs.
Custom PCBs designed for this library:
🛠️ Custom hardware & PCBs: looking for ready-to-use devices or custom-made PCBs based on this project? Reach out via email in the Contact section below.
Part of a full OBD2 / automotive diagnostics ecosystem:
| Firmware & Readers | Libraries | Manufacturer Protocols | UI |
|---|---|---|---|
| OBD2 K-line Reader | OBD2 K-Line Library | BMW I/K Bus | OBD2 Diagnostic UI |
| OBD2 CAN Bus Reader | OBD2 CAN Bus Library | VAG KW1281 |
If you enjoy my projects and want to support me, you can do so through the links below:
For information, job offers, collaboration, sponsorship, or purchasing my devices, you can contact me via email.
📧 Email: muksin.muksin04@gmail.com
Created by Muki · If you find this useful, consider giving it a ⭐







