Category Archives: Euro6

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

Fuel Consumption

Consumption Display Correction

It is the ECU software that estimates fuel consumption as it calculates all individual injections (multiple per stroke) anyway. Based on injection quantity demand it will calculate injector drive time, taking conditions like rail pressure and fuel temperature into account. It cannot measure fuel flow directly as this would require expensive equipment – tracking fuel flow + return flow accurately, all temperature compensated.
In reality most drivers notice some trip computer offset vs. actual consumption calculated at gas station fill-up. Usually the displayed value is too optimistic. The offset may depend on driving conditions and fuel quality. Often enough it is roughly constant for an individual driver so it is still useful information.

We offer fuel consumption display correction by patching ECU software.
Simple solution is to derive a constant factor.

E.g. indicated 6.6 litre/100km vs. 7.0 actual → correction factor = 7.0 / 6.6 = 106.1 %.
After modifying and reprogramming ECU ROM, fuel consumption CAN value (ECU output, [mm³/s]) will be adjusted accordingly, to be picked up by combination meter computer. This one calculates all trip values, finally sends display control commands to center display over serial connection.

Injecting complex ECU subroutine f(torque, temp, rpm, …) and/or table data is also possible, requires measurement data in the first place, though.

DPF Active Regeneration

As you may have noticed, active DPF regeneration has a big impact on instant fuel consumption. All injection parts are included in CAN consumption value, therefore post-injections are noticeable in center display when it is set to current consumption mode.
Collected CAN data showed ~300 % actual fuel consumption at idle when active regeneration is in progress, mainly due to post-injections and intake air throttling in order to heat up the DPF, compared to normal idling with regeneration off.

Idling at 800 rpm, coolant temperature ~90°C both times:

Item Unit Normal Active Regeneration
Injection Amount mm³/st 3.3 12 1
Fuel Consumption mm³/s 88 319
cm³/s 0.088 0.319
litre/h 0.32 1.15

1) Calculated from CAN value, SSM2 item “Final Injection Amount” would indicate 4.0 mm³/st (!). Logged data suggests this SSM2 parameter matches CAN consumption value as long as post-injections are not occurring (DPF active regeneration). To get fuel consumption, best way is to parse the CAN fuel flow value instead.


Other Brands

Mazda CX-5 (SkyActiv-D 2.2)

Fuel consumption algorithm and correction works similarly.

Fuel Level


On Euro 4 and early EU 5 (MY till including 2011) diesel models fuel level is being measured by BIU and transmitted on CAN-bus as resistance value in ohms (Ω). The ECU parses this and does some processing. First it calculates artificial fuel level voltage using standard voltage divider formula. Voltage value is being damped because the level information fluctuates a lot with fluid moving. Then the damped result is being used for LUT (Lookup table).

Euro 5 gen3 and EU 6, = MY 2012+: Fuel level is being digitized by combination meter. ECU ROM does more sophisticated damping/averaging.


Did some math, using exact ROM table data (ScoobyRom, export as CSV), applying formulas, creating plots.

For above voltage divider, where:

  • Vin: Battery Voltage (assumed constant in this case)
  • R1: constant series resistor
  • R2: variable fuel level resistance (two sensors in series, one per tank half)
  • Vout: fuel level voltage (artificial ECU value in this case)

This way I eliminated ECU’s artificial fuel level voltage, creating direct relationship between resistance [Ω] (CAN value) and volume [litre].

ROM Tables and Calculated Results

gen1 Euro 4 (MY 2008-2010)

Fuel tank capacity: 64 litres.

Fuel Tank Level, 2D table, Euro 4, ScoobyRom screenshot

gen2 Euro 5 (MY 2010-2011)

Fuel tank capacity: 65 litres.

Fuel Tank Level, 2D table, gen2 Euro 5, ScoobyRom screenshot

gen3 Euro 5 (MY 2012-2014) and gen4 Euro 6 (MY 2015+)

Fuel tank capacity: 60 litres.

There seems to be a calibration data error as the vertical step (at 19 ↔ 23 litres) does not make sense! ECU’s LUT code can handle this but technically it is a flaw. The averaging algorithm after table lookup will mitigate this issue. Same map data was found in newer Euro 5 and Euro 6 ROMs.

Fuel Tank Level, 2D table, Euro 6, ScoobyRom screenshot

Diagnostic Trouble Codes

DTCs are triggered when (artificial) fuel level voltage is outside range. As usual it’s not that simple, many conditions may affect this, too – battery voltage, CAN state etc.

  • P0462 Fuel Level Sensor Circuit (Low Input)
  • P0463 Fuel Level Sensor Circuit (High Input)

For some reason, above codes are not publicly exposed in Euro 6 spec models, also not available in service manual DTC listing. They are processed internally however.

Fuel Gauge

Fuel gauge and fuel warning light, Subaru Impreza diesel Euro 4. At depicted position, there are still 5 to 10 litres left in the tank.

I tested the fuel gauge by inserting a variable resistor after disconnecting a fuel level sensor connector from the wiring harness, below the rear seats. The Euro 4 fuel gauge at least reacts very slowly. It takes more than 20 seconds from empty to full and vice versa. The combination meter does its own damping obviously. Therefore, gauge hijacking, i.e. abusing the fuel gauge in order to display something fluctuating like manifold air pressure (MAP) is not feasible (without hacking combination meter ROM, of course).


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.

DPF Light


  • Do consult your car manual! Unfortunately owner’s manuals lack useful details.
  • Please also read our DPF management page.
  • Same DPF light logic in Euro 4/5/6 ROMs.
  • DTC numbers differ across boxer diesel generations.

Applies To

All Boxer Diesel models fitted with closed-type Diesel Particulate Filter (managed DPF), emissions spec Euro 4, 5, 6.

Therefore does NOT apply to early diesel models equipped with open-type DPF (MY 2008/2009 Legacy/Outback). These do not have DPF management at all in software, no sensors, no DPF light, a lot less to worry about!


Constant light means “Soot High Warning“, also called “Vehicle Speed Request“.

According to manual, one should drive for at least 15 minutes at 60+ km/h, providing favorable conditions (exhaust gas temperature high enough) for active DPF regeneration to start (and ideally complete) in order to reduce soot.

Steady light is triggered by single condition:

  • Soot Accumulation Ratio > 85%

According to ROM logic, steady light will turn off when soot drops below 75% (hysteresis).

If there’s any error condition, see below, the error has higher priority, always resulting in flashing mode.


Flashing/blinking means “Error“, any of the four possible conditions can trigger this mode right away – without showing steady light before.
The manual usually states something like: go to Subaru dealership for inspection. Waiting too long might worsen the issue! Mileage driven with light ON can be recorded by ECU and read out with software!

  1. Oil Dilution Ratio ≥ 10% (also sets DTC P1468 Oil Dilution). Remember, as dilution is just a rough estimate, the value and therefore this error can easily be false! Might disappear when dilution drops below threshold due to calculated evaporation, see post Oil Dilution Graph. Dealership might have forgotten to reset oil dilution at oil change – seen this many times on forums.
  2. Compulsory regeneration required, also called “Dealer Visit Request“; e.g. Soot Accumulation ≥ 100%; ECU does not try active regen anymore unless soot drops to normal level
  3. Ash Accumulation Ratio ≥ 100% (also sets DTC Ash Overfill). Need to clean or replace DPF and tell the ECU to reset this value.
  4. DPF Limp-Home Mode (also sets DTC DPF Limp-Home Mode).

DPF Light Control

At ignition ON, the DPF light illuminates for two seconds exactly – light test –  and should stay off afterwards, indicating normal condition. Otherwise see above.

On Impreza Euro 4 / 5, ECU operates DPF light using CAN message 0x600 byte 0 bit 1, bit = 1 means light ON.

Euro 6 just seems to use different CAN IDs and frame contents.

Like we did in above GIF animation, flash rate is 400 ms/400 ms on/off (8/8 CAN messages at 50 ms interval), respectively. There are no other stock flash modes. In the future we’d like to use DPF light for additional purposes e.g. indicating active regeneration by implementing a different flash rate. We already did a patch using DPF light to indicate active regeneration: Diesel ECU Patch v1. For source code see post DPF Light Patch.


  • 2016-10 incorporate Euro 6 findings


Tachometer driven by custom software, engine off, for demo purpose. Needle is at maximum position.

Tachometer redline range is 4,700 – 5,500 rpm. All related subroutines are well known by now. Same source code in all diesel ROMs it seems.

Within normal driving conditions the ECU won’t allow any over-rev because it gradually reduces injected fuel (zero at 4,800 rpm ?). This way over-rev can only be reached by force (mis-shift or faults).

Over-Rev Counters

There are two over-rev counters, triggered by two different RPM levels. Both are considered important therefore saved into EEPROM.

Item Unit MY08 MY09 MY10 MY11
High RPM: Repeated incidents might damage engine.
High RPM Threshold rpm 5,500
High RPM Hysteresis Low rpm 5,250 4,900
Very high RPM: Might damage engine on single occasion.
Very High RPM Threshold rpm 5,900
Very High RPM Hysteresis Low rpm 5,650 4,900

RPM must drop below hysteresis low value to allow next incident to be triggered. Prevents multiple counter increments on single incident.

Reaching five recorded “high” or a single “very high” incident might also turn on MIL.

DTC P0219 Engine Overrunning Failure

Triggered by condition: RPM ≥ 5,150. Confirmed with all models so far, Euro 4/5/6. Also causes freeze frame(s) capture.

High RPM History

Diesel specific, basically meant to acquire additional info. Subaru’s warranty department will probably look at this.

Although diagnostic software lists names like “Highest Over-Rev RPM history”, these actually start tracking within redline already (allowed but to be avoided), obviously don’t mean real over-revs when rpm < 5,500.

Only when above DTC P0219 has been triggered, the high-RPM-history management subroutine activates, tracking highest RPM it sees during incident. Later when DTC condition is not set anymore (=RPM dropped below 4,900) it updates its records, filling in highest engine speed it had seen plus current odometer value.

There are four records: highest and last three incidents.

Each record consists of two parameters and can be retrieved using a Subaru specific protocol:

  1. RPM, UInt8: x*20+4000 [rpm] → lowest possible value is 4,000 meaning NO incident yet!
  2. Odometer1, UInt16: x*5 [km]

Since history subroutine is separated from DTC checking subroutine and both use current RPM as input, it’s possible that when history sub gets to run, the RPM had already dropped < 5,150. So even though history needs the 5,150 rpm DTC threshold, remembered RPM values can be slightly lower, already seen that in practice.

1) It is actually the ECUs internal odometer, does not have to match dashboard odometer driven by combination meter computer! Usually these two odometer values drift off over time, typically 1% or more. Accessing Subaru diesel ECU odometer usually requires ROM specific software knowledge as there is no diagnostic protocol parameter implemented for this.