Chris Collins

Tools · cars

OBD-II car diagnostics

Plug an ELM327 adapter into the car and read it from the browser over Bluetooth LE or USB — live gauges and graphs with CSV logging, stored, pending and permanent trouble codes with descriptions, the freeze frame, readiness monitors, the VIN, and clearing codes — or try it all on a simulated car.

Added

Works with

How to use it

Every car sold in the US since 1996 and in Europe since 2001 (petrol) or 2004 (diesel) has an OBD-II socket under the dashboard, usually near the steering column. A cheap ELM327 adapter turns it into a serial port that answers text commands. This page sends those commands from the browser and shows what comes back: the check-engine codes and what they mean, live engine data, and whether the car is ready for an emissions test.

How to use it

  1. Pick how to connect. Demo car needs nothing: a simulated car with an ELM327 in front of it, three stored codes, a pending one, a freeze frame and a one-minute drive loop. Try it first.

  2. For a real car: plug the adapter in, turn the ignition on (engine running or not), and press Connect. The page resets the adapter (ATZ), turns echo, line feeds and spaces off and headers on (ATE0, ATL0, ATS0, ATH1), lets it search for the car’s protocol (ATSP0 and 0100 — up to ten seconds on older cars), then reads the protocol it found, the battery voltage (ATRV), the supported PIDs and the VIN.

  3. Live data: press Start live data. Gauges for engine speed, road speed, coolant, load, throttle and battery; tiles for the rest; a two-minute graph of up to six values. Choose what to read under Values to read — fewer values update faster, since the adapter asks for one at a time. Record CSV saves every reading with its time to a spreadsheet file.

  4. Trouble codes: Read codes reads stored (Mode 03), pending (Mode 07) and permanent (Mode 0A) codes from every module that answers, with a description for the generic P0 codes. Freeze frame (Mode 02) shows the conditions when the first code was stored.

  5. Clear codes… (Mode 04) asks first, and says what it does: the light goes off, the codes and freeze frame go, and every readiness monitor resets — so an emissions test will fail until you have driven enough for them to finish. It doesn’t fix anything.

  6. Readiness lists the on-board self-tests (Mode 01 PID 01) and which have finished.

  7. Vehicle decodes the VIN (maker, model year, check digit) and lists what each module supports.

  8. Console shows every command and reply, and sends your own (ATDP, ATRV, 0105, 0902).

  9. Code lookup describes a code without a car.

Units switch between metric and US at the top.

Which adapter

Bluetooth LE adapters work with Web Bluetooth: Vgate iCar Pro BLE, vLinker MC+/FS BLE, Veepeak OBDCheck BLE and BLE+, and most "Bluetooth 4.0" ELM327 clones. They are serial bridges with a vendor GATT service; the page asks for the common ones — FFF0 (notify FFF1, write FFF2), FFE0 (FFE1 both ways), the vLinker service E7810A71-73AE-499D-8C15-FAA9AEF0C3F2, 18F0 (2AF0/2AF1) and Nordic UART — and picks the notify and write characteristics in whichever it finds. If yours uses another service, put its UUID in the box before connecting (the Bluetooth LE explorer will show it).

Classic Bluetooth adapters — the usual cheap blue ELM327 "v1.5", the OBDLink LX and MX+ — use the Serial Port Profile, which Web Bluetooth doesn’t reach at all. On a computer there is one way in: Chrome and Edge 117 and later let Web Serial open a paired Bluetooth Classic serial device. Pair the adapter in the system’s Bluetooth settings (PIN usually 1234 or 0000), choose USB / serial / Classic BT, and pick it from the list. This doesn’t work on Android, iPhone or in other browsers; I haven’t been able to test it with every adapter. Wi-Fi adapters can’t be used: a web page can’t open a raw TCP socket.

USB adapters work with Web Serial: ELM327 USB cables (CH340 or FTDI), OBDLink SX, vLinker FS USB. Most ELM327 clones run at 38400 baud; some old ones at 9600, the OBDLink SX and vLinker at 115200. If you get nothing back, try another speed.

Clones vary a lot. Many cheap ones claim "v2.1" and implement only part of the command set; a few can’t do the older protocols at all.

What it can’t do

OBD-II is the emissions part of the car’s diagnostics. It reads the engine computer and, often, the transmission. ABS, airbag, body and most manufacturer-specific data use other services (UDS) and the maker’s own identifiers, which this page doesn’t do. The code descriptions are mine, short, and cover the generic SAE J2012 P0 codes and the common P2 and U0 ones; a maker-specific code (P1xxx, most B, C and U codes with 1 or 2 second) is listed but needs the maker’s information.

How it works

The ELM327 takes a command terminated by a carriage return and answers with lines of text ending in a > prompt. With headers on, each line starts with the sender’s address — 7E8 for the engine on 11-bit CAN, 18DAF110 on 29-bit CAN, three header bytes on the older J1850, ISO 9141 and KWP buses — so answers from two modules can be told apart. A CAN frame carries at most seven bytes, so longer answers (the VIN, a list of codes) come as an ISO-TP first frame and numbered consecutive frames, which the page puts back together per sender and checks for gaps; the older buses split them into numbered messages instead. The parsing, the PID formulas, the code tables and the simulated car are in obd2-core.js with tests that run whole sessions on CAN 11-bit, CAN 29-bit and ISO 9141-2.

Related: the serial terminal (for a raw session with the adapter), tyre sizes and speedometer error, the engine calculator and EV charging.

Browser support

Web Bluetooth: Chrome and Edge on Mac, Windows, ChromeOS and Android. Web Serial: Chrome and Edge on a computer. Safari, Firefox and every browser on iPhone and iPad have neither; the demo car and the code lookup work everywhere.

Privacy

Everything happens between the page and the adapter. Nothing about your car — VIN, codes, logs — is sent anywhere; CSV logs are saved to your own computer.

Runs entirely in your browser; nothing you type leaves this page.