Category Archives: Maintenance

Oil Dilution News

Through comparing a few ROMs recently I have noticed some significant changes regarding oil dilution.
So far it seems, this is about newer Euro 6 diesel ECU firmware only, meaning MY 2015+. Apparently, firmware containing modifications were created in May 2017, probably published since 2017-07.

The oil dilution ratio threshold to trigger DTC P1468 Oil Dilution is now 15 % instead of 10 %.

A couple of tables have been adjusted, for example “oil dilution evaporation” is now defined up to 15 % and a few DPF regeneration behaviour tweaks.
Also, the relationship between log items “Distance To Oil Change [km]” and “Oil Dilution Ratio [%]” is not linear anymore, rather nonlinear in fact.

Both graphs were created out of 2015/2016/2017 Outback Diesel CVT ROM data:

CID JB4K104B, ROM date 2017-05:

Older Euro 6 CID JB4K102B, ROM date 2016-10, and probably still applicable to all Euro 4/5 models:

I will update related pages in the near future.
For now, if you are affected, don’t use my custom “Oil Dilution 2” log item anymore.

If you like, you can use this simple formula instead, but it is only valid between 0 % and 8 %:
OilDilutionRatio3[%](DistanceToOilChange[km]) = 60-DistanceToOilChange/250

Example values:

13500 6.0
13400 6.4
13300 6.8
13200 7.2

Since diagnostic item “Distance to Oil Change” is scaled in [100 km], above formula provides oil dilution in 0.4 % steps. Accuracy has become worse but is still better than standard log item “Oil Dilution Ratio” which only provides integer resolution. Not sure if logging apps such as Torque can handle table lookup or piece-wise functions.


Injector Codes

Denso Injector DCRI107890 (Denso part# 095000-7890, Subaru part# 16613-AA020) for Euro 4 Subaru Diesel


Quote from a DENSO document incl. picture below:

Replacing a Diesel Common Rail Injector:
When replacing a DENSO Diesel Common Rail Injector, marked with a compensation code, it is necessary to register the ID code, printed on the upper part of the injector, with a genuine OEM – or DENSO diagnostic tool, into the electronic control unit (ECU). The injector compensation (ID) code is used to compensate injector production tolerances.
Some vehicles also require Small Injection Quantity Learning.

Denso Injector ID graphic

Subaru’s term for injector compensation or ID code is “injector code“. Dealership diagnostic software (SSM-III, SSM4) has menu items like “Injector Code Display” and “Injector Code New Registration (SSM to ECM)

First off, the engine control unit has no way of measuring actual injected fuel amount, such technology would be expensive for these kind of small fluid quantities. Due to high common rail pressure, even tiny production tolerances result in unwanted injection quantity variations. Obviously, each injector must be registered using its correct cylinder number so the ECU can apply individual adjustments when it is calculating injections. Basically, the ECU accomplishes desired (target) injection quantity by adjusting the duration of injector drive signal.

Since programmed injector codes as well as any other important data is being saved into an extra EEPROM chip, there is no risk of data loss having the car battery disconnected.

Consequences of Wrong or Missing Injector Codes

According to DENSO:

  • Knocking noise
  • Unstable idle
  • Wiggling during driving
  • MIL (Check Engine Lamp) on

Cylinder numbers – Quick Reference

As for a quick reminder, looking at the front of the car into engine bay, cylinder numbers are:

towards back
  3        4
  1        2
car front (radiator etc.)

Getting Injector Codes via QR Code

Although normally this should not be necessary, injector codes can be read from the actual injector parts even when mounted on the engine and inside the engine bay, therefore not easily accessible. Taking a picture using a mirror tool is relatively easy, no need to disassemble any parts:

Injector QR Cyl2 small

While the injector code label itself is hidden by the (white) electrical connector, its QR code is visible by default.
Make sure the QR code on the photo is as sharp as possible and has sufficient resolution. At the car I usually just try to get high quality pictures. Later on my computer I simply select the best pic, then scan QR info straight off the computer screen using a smartphone.

Using an image manipulation program (i.e. GIMP, PhotoShop) in order to improve the QR code area can result in much better QR detection. In my case, this was not needed as the app can also detect inverted QR (light code on dark background).
Android app tested: “Barcode Scanner” from F-Droid repository. Check settings → Invert scan.

As an example, the following pic is the extracted and improved QR code portion from above picture. I used these steps in GIMP: crop, perspective correction, grayscale, invert, brightness & contrast . You should be able to scan this:

Injector QR Cyl2 processedScanning captured QR code results in a line of text containing 49 characters:


First 19 chars:

  • First four chars 7890 match Denso basic part number.
  • AA020 is also found in Subaru part# 16613-AA020
  • Possibly contains production date 2008-09-11 ?
  • Serial# ?

Injector Code Format

Remaining 30 chars is the exact injector code needed for ECU. These chars must be in hexadecimal [0-9, A-F] form as they are transmitted as 15 bytes to and from the ECU:

Byte index [0..14] Content
0 const, sort of generation ID, verified by ECU:

  • Euro 4: B3
  • Euro 5: B2
  • Euro 6: B6
1..12 12 payload bytes containing correction data, type int8, for up to 12 pre-defined correction points. Each signed byte must be within range [-125, 125]. In other words, the following five bytes are not allowed: 7E, 7F, 80, 81, 82.
13 const 00
14 simple XOR checksum

Resultant properly formatted injector code (left to right, 4 chars per block):

B300    0000
0000    E9EB
EBEC    F300
0000    45


Invalid codes will be rejected! Euro 5+ will return NRC 0x31 (request out of range).
Injector code data is not compatible between common rail system generations due to differing correction points! Euro 4 uses fewer points (10) than E5+ (12). Therefore, for example, programming a Euro 5 injector code into Euro 4 ECU will not work and vice versa.


AFAIK, Denso’s own PC diagnostic software has the ability to read from a QR scanner device, Subaru OEM application SSM-III does not – need to type in codes manually.

Protocols needed for injector code display & registration:

  • Euro 4: SSM2 via Serial
  • Euro 5/6: Extended OBD-II

As far as we know, there is no free/open-source software for this yet.

EcuTek tool probably supports injector coding (up to Euro 5 ?).

Other Brands

Many other car brands are based on Denso diesel software. These often use similar 15 byte injector codes as well. However, injectors and pre-defined correction points usually differ!

Mazda CX-5 (SkyActiv-D 2.2)

Piezo injectors! 15 bytes; first byte: 3C; pressure levels and corrections points differ vs. Subaru.

Mazda terminology: fuel injector code programming, injector correction factors


  • 2017-05: additional notes and details
  • 2016-04-03: Euro 6

Oil Dilution Reset (K-Line, Euro4)

Applies to

Old Euro 4 models, model years (MY) 2009/2010, fitted with closed-type DPF, (therefore Impreza and Forester only?). This also means using SSM2 via Serial (K-Line) protocol, as SSM2 via CAN will not work for most maintenance operations on such old ECUs due to ROM software limitation.


After changing the engine oil, the ECU needs to be told in order to reset its oil dilution amount and ratio values – the ECU cannot detect the change by itself. By the way, Euro 4 engines do not even have an oil level switch/sensor. Also look at post Oil Dilution Graph describing ECU calculations.

By applying a little communication, dilution will be zeroed, also saved into the ECU’s EEPROM after ignition off. Otherwise this (estimated!) value might rise over time and trigger DPF light flashing having reached 10% ratio.

It seems there are still folks out there interested in this, changing oil by themselves, not at the dealership where mechanics use Subaru Select Monitor (SSM-III or newer SSM-IV) software.
I searched through some of my old notes and found the rather short and easy procedure.


Working K-Line connection to ECU. See page SSM2 via Serial.

C-style pseudo code

// only one single SSM2 address is needed
const int address = 0x27D;
byte b = Read(address);

if (b == 0xFF) { print("Probably unmanaged (closed-type) DPF, nothing to do."); exit; }

// set bit 6
Write(address, b | 0x40);

// Wait for some time (500 ms or so is more than enough for the ECU to do its work)

// clear bit 6
b = Read(address);
Write(address, b & ~0x40);

// verify, make sure bit 6 is zero again...
b = Read(address);

Almost done! Now turn ignition off so that new content gets saved into EEPROM! I also recommend waiting for about 20 seconds, then turn ignition back on in order to query oil dilution ratio [%] and/or oil dilution amount [g] parameter(s) to be sure. These values should be zero now. See post Why and when cycling ignition matters for explanation.

In RomRaider logger definitions (version 310) these parameters are called:

P193 Oil Dilution Ratio % Öl Verdünnung Verhältniss
P236 Cumulative oil diesel entry g Öl kum Dieseleintrag

SSM2 via K-Line communication example

SND = message from tester to ECU
RCV = received response from ECU

SND: 80 10 F0 05 A8 00 00 02 7D AC
RCV: 80 F0 10 02 E8 00 6A

SND: 80 10 F0 05 B8 00 02 7D 40 FC
RCV: 80 F0 10 00 F8 40 BA

SND: 80 10 F0 05 A8 00 00 02 7D AC
RCV: 80 F0 10 02 E8 40 AA

SND: 80 10 F0 05 B8 00 02 7D 00 BC
RCV: 80 F0 10 00 F8 00 7A

SND: 80 10 F0 05 A8 00 00 02 7D AC
RCV: 80 F0 10 02 E8 00 6A


It has been confirmed to be working, using RomRaider‘s built-in Test tool (menu: Tools → Launch Test App…). Since the sequence of individual commands is not time critical, it can be done by sending SSM2 messages manually one after the other. See this RomRaider Forums thread.


Wikipedia: Diagnostic Trouble Code (DTC)
All following DTCs are Subaru specific, applicable to closed-type DPF Boxer Diesel models only, Euro 4, 5, 6 emission standards.
Some of these DPF related DTCs trigger DPF light flashing.

ID Name Comment
P1465 DPF Particulate Overfill
P1466 DPF Substrate Damaged (E4: never gets set?)
P1467, P242F DPF Ash Overfill ≥ 100 %
P1468 Oil Dilution ≥ 10 % ; also see Distance to Oil Change
P1469, P246C DPF Limp-Home Mode Reduces injection quantity and power.
P1471 DPF Pressure Difference Sensor Upstream Piping Trouble (E4: never gets set?)
P1472, P2454 DPF Pressure Difference Sensor (Low)
P1473, P2455 DPF Pressure Difference Sensor (High)
P147B Catalytic Converter and DPF
P2453 Particulate Filter Pressure Sensor “A” Circuit Range/Performance

Related ROM code has not been analyzed completely yet, no guarantees as usual. It is definitely much more sophisticated compared to Subaru petrol ROMs.


  • 2016-10 Added DPF related Euro 6 DTCs.

Injector Learning / Calibration

Applies to all known Boxer Diesel models, Euro 4/5/6.
Injector learning (micro quantity calibration) procedure is supposed to improve injection accuracy of small injections, improving vibrations, noise, fuel economy etc. The ECU measures engine speed changes, derives learning values and uses them from there on.

Tiny fuel injections, achieved through very short pulses, are especially sensitive to mechanical wear inside injectors. Remember, the ECU does not know how much fuel is actually being sprayed into the cylinders. However, by measuring acceleration (crankshaft speed changes) after at each cylinder’s power stroke, it can adjust injection pulses to achieve a balance across cylinders.

Normally, a power stroke consists of two or three individual injections, main injection always being the largest one. For micro quantity calibration, the software does things differently. It divides the necessary fuel to hold engine speed into more and evenly small injections so that only short pulses matter and differences in injected amounts can be compensated.
The entire procedure is done in two ways:

  1. Automatically by ECU when idling (~800 rpm), for example at traffic light stop. There’s a delay of 5 seconds (stock calibration) till commencement. Then the actual process takes roughly a minute to complete. In this auto-mode the software only goes through first 4 pressure levels. ECU will try again later if it could not finish.
  2. Compulsory using Subaru dealer software (open source solution is planned). In addition to auto-mode, it uses higher common rail pressure, revving the engine up to 1,200 rpm at 5th pressure level which is not acceptable in auto-mode.

Injector Learning Chart

Either way, the operation causes distinct engine sound due to special injection patterns, easy to recognize. Also altering common rail pressure to the next pressure level causes noise to change.

You can use logging (Subaru specific protocols) in order to monitor related parameters:

  • injector learning status (ON/OFF)
  • injection quantity learning values [ms] (4 cylinders times 5 pressure levels = 20 values; all zeroes means learning has not been completed successfully)
  • mileage after last learning [km]
  • mileage after injector replacement [km]

As usual, all relevant values are being saved into EEPROM.

Automatic Injector Learning Intervals

In theory, ECU wants to do automatic injector learning at these predefined intervals:

# Odometer
1 50 50
2 200 150
3 350 150
4 950 600
5 1,550 600
6 4,550 3,000
7 7,550 3,000

Confirmed by disassembly from Euro 4/5/6 software. As you can see, the interval is being increased up to 3,000 km.

Above odometer values are theoretical because:

  • For the ECU mileage after last learning matters, not any absolute odometer value.
  • If conditions are not met, learning process is being delayed, trying again at next occasion, increasing all further odometer numbers.
  • ECU internal odometer is not very precise, it will drift off from combination meter odometer over time.

Injector Learning Conditions

Basically, engine must be warm, around 80°C coolant temperature. Lots of parameters must be within pre-defined ranges (fuel temperature, accelerator not depressed, battery voltage 12..15 Volts, …).

Video Links

Courtesy of contributors posting their videos.

Automatic learning



  • Adjusting internal variable “mileage after last learning”, i.e. setting to 3000+ km triggers automatic calibration ASAP.
  • Adjusting ECU odometer, i.e. to re-synchronize with dashboard value.

Other Brands

Many other car brands are based on Denso diesel software.

Mazda SkyActiv-D 2.2 (CX-5)

  • Piezo injectors!
  • 20x “Fuel injection learning value …” [µs] (FI_LRN_{pressure level, cyl}) monitoring PIDs.
Automatic learning

3 pressure levels (350, 650, 950 bar = 5080, 9430, 13780 psi)
Learning interval up to 2,000 km.

Compulsory learning

2 additional pressure levels (1400, 1970 bar = 20310, 28570 psi), at increased engine speed.

Engine Oil Change (DPF models)

Owners want to be able to change oil by themselves obviously.
On closed-type DPF models (all except MY 2008/2009 Legacy/Outback which are mated with open-type DPF) you’ll need to reset oil dilution parameter as it is calculated (not measured!) by the ECU. Basically active DPF regenerations in particular cause diesel fuel bypass into engine oil. Piston rings cannot seal perfectly.

No auto-detection! Since Subaru diesels, unlike Mazda for example, are not equipped with an oil pressure sensor, its software cannot detect an oil change nor deteriorated engine oil. Subaru’s simple on/off oil pressure switch (near oil filter) is connected to the dashboard. There’s also a low/high oil level switch available on Euro 5/6 models which won’t help here, too, although this one is evaluated by complex ECU algorithm.

Following info as seen in all managed-DPF-ROMs so far.

DTC P1468 Oil dilution (MIL remains off) is being triggered when oil dilution ratio ≥ 10 %. Results in DPF light flashing , there is no warning in advance! If oil dilution gets below 10 % (estimated evaporation) the light will also turn off.

The engine management software assumes 6.13 kg oil mass and this maintenance operation resets RAM variable “Oil Dilution Amount [kg]” to zero.
The ROM’s internal calculation steps are:

  1. update OilDilutionAmount [kg] according to CoolantTemp, Injection Quantities etc.
  2. OilDilutionRatio [%] = 100 * OilDilutionAmount [kg] / 6.13 [kg]
  3. EstimatedDistanceToOilChange [km], via LUT

Also see posts Estimated Distance to Oil Change as well as Oil Dilution Graph.

Oil Dilution Reset

We’ve traced related Euro 4/5/6 ECU-ROM machine code. Here are all possible options:

Euro 4 (IV)

  1. Diagnostic protocol (SSM2 via Serial only). See post Oil Dilution Reset (K-Line, Euro4). There is no alternative method on Euro 4 models! (In theory, we could patch Euro 4 ROMs adding the same Euro 5/6 manual procedure as below. Not a trivial task, though, talk about hours of development and testing…)

Euro 5 (V), Euro 6 (VI)

  1. Diagnostic protocol (Extended OBD-II only since advanced stuff is not implemented in SSM2 anymore unlike Euro 4)
  2. Manual procedure, should be printed in the owner’s manual. The following table is derived from actual ECU software, confirmed in Euro 5 gen2/gen3 and Euro 6 ROMs:
    Step Description
    Prerequisites Brake Light
    • Whole procedure must be done while parking.
    • Engine must be running.
    • Parking brake recommended, vehicle speed must be zero all the time.
    1 Depress and keep holding brake pedal. (Slight pressure is sufficient).
    2 (Rear) defogger ON
    3 Lights ON (stage 1 = parking/clearance/DRL lights is sufficient)
    From here you only have 4 seconds to accomplish each of the following steps and roughly half a minute total countdown!
    4 Defogger OFF
    5 Lights OFF
    6 Defogger ON (again)
    7 Lights ON (again)
    8 Defogger OFF
    9 Lights OFF
    10 Release brake pedal.
    Now the glow light (depicting yellow coil) will flash for 5 seconds indicating full success.
    Otherwise wait for half a minute at least, then try again, repeating the whole procedure.

    Many users have confirmed this procedure, e.g. Subaru Forester Owners Forum – Oil change on Diesel engine and ECU service reset.

    Wanted – please contribute:

    • dashboard video to confirm glow light flashing modes
    • picture of car owner’s manual page describing reset procedure

Other Brands

Mazda SkyActiv-D 2.2 (CX-5)

“Engine Oil Data Reset”, either via OBD or manual procedure (test terminal & accelerator pedal).

ECU software contains algorithms that can detect deteriorated engine oil via oil pressure sensor, there are several DTCs.

Estimated Distance to Oil Change

Estimated distance to oil change is directly driven by oil dilution ratio. Confirmed in all Boxer Diesel ROMs so far, Euro 4/5/6 spec. (Exception: does not apply to open-style DPF – earliest Euro 4 models).

The term “distance to oil change” is actually misleading. Normally, some time after oil change + reset, oil dilution ration often settles somewhere between 4 and 6% (Euro 4), the lower the better. Do not confuse this with distance till next maintenance! Do consult car manual instead or ask dealership.

The firmware uses a 2D LUT (two dimensional lookup table) and standard interpolation:

ScoobyRom screenshot portion

ScoobyRom screenshot portion

However this x-y table data makes up this perfectly linear relationship:

DistanceToOilChange[km] = 15000 - 1500 * OilDilutionRatio[%]

Distance to oil change cannot get negative because interpolation subroutines don’t extrapolate.

Note that the logging parameter Oil Dilution Ratio [%] (SSM2 0x00027C, x[%]) cannot provide decimal places, as it is a simple integer value without conversion.
Original RAM value however is a 32-bit floating point variable so if you are able to log RAM (advanced, specific ECU ROM definitions required!) you can spot slight changes.

Another and rather easy option is to log parameter Estimated Distance to Oil Change (SSM2 0x00029A, x*100 [km]) and reverse-calculate oil dilution ratio:

10-x/15 [%]

This will provide better oil dilution precision, roughly one decimal place.

Note: Maximum result value is 10 % since underlying value cannot get negative. Use standard oil dilution parameter if you get close to and above 10 %.

Add this to RomRaider logger definitions:

<parameter id="P300" name="Oil Dilution 2" desc="Reverse-calculated from Estimated Distance to Oil Change to get better precision." ecubyteindex="72" ecubit="4" target="1">
    <conversion units="%" expr="10-x/15" format="0.00" gauge_min="0" gauge_max="15" gauge_step="1" />

For newer models that use the new diagnostic protocol, look here: Extended OBD-II

Of course both oil dilution ratio and distance to oil change should be considered rough estimations. So far all Subaru control units cannot measure dilution, there is no suitable sensor attached. Such dilution sensors do exist but add costs, especially development and (reliability) testing. As a result of missing sensor, the ECU must be told to reset oil dilution value when engine oil has been replaced – see Engine Oil Change (DPF models).

10 % oil dilution is critical where ECU will flash DPF light, also stores DTC P1468 Oil Dilution.

We know the oil dilution algorithm in detail and are able to debug issues. Basically, oil dilution gets to increase while active DPF regeneration is being performed. Otherwise it will drop (very) slowly as the ECU estimates oil evaporation. As you might expect, evaporation rate depends on (coolant) temperature, the higher the better. See post Oil Dilution Graph for more details.

Articles regarding oil dilution:


  • 2016-10: confirmed that this also applies to Euro 6 spec
  • 2016-05: added logger.xml snippet