AUTO-230 · Lesson 10 of 12 · 20 min
OBD-II monitors and diagnostic trouble codes
Ines Moreau brings her hybrid back a month after its service with the check-engine lamp lit and a printout from a parts store that reads P0128, coolant thermostat, coolant temperature below thermostat regulating temperature. The parts store suggested a thermostat. Ines wants to know whether that is right, because the car has never overheated and the heater works. Marty uses the visit for a lesson he gives every apprentice. "A code is the computer telling you that one of its tests failed," he says. "Before you fix anything, you need to know what the test was, when it ran, and what it saw. That is what this whole system is for."
This lesson covers on-board diagnostics, second generation (OBD-II): what it requires, the monitors that test emission-related systems, how codes are stored and cleared, the structure of a diagnostic trouble code, and the scan tool data that support diagnosis, including freeze frame, pending and permanent codes, readiness status and on-board test results.
What OBD-II is
OBD-II is a set of requirements, first adopted in California and then by the US Environmental Protection Agency, that apply to all light-duty vehicles sold in the US from the 1996 model year. Canada adopted matching requirements for its vehicles, and since nearly all vehicles sold in Canada are built to the same specifications as US vehicles, OBD-II systems are effectively the same on both sides of the border. The rules require the engine computer to monitor every system and component that could make the vehicle's emissions exceed its standard by more than a set margin, typically 1.5 times the standard; to light a malfunction indicator lamp (MIL) when it finds one; to store a diagnostic trouble code and the conditions when it set; and to make all of that available through a standard connector and standard communication rules, so that any generic scan tool can read it. Before OBD-II, every manufacturer had its own connector, codes and tools.
The diagnostic link connector (DLC) is a 16-pin connector, usually under the dashboard near the steering column, defined by the standard SAE J1962. Pin 16 carries battery power, pins 4 and 5 are grounds, and pins 6 and 14 carry the high-speed CAN network that all vehicles have used for OBD communication since the 2008 model year; older vehicles used other protocols on other pins. The generic part of the system is organized into numbered services, often called modes: live data, freeze frame, stored codes, clearing codes, on-board test results, pending codes, vehicle information and permanent codes. Manufacturer-specific data, codes and tests go well beyond the generic ones, and a professional scan tool reads both.
Monitors
A monitor is a test the computer runs on an emission-related system. Continuous monitors run all the time the engine runs: the misfire monitor from Lesson 7, the fuel system monitor, which watches fuel trims for too-lean and too-rich faults as Lesson 5 described, and the comprehensive component monitor, which checks every sensor and actuator input and output for circuit faults and for readings that make sense. P0128 is a comprehensive component result: the computer models how fast the coolant should warm up, given the engine's load and the outside temperature, and sets the code if the coolant does not reach the thermostat's regulating temperature in time.
Non-continuous monitors run once per trip, when their enable conditions are met: the catalyst monitor, the evaporative system monitor, the oxygen sensor and oxygen sensor heater monitors, the EGR or variable valve timing monitor, the secondary air monitor where fitted, and on some vehicles the particulate filter and others. Each needs particular conditions, such as a warm engine, a steady speed, a fuel level range or a cold soak, and some depend on others having passed first; the catalyst monitor, for example, waits until the oxygen sensor monitors have run, because it relies on the sensors. A drive cycle is a sequence of driving conditions designed to run all of the monitors, and each manufacturer publishes its own.
How codes set, light the lamp and clear
When a monitor fails for the first time, the computer usually stores a pending code but does not light the lamp. If the same monitor fails again on the next trip in which it runs, the code becomes confirmed, also called stored or matured, the MIL comes on, and the computer saves a freeze frame: a snapshot of key data such as engine speed, load, coolant temperature, fuel trims, vehicle speed and fuel system status at the moment the fault was detected. This two-trip logic stops one unusual event from lighting the lamp. Some faults, such as a catalyst-damaging misfire, light the lamp on the first failure.
If the fault goes away and the monitor passes on three consecutive trips, the computer turns the MIL off but keeps the code in history; it erases it after about 40 warm-up cycles without the fault, a warm-up cycle meaning the coolant rose by a set amount and reached a set temperature. Clearing codes with a scan tool, or disconnecting the battery on many vehicles, turns off the lamp, erases freeze frame data and resets every monitor to not complete. Since 2010, vehicles also store permanent codes, which a scan tool cannot erase: a permanent code stays until the monitor that set it has run and passed, so clearing codes before an inspection does not hide a fault. That is why Ridgeline never clears a code before recording the freeze frame, and never tells a customer a fault is fixed until the monitor has passed.
# Life of a diagnostic trouble code (simplified two-trip logic)
trips = ["fail", "fail", "pass", "pass", "pass"]
state, mil, history = "none", False, []
passes = 0
for n, result in enumerate(trips, 1):
if result == "fail":
passes = 0
if state == "none":
state = "pending"
elif state == "pending":
state, mil = "confirmed", True
else:
passes += 1
if mil and passes >= 3:
mil = False
state = "history (MIL off, code kept until about 40 warm-up cycles)"
history.append((n, result, state, "MIL on" if mil else "MIL off"))
for n, r, s, m in history:
print(f"trip {n}: monitor {r:<4} -> {s}, {m}")trip 1: monitor fail -> pending, MIL off trip 2: monitor fail -> confirmed, MIL on trip 3: monitor pass -> confirmed, MIL on trip 4: monitor pass -> confirmed, MIL on trip 5: monitor pass -> history (MIL off, code kept until about 40 warm-up cycles), MIL off
Reading a trouble code
The standard SAE J2012 defines the structure of diagnostic trouble codes. Each code has a letter and four characters. The letter names the system: P for powertrain, B for body, C for chassis and U for network communication. The first digit after the letter says whether the code's meaning is set by the standard, 0 and, for powertrain, 2, or by the manufacturer, 1 and, for powertrain, partly 3. The next digit, in generic powertrain codes, names the subsystem: 1 and 2 for fuel and air metering, with 2 including injector circuits; 3 for ignition and misfire; 4 for auxiliary emission controls such as EGR, EVAP and the catalyst; 5 for vehicle speed, idle control and auxiliary inputs; 6 for the computer and its output circuits; and 7, 8 and 9 for the transmission. The last two digits identify the specific fault. Many manufacturers add a two-character failure type byte after the code, such as an open circuit or a signal stuck high, which narrows the fault further.
# Decode the structure of a powertrain trouble code (generic subsystem groups)
systems = {"P": "powertrain", "B": "body", "C": "chassis", "U": "network"}
groups = {"1": "fuel and air metering", "2": "fuel and air metering (injector circuits)",
"3": "ignition system or misfire", "4": "auxiliary emission controls",
"5": "vehicle speed, idle control and inputs", "6": "computer and output circuits",
"7": "transmission", "8": "transmission", "9": "transmission"}
def decode(code):
s, d1, d2 = code[0], code[1], code[2]
owner = "generic (standard)" if d1 in "02" else "manufacturer-specific"
text = f"{code}: {systems[s]}, {owner}"
if s == "P" and d1 in "02":
text += f", subsystem: {groups.get(d2, 'other')}"
return text
for c in ("P0171", "P0301", "P0420", "P0456", "P0128", "P1101", "U0121"):
print(decode(c))P0171: powertrain, generic (standard), subsystem: fuel and air metering P0301: powertrain, generic (standard), subsystem: ignition system or misfire P0420: powertrain, generic (standard), subsystem: auxiliary emission controls P0456: powertrain, generic (standard), subsystem: auxiliary emission controls P0128: powertrain, generic (standard), subsystem: fuel and air metering P1101: powertrain, manufacturer-specific U0121: network, generic (standard)
The data that support a code
A code is a starting point. Freeze frame data show the conditions when the fault was found, which tell the technician how to reproduce it: a lean code that set at idle with a cold engine calls for a different test from one that set at highway speed under load. Live data show the engine's current behavior. On-board test results, the service often called Mode 6, show the measured value, the minimum and maximum limits for each test the computer runs, even tests that have not failed; a catalyst test value close to its limit, or a misfire count creeping up on one cylinder, warns of a fault before the lamp comes on. The vehicle information service reports the vehicle identification number, the calibration identification of the engine computer's software and a calibration verification number that proves the software has not been altered, which inspection programs read.
Readiness status, or monitor status, shows which non-continuous monitors have completed since codes were last cleared. A fresh battery, a cleared code or a reprogrammed computer leaves monitors not ready until the vehicle has been driven through their conditions. Inspection programs look at readiness, as Lesson 11 explains, and a vehicle with too many incomplete monitors is turned away to be driven and tested again.
Ines's P0128
Kiran reads the freeze frame. The code set on a morning of 21 °F, after twenty minutes of driving at about 31 mph with the engine running only part of the time, as a hybrid does. Coolant temperature in the freeze frame is 142 °F. In live data on a cold start the next morning, with the hybrid system held in a service mode that keeps the engine running, coolant climbs steadily to 158 °F and then stalls there, rising only slowly while the radiator's lower hose, which should stay cool until the thermostat opens, warms up early. With an infrared thermometer, the lower hose is already at 113 °F when the engine reaches 149 °F. The thermostat is opening too early, or leaking, so the engine never reaches its regulating temperature of about 180 °F in cold weather, and the computer's model of warm-up flags it.
Marty points out why the code matters on a hybrid. A cool engine runs richer, its oil warms slowly and collects water and fuel, the cabin heater works less well, and the engine computer keeps the engine running longer to heat things, which costs fuel. The repair is a new thermostat of the correct temperature rating with a new seal, and the cooling system is filled and bled using the procedure for this car, which includes running the electric water pump with the scan tool. The next cold start reaches 185 °F and holds it. Kiran clears the code only after recording the freeze frame on the repair order, and she tells Ines that the permanent code will disappear on its own once the monitor has run and passed, probably within a day or two of normal driving. So the parts store was right this time. Marty's point, he says, is that now they know it was right.
Worked problem
Pending, confirmed or permanent?
A scan tool shows P0442 as pending, P0300 as confirmed with the MIL on, and P0300 as permanent. The technician repairs the misfire and clears the codes. What will the scan tool show immediately afterwards, and what still has to happen?
Show solution
- Clearing removes the pending and confirmed codes and turns off the MIL.
- The permanent P0300 stays until the misfire monitor runs and passes.
- Every non-continuous monitor is reset to not ready, including the EVAP monitor that found the small leak.
- The P0442 will return if the EVAP leak is still there, so it needs its own diagnosis.
Answer: Permanent P0300 remains until the misfire monitor passes; monitors show not ready; the EVAP pending code needs diagnosis, not clearing.
Common mistakes
MistakeClearing codes before recording freeze frame data.
InsteadRecord the freeze frame first; it shows the conditions to reproduce the fault.
MistakeTreating a code as a part number.
InsteadA code reports a failed test; find out what was tested and why it failed.
MistakeIgnoring pending codes because the MIL is off.
InsteadA pending code is an early warning from a failed monitor.
MistakeExpecting a cleared vehicle to pass an inspection right away.
InsteadMonitors must complete and permanent codes must clear first.
MistakeIgnoring Mode 6 because nothing has failed.
InsteadValues close to their limits warn of faults before they set codes.
Summary and key terms
- OBD-II requires monitoring of emission systems, a MIL, stored codes and standard access through the DLC.
- Continuous monitors run all the time; non-continuous monitors run once per trip when conditions allow.
- Most codes are pending after one failure and confirmed, with the MIL on, after a second.
- Freeze frame data record the conditions when a confirmed code set.
- Permanent codes cannot be cleared by a scan tool; they clear when the monitor passes.
- Under SAE J2012, the letter, the first digit and the subsystem digit tell what kind of fault a code describes.
- Readiness status shows which monitors have completed since codes were cleared.
- OBD-II
- The second generation of on-board diagnostics, required on light vehicles from the 1996 model year.
- Malfunction indicator lamp (MIL)
- The check-engine lamp that OBD-II lights for emission-related faults.
- Monitor
- A test the engine computer runs on an emission-related system or component.
- Pending code
- A code stored after a monitor fails once, before the MIL is lit.
- Freeze frame
- A snapshot of engine data stored when a confirmed code sets.
- Permanent code
- A code that only clears when its monitor runs and passes.
- Readiness status
- The record of which monitors have completed since codes were last cleared.
Practice problems
Work each problem on paper first, then reveal the answer to check.
What does the first digit 1 in P1101 tell you?
Show answer
The code's meaning is defined by the manufacturer, not the standard.
Which subsystem does a P03xx code belong to?
Show answer
The ignition system or misfire.
Why might a catalyst monitor not run even though the engine is warm?
Show answer
It may be waiting for the oxygen sensor monitors to complete or for its own enable conditions.
How many consecutive passing trips usually turn the MIL off for most faults?
Show answer
Three.
Lesson quiz · 5 questions
Score 60% or more to complete this lesson.
Create a free account to save your progress, take quizzes and earn a certificate.