According to the OBD-II standard, requests to a vehicle's ECU via the OBD-II port are made up of two bytes (excluding header and CRC bytes). The first byte determines the desired mode of operation, and the second byte is the requested parameter identification (PID) number. The ECU will respond with a two byte acknowledgement and possibly some number of data bytes.
Modes
There are nine modes of operation described in the OBD-II standard (SAE J1979). They are:
- Show current data
- Show freeze frame data
- Show stored trouble codes
- Clear trouble codes and stored values
- Test results, oxygen sensors
- Test results, non-continuously monitored
- Show pending trouble codes
- Special control mode
- Request vehicle information
Vehicle manufactures are not required to support all modes, and they are allowed to include custom modes above #9.
PIDs
The table below shows the standard OBD-II PIDs as defined by SAE J1979. The expected response for each PID is given, along with information on how to translate the response into meaningful data. Again, not all vehicles will support all PIDs and there can be manufacturer-defined custom PIDs that are not defined in the OBD-II standard.
Note that modes 1 and 2 are basically identical, except that Mode 1 provides current information, whereas Mode 2 provides a snapshot of the same data taken at the point when the last diagnostic trouble code was set. The exceptions are PID 01, which is only available in Mode 1, and PID 02, which is only available in Mode 2. If Mode 2 PID 02 returns zero, then there is no snapshot and all other Mode 2 data is meaningless.
Mode (hex) | PID (hex) | Data bytes returned | Description | Min value | Max value | Units | Formula |
---|
01 | 00 | 4 | PIDs supported | | | | Bit encoded [A7..D0] == [PID 0x01..PID 0x20] |
01 | 01 | 4 | Number of trouble codes and I/M info | | | | Bit encoded. See below. |
01 | 03 | 2 | Fuel system status | | | | Bit encoded. See below. |
01 | 04 | 1 | Calculated engine load value | 0 | 100 | % | A*100/255 |
01 | 05 | 1 | Engine coolant temperature | -40 | 215 | °C | A-40 |
01 | 06 | 1 | Short term fuel % trim—Bank 1 | -100 (lean) | 99.22 (rich) | % | 0.7812 * (A-128) |
01 | 07 | 1 | Long term fuel % trim—Bank 1 | -100 (lean) | 99.22 (rich) | % | 0.7812 * (A-128) |
01 | 08 | 1 | Short term fuel % trim—Bank 2 | -100 (lean) | 99.22 (rich) | % | 0.7812 * (A-128) |
01 | 09 | 1 | Long term fuel % trim—Bank 2 | -100 (lean) | 99.22 (rich) | % | 0.7812 * (A-128) |
01 | 0A | 1 | Fuel pressure | 0 | 765 | kPa (gauge) | A*3 |
01 | 0B | 1 | Intake manifold pressure | 0 | 255 | kPa (absolute) | A |
01 | 0C | 2 | Engine RPM | 0 | 16,383.75 | rpm | ((A*256)+B)/4 |
01 | 0D | 1 | Vehicle speed | 0 | 255 | km/h | A |
01 | 0E | 1 | Timing advance | -64 | 63.5 | ° relative to #1 cylinder | A/2 - 64 |
01 | 0F | 1 | Intake air temperature | -40 | 215 | °C | A-40 |
01 | 10 | 2 | MAF air flow rate | 0 | 655.35 | g/s | ((256*A)+B) / 100 |
01 | 11 | 1 | Throttle position | 0 | 100 | % | A*100/255 |
01 | 12 | 1 | Sec.(?) air status | | | | Bit encoded. See below. |
01 | 13 | 1 | Oxygen sensors present | | | | [A0..A3] == Bank 1, Sensors 1-4. [A4..A7] == Bank 2... |
01 | 14 | 2 | Bank 1, Sensor 1: Oxygen sensor voltage, Short term fuel trim | 0 0 | 1.275 99.2 | Volts % | A * 0.005 (B-128) * 0.7812 (if B==0xFF, sensor is not used in trim calc) |
01 | 15 | 2 | Bank 1, Sensor 2: Oxygen sensor voltage, Short term fuel trim | 0 0 | 1.275 99.2 | Volts % | A * 0.005 (B-128) * 0.7812 (if B==0xFF, sensor is not used in trim calc) |
01 | 16 | 2 | Bank 1, Sensor 3: Oxygen sensor voltage, Short term fuel trim | 0 0 | 1.275 99.2 | Volts % | A * 0.005 (B-128) * 0.7812 (if B==0xFF, sensor is not used in trim calc) |
01 | 17 | 2 | Bank 1, Sensor 4: Oxygen sensor voltage, Short term fuel trim | 0 0 | 1.275 99.2 | Volts % | A * 0.005 (B-128) * 0.7812 (if B==0xFF, sensor is not used in trim calc) |
01 | 18 | 2 | Bank 2, Sensor 1: Oxygen sensor voltage, Short term fuel trim | 0 0 | 1.275 99.2 | Volts % | A * 0.005 (B-128) * 0.7812 (if B==0xFF, sensor is not used in trim calc) |
01 | 19 | 2 | Bank 2, Sensor 2: Oxygen sensor voltage, Short term fuel trim | 0 0 | 1.275 99.2 | Volts % | A * 0.005 (B-128) * 0.7812 (if B==0xFF, sensor is not used in trim calc) |
01 | 1A | 2 | Bank 2, Sensor 3: Oxygen sensor voltage, Short term fuel trim | 0 0 | 1.275 99.2 | Volts % | A * 0.005 (B-128) * 0.7812 (if B==0xFF, sensor is not used in trim calc) |
01 | 1B | 2 | Bank 2, Sensor 4: Oxygen sensor voltage, Short term fuel trim | 0 0 | 1.275 99.2 | Volts % | A * 0.005 (B-128) * 0.7812 (if B==0xFF, sensor is not used in trim calc) |
01 | 1C | 1 | OBD standards this vehicle conforms to | | | | Bit encoded. See below. |
01 | 1D | 1 | Oxygen sensors present | | | | Similar to PID 13, but [A0..A7] == [B1S1, B1S2, B2S1, B2S2, B3S1, B3S2, B4S1, B4S2] |
01 | 1E | 1 | Auxiliary input status | | | | A0 == Power Take Off (PTO) status (1 == active) [A1..A7] not used |
01 | 1F | 2 | Run time since engine start | 0 | 65,535 | seconds | (A*256)+B |
01 | 20 | 4 | PIDs supported 21-40 | | | | Bit encoded [A7..D0] == [PID 0x21..PID 0x40] |
01 | 21 | 2 | Distance traveled with MIL on | 0 | 65,535 | km | (A*256)+B |
01 | 22 | 2 | Fuel Rail Pressure (relative to manifold vacuum) | 0 | 5177.265 | kPa | ((A*256)+B) * 0.079 |
01 | 23 | 1 (?) | Fuel Pressure (diesel) | 0 | 765 (?) | kPa (gauge) | A*3 (?) |
01 | 24 | 4 | O2S1_WR_lambda(1): Equivalence Ratio Voltage | 0 0 | 2 8 | N/A V | ((A*256)+B)*0.0000305 ((C*256)+D)*0.000122 |
01 | 25 | 4 | O2S2_WR_lambda(1): Equivalence Ratio Voltage | 0 0 | 2 8 | N/A V | ((A*256)+B)*0.0000305 ((C*256)+D)*0.000122 |
01 | 26 | 4 | O2S3_WR_lambda(1): Equivalence Ratio Voltage | 0 0 | 2 8 | N/A V | ((A*256)+B)*0.0000305 ((C*256)+D)*0.000122 |
01 | 27 | 4 | O2S4_WR_lambda(1): Equivalence Ratio Voltage | 0 0 | 2 8 | N/A V | ((A*256)+B)*0.0000305 ((C*256)+D)*0.000122 |
01 | 28 | 4 | O2S5_WR_lambda(1): Equivalence Ratio Voltage | 0 0 | 2 8 | N/A V | ((A*256)+B)*0.0000305 ((C*256)+D)*0.000122 |
01 | 29 | 4 | O2S6_WR_lambda(1): Equivalence Ratio Voltage | 0 0 | 2 8 | N/A V | ((A*256)+B)*0.0000305 ((C*256)+D)*0.000122 |
01 | 2A | 4 | O2S7_WR_lambda(1): Equivalence Ratio Voltage | 0 0 | 2 8 | N/A V | ((A*256)+B)*0.0000305 ((C*256)+D)*0.000122 |
01 | 2B | 4 | O2S8_WR_lambda(1): Equivalence Ratio Voltage | 0 0 | 2 8 | N/A V | ((A*256)+B)*0.0000305 ((C*256)+D)*0.000122 |
01 | 2C | 1 | Commanded EGR | 0 | 100 | % | 100*A/255 |
01 | 2D | 1 | EGR Error | -100 | 99.22 | % | A*0.78125 - 100 |
01 | 2E | 1 | Commanded evaporative purge | 0 | 100 | % | 100*A/255 |
01 | 2F | 1 | Fuel Level Input | 0 | 100 | % | 100*A/255 |
01 | 30 | 1 | # of warm-ups since codes cleared | 0 | 255 | N/A | A |
01 | 31 | 2 | Distance traveled since codes cleared | 0 | 65,535 | km | (A*256)+B |
01 | 32 | 2 | Evap. System Vapor Pressure | -8,192 | 8,192 | Pa | ((A*256)+B)/4 - 8,192 |
01 | 33 | 1 | Barometric pressure | 0 | 255 | kPa (Absolute) | A |
01 | 34 | 4 | O2S1_WR_lambda(1): Equivalence Ratio Current | 0 -128 | 2 128 | N/A mA | ((A*256)+B)*0.0000305 ((C*256)+D)*0.00391 - 128 |
01 | 35 | 4 | O2S2_WR_lambda(1): Equivalence Ratio Current | 0 -128 | 2 128 | N/A mA | ((A*256)+B)*0.0000305 ((C*256)+D)*0.00391 - 128 |
01 | 36 | 4 | O2S3_WR_lambda(1): Equivalence Ratio Current | 0 -128 | 2 128 | N/A mA | ((A*256)+B)*0.0000305 ((C*256)+D)*0.00391 - 128 |
01 | 37 | 4 | O2S4_WR_lambda(1): Equivalence Ratio Current | 0 -128 | 2 128 | N/A mA | ((A*256)+B)*0.0000305 ((C*256)+D)*0.00391 - 128 |
01 | 38 | 4 | O2S5_WR_lambda(1): Equivalence Ratio Current | 0 -128 | 2 128 | N/A mA | ((A*256)+B)*0.0000305 ((C*256)+D)*0.00391 - 128 |
01 | 39 | 4 | O2S6_WR_lambda(1): Equivalence Ratio Current | 0 -128 | 2 128 | N/A mA | ((A*256)+B)*0.0000305 ((C*256)+D)*0.00391 - 128 |
01 | 3A | 4 | O2S7_WR_lambda(1): Equivalence Ratio Current | 0 -128 | 2 128 | N/A mA | ((A*256)+B)*0.0000305 ((C*256)+D)*0.00391 - 128 |
01 | 3B | 4 | O2S8_WR_lambda(1): Equivalence Ratio Current | 0 -128 | 2 128 | N/A mA | ((A*256)+B)*0.0000305 ((C*256)+D)*0.00391 - 128 |
01 | 3C | 2 | Catalyst Temperature Bank 1, Sensor 1 | -40 | 6,513.5 | °C | ((A*256)+B)/10 -40 |
01 | 3D | 2 | Catalyst Temperature Bank 1, Sensor 2 | -40 | 6,513.5 | °C | ((A*256)+B)/10 -40 |
01 | 3E | 2 | Catalyst Temperature Bank 2, Sensor 1 | -40 | 6,513.5 | °C | ((A*256)+B)/10 -40 |
01 | 3F | 2 | Catalyst Temperature Bank 2, Sensor 2 | -40 | 6,513.5 | °C | ((A*256)+B)/10 -40 |
01 | 40 | 4 | PIDs supported 41-60 (?) | | | | Bit encoded [A7..D0] == [PID 0x41..PID 0x60] (?) |
01 | 41 | ? | Monitor status this drive cycle | ? | ? | ? | ? |
01 | 42 | 2 | Control module voltage | 0 | 65.535 | V | ((A*256)+B)/1000 |
01 | 43 | 2 | Absolute load value | 0 | 25696 | % | ((A*256)+B)*100/255 |
01 | 44 | 2 | Command equivalence ratio | 0 | 2 | N/A | ((A*256)+B)*0.0000305 |
01 | 45 | 1 | Relative throttle position | 0 | 100 | % | A*100/255 |
01 | 46 | 1 | Ambient air temperature | -40 | 215 | °C | A-40 |
01 | 47 | 1 | Absolute throttle position B | 0 | 100 | % | A*100/255 |
01 | 48 | 1 | Absolute throttle position C | 0 | 100 | % | A*100/255 |
01 | 49 | 1 | Accelerator pedal position D | 0 | 100 | % | A*100/255 |
01 | 4A | 1 | Accelerator pedal position E | 0 | 100 | % | A*100/255 |
01 | 4B | 1 | Accelerator pedal position F | 0 | 100 | % | A*100/255 |
01 | 4C | 1 | Commanded throttle actuator | 0 | 100 | % | A*100/255 |
01 | 4D | 2 | Time run with MIL on | 0 | 65,535 | minutes | (A*256)+B |
01 | 4E | 2 | Time since trouble codes cleared | 0 | 65,535 | minutes | (A*256)+B |
01 | C3 | ? | ? | ? | ? | ? | Returns numerous data, including Drive Condition ID and Engine Speed* |
01 | C4 | ? | ? | ? | ? | ? | B5 is Engine Idle Request B6 is Engine Stop Request* |
02 | 02 | 2 | Freeze frame trouble code | | | | BCD encoded, see below. |
03 | N/A | n*6 | Request trouble codes | | | | 3 codes per message frame, BCD encoded. See below. |
04 | N/A | 0 | Clear trouble codes / MIL | | | | Clears all stored trouble codes and turns the MIL off. |
09 | 02 | 5x5 | Vehicle serial number | | | | Returns 5 lines, A is line ordering flag, B-E ASCII coded VIN digits. |
In the formula column, letters A, B, C, etc. represent the decimal equivalent of the first, second, third, etc. bytes of data. Where a (?) appears, contradictory or incomplete information was available. Someone with a copy of the 2006 SAE HS-3000 should fact-check these.
Bitwise encoded PIDs
Some of the PIDs in the above table cannot be explained with a simple formula. A more elaborate explanation of these data is provided here:
Mode 1 PID 01: A request for this PID returns 4 bytes of data. The first byte contains two pieces of information. Bit A7 (the seventh bit of byte A, the first byte) indicates whether or not the MIL (check engine light) is illuminated. Bits A0 through A6 represent the number of diagnostic trouble codes currently flagged in the ECU. The second, third, and fourth bytes give information about the availability and completeness of certain on-board tests:
Test available Test completeMisfire B0 B4 Fuel System B1 B5Components B2 B6Reserved B3 B7Catalyst C0 D0Heated Catalyst C1 D1Evaporative System C2 D2Secondary Air System C3 D3A/C Refrigerant C4 D4Oxygen Sensor C5 D5Oxygen Sensor Heater C6 D6EGR System C7 D7
Mode 1 PID 03: A request for this PID returns 2 bytes of data.The first byte describes fuel system #1. Only one bit should ever be set.
A0 Open loop due to insufficient engine temperatureA1 Closed loop, using oxygen sensor feedback to determine fuel mixA2 Open loop due to engine loadA3 Open loop due to system failureA4 Closed loop, using at least one oxygen sensor but there is a fault in the feedback systemA5-A7 Always zero
The second byte describes fuel system #2 (if it exists) and is encoded identically to the first byte.
Mode 1 PID 12: A request for this PID returns a single byte of data which describes the secondary air status. Only one bit should ever be set.
A0 Upstream of catalytic converterA1 Downstream of catalytic converterA2 From the outside atmosphere or offA3-A7 Always zero
Mode 1 PID 1C: A request for this PID returns a single byte of data which describes which OBD standards this ECU was designed to comply with. The hexadecimal and binary representations of the data byte are shown below next to what it implies:
0x01 00000001b OBD-II as defined by the CARB0x02 00000010b OBD as defined by the EPA0x03 00000011b OBD ''and'' OBD-II0x04 00000100b OBD-I0x05 00000101b Not meant to comply with any OBD standard0x06 00000110b EOBD
Mode 3: (no PID required) A request for this mode returns information about the DTCs that have been set. The response will be an integer number of packets each containing 6 data bytes. Each trouble code requires 2 bytes to describe, so the number of packets returned will be the number of codes divided by three, rounded up. A trouble code can be decoded from each pair of data bytes. The first character in the trouble code is determined by the first two bits in the first byte:
A7 A6 First DTC character-- -- ------------------- 0 0 P 0 1 C 1 0 B 1 1 U
The second character in the DTC is a number defined by
A5 A4 Second DTC character-- -- -------------------- 0 0 0 0 1 1 1 0 2 1 1 3
The third character in the DTC is a number defined by
A3 A2 A1 A0 Third DTC character-- -- -- -- ------------------- 0 0 0 0 0 0 0 0 1 1 0 0 1 0 2 0 0 1 1 3 0 1 0 0 4 0 1 0 1 5 0 1 1 0 6 0 1 1 1 7 1 0 0 0 8 1 0 0 1 9
The fourth and fifth characters are defined in the same way as the third, but using bits B7..B4 and B3..B0. The resulting five-character code should look something like "U0158" and can be looked up in a table of OBD-II DTCs.