AI-generated text still pending human review/editing.
ISO-TP transport ↗

OBD-II & SAE J1979

On-Board Diagnostics II is the standardized language every emissions-related ECU speaks. SAE J1979 (a.k.a. ISO 15031-5) defines the request/response messages, engine RPM, vehicle speed, trouble codes, the VIN, that a generic scan tool can read from any compliant vehicle. On a modern car it rides on CAN, transported by ISO-TP.

ISO-TP Transport

OBD-II is an application layer. The bytes travel inside ISO-TP (ISO 15765-2) frames, the same transport UDS uses. sloppyCAN's ISO-TP/UDS tab handles the framing; OBD-II mode gives you one-click buttons instead of typing raw hex. Short requests (1-3 bytes) fit in a single frame; long responses like the VIN arrive as a multi-frame sequence and are reassembled for you.

The transport mechanics, Single Frame, First Frame, Flow Control, Consecutive Frames, are covered in the ISO-TP Explainer.

Connector & CAN Pins

Every OBD-II car has a 16-pin SAE J1962 connector within reach of the driver's seat. On a CAN bus vehicle (mandatory in the US since 2008) the diagnostic CAN pair lives on:

PinSignal
6CAN High (CAN-H)
14CAN Low (CAN-L)
16Battery + (12 V, unswitched)
4 / 5Chassis / signal ground

The diagnostic CAN runs at 500 kbit/s (sometimes 250 kbit/s) with 11-bit identifiers on most vehicles.

Request/Response Flow

A scan tool broadcasts to the functional address 0x7DF. Any ECU that can answer replies on its own address in the range 0x7E8-0x7EF. The engine ECU almost always answers first, on 0x7E8.

Tester → broadcast
0x7DF
01 0C - "give me current Mode 01, PID 0C (RPM)"
→
Engine ECU → tester
0x7E8
41 0C 1A F8 - response SID 0x41, PID 0C, value bytes

The response SID is the request mode + 0x40 (Mode 01 → 0x41), and it echoes the PID so you know which answer is which. Physical (point-to-point) addressing also exists: request 0x7E0 → response 0x7E8. The 29-bit equivalents are 0x18DB33F1 (broadcast) and 0x18DAF1xx (responses).

0x7DF is a broadcast, so several ECUs can answer the same request: engine on 0x7E8, transmission on 0x7E9, and so on. sloppyCAN groups every responder under the one request, tagged by ID. If a reply spans multiple frames, the Flow Control the tester sends back must go to that ECU's physical address (0x7E0), not the broadcast 0x7DF, otherwise a real ECU ignores it.

Modes

OBD-II groups functions into modes (also called services):

ModeMeaningRequest
01Current data (live PIDs)01 <pid>
02Freeze-frame data (snapshot at fault)02 <pid> <frame#>
03Stored DTCs03
04Clear DTCs & reset MIL04
06On-board monitor test results06 <mid>
07Pending DTCs (this drive cycle)07
08Control on-board component08 …
09Vehicle info (VIN, CalID, CVN)09 <pid>
0APermanent DTCs0A

Mode 04 is destructive. Clearing DTCs also wipes freeze-frame data and resets the readiness monitors, so the car has to re-run its self-tests before it will pass inspection. sloppyCAN guards this button with a confirmation.

Decoding a PID Value

Each PID has a fixed formula. Take Engine RPM (Mode 01, PID 0x0C). The ECU returns two bytes A and B, and the standard says:

RPM = ((A × 256) + B) ÷ 4

Response 41 0C 1A F8 → A=0x1A=26, B=0xF8=248 → ((26×256)+248)÷4 = 1726 rpm

Other PIDs use one byte: Vehicle speed (PID 0D) is A km/h; Coolant temp (PID 05) is A − 40 °C (the −40 offset lets one unsigned byte cover −40…215 °C). Percentages are usually A × 100 ÷ 255. sloppyCAN applies these conversions automatically and shows the engineering value.

Discovering Supported PIDs

A scan tool asks which PIDs exist rather than guessing. PID 0x00 returns a 4-byte bitmask of which PIDs in 0x01–0x20 are supported, MSB first (the top bit = PID 0x01). If the last bit (PID 0x20) is set, it means "ask PID 0x20 for the next block," and so on through 0x40 and 0x60.

Response 41 00 BE 1F A8 13 → first byte 0xBE = 1011 1110:
101
002
103
104
105
106
107
008

So PIDs 01, 03, 04, 05, 06, 07 are supported; 02 and 08 are not. The Probe supported PIDs button walks all four blocks and lights the grid.

Trouble Codes (DTCs)

Modes 03, 07 and 0A return Diagnostic Trouble Codes, two bytes each. Those 16 bits unpack into the familiar P0420 form:

BitsMeaning
15–14System letter: 00=P (Powertrain), 01=C (Chassis), 10=B (Body), 11=U (Network)
13–12First digit (0–3)
11–0Remaining three hex digits

Example 0x0420 → top two bits 00 = P, next two 00 = 0, low 12 bits 0x420 → P0420 ("Catalyst System Efficiency Below Threshold, Bank 1").

Try it

Back in sloppyCAN, switch the ISO-TP/UDS tab to OBD-II, click Demo in the header, then hit Engine RPM or start Quick Watch on RPM + Speed + Coolant. The demo ECU answers on 0x7E8 with live-ish values so you can see the whole flow without hardware.