Tag Archives: CAN

Log Graphs 1


Car: 2009 Impreza 2.0 Turbo Diesel, 110 kW / 148 hp / 150 PS, European domestic market, Euro 4 spec.

Important: Newer Boxer Diesel generations (Euro 5/6) may show different behaviour!

ECU firmware: patched ROM for unlimited logging, otherwise stock.
Protocol: SSM2 via CAN
More than 120 items had been logged, plenty of RAM variables (*) plus standard SSM2 items at roughly 170 ms interval.


I prepared two graph images plotting some interesting parameters, click picture for full resolution:

Image 1/2


Image 2/2


Additional details

… at specific time positions:

#1: State before active regeneration

Time @ ~ 33 ½ min
Cruise Control: active
Vehicle Speed*: 110 km/h
Engine Speed: 2300 rpm
Gear: 5
Coolant Temperature: 93 °C
Injections: 2 (pre + main)
Soot Accumulation Ratio: 64 %
DPF Pressure Difference: ~ 5 kPa
Exhaust Gas Temperature (EGT) Catalyst Inlet: 345 °C
EGT DPF Inlet: 370 °C
Intake Air Amount: 430 mg/cyl
Mass Air Flow: 33.8 g/s
Manifold Absolute Pressure (MAP)*: 126 kPa
Inlet Air Temperature: 25 °C
Manifold Air Temperature: 48 °C
Fuel Temperature: 58 °C
Throttle Opening Angle: 79 deg
EGR Valve Opening Angle: 38 deg
Final Oil Dilution Rate*: -1.9 mg/s (evaporation)
Oil Dilution Amount: 282.0 g (4.6 %)

#2: Soot 65%, preparing for DPF regeneration

@ 33 ¾ min
Soot Accumulation Ratio* reaches 65%, this triggers active regeneration preparations. Note: I am referring to the actual RAM value, diagnostic parameter may indicate 65% earlier due to rounding.
Apparently ECU now does 3 injections (pre + main + after) when power demand is high enough, no post injections yet

#3: Active Regen ON

@ 34:04; = 20 seconds after #2, DPF Regeneration Switch turns ON
EGR valve closes instantly, 0 deg
Manifold Air Temperature dropping
Boost Control opens VGT immediately, from 52 to 25%
Manifold Absolute Pressure* dropping
pilot-injection kicks in, 2 injections (pilot C + main)
post-injections begin to fade in but not active yet

#4: Post-Injections

@ 33 seconds after #2, post-injections A + B become operational (injection amount > 0)
oil dilution rising
EGTs climbing
Manifold Absolute Pressure*: 75 kPa (~ 25 below ambient), varying, stays below ambient most of the time during regen at low power demand
EGT Catalyst Inlet: 340 °C
EGT DPF Inlet: 320 °C
injections: 4 (pilot C + main + post A + post B)

#5: Coasting Fuel Cut-Off During Regen

Example @ 35:12
EGR valve opens instantaneously, 70 deg; EGR behaves rather digitally during regen – either fully closed (0 deg, for max EGT) or max opened (70 deg, less fresh air)
Throttle Opening Angle: rising up to 31 deg
injections: 0
Fuel Consumption*: 0 mm³/s
oil dilution going down slowly due to estimated evaporation
EGT Catalyst Inlet: decreases fast, EGT at DPF inlet (> 600 °C) follows with a delay
Engine Speed: gear change from 5th to 6th to reduce engine braking effect

#6: Idling with Active Regen ON

@ 45:30
Engine Speed: 800 rpm
Post A Injection Amount*: 0
Post B Injection Amount*: ~ 8 mm³/st
Apparently while idling the ECU prefers the 2nd post-injection (“B”), otherwise during driving it’s rather mixed
Final Oil Dilution Rate: ~ 20 mg/s (medium)
Boost Control: 25 % (VGT fully open)
Manifold Absolute Pressure*: 74 kPa
Throttle Opening Angle: 5.5 deg
EGR Valve Opening Angle: 0 deg
Intake Air Amount: 370 mg/cyl
Mass Air Flow: 9.8 g/s

#7: DPF Regeneration OFF

@ 46:15, decision is based on elapsed time from #2, achieved soot level does not matter (!)
DPF Regeneration SW had been ON for 12.2 minutes
all post-injections off
Oil Dilution Amount*: 299.6 g (4.9 %) = + 0.3 % during regeneration
EGR back to normal operation
Boost Control: 65 % instantly (max speed, spooling up turbo)
MAP rising
EGT Catalyst Inlet: 270 °C
EGT DPF Inlet: 490 °C

Mode 23 – Read Memory

According to some of my notes, Euro 5 diesel models, or cars that support Extended/Enhanced OBD-II in general, might support mode/service 23 for dumping ROM or RAM blocks:

Format is similar or same as ReadMemoryByAddress (23 hex) service specified UDS (Unified Diagnostic Services, ISO 14229) protocol:

"23 <Format> <Address[]> <Length[]>"

Several $23 formats can be supported, Euro 5 diesel:

  1. "23 14 A1 A2 A3 A4 L1"
  2. "23 24 A1 A2 A3 A4 L1 L2"

As you can guess, format byte e.g. 0x14 means:

  • 4 address bytes → uint32 big endian, encoded in low nibble of format byte
  • 1 length byte → uint8, encoded in high nibble of format


Stock firmware usually restrict available address ranges, allowing only partial dumps. ROM calibration data and RAM regions might work. Knowing how to reflash and reverse-engineer the logic, such restrictions can be patched and therefore eliminated.


Depends on actual implementation, (early) Euro 5 diesel ROM logic:

  • 0 < length ≤ 0x400 (dec 1024) bytes otherwise NRC 31
  • other formats or request message lengths yield NRC 13
NRC (hex) Description
13 Incorrect message length or invalid format
31 Request out of range


Euro 5 diesel (1.5 MiB ROM, SH7059 chip) example – dump beginning at ROM calibration data:

Start address = 0xC0000
Length (per request) = 0x40 = 64 bytes

"23 14 00 0C 00 00 40"
Positive response: "63 <XX XX XX ... total 64 payload bytes ... XX XX>"

"23 14 00 0C 00 40 40"

"23 14 00 0C 00 80 40"

"23 14 00 0C 00 C0 40"

"23 14 00 0C 01 00 40"

Anyone able to confirm that these mode 23 commands and formats are working?

Personal experience on many different control units: Maximizing length per request yields max transfer speed, however application algorithm must be able to handle NRC codes and react properly.

Diesel ECU Patch v2

Patched the CAN-handler responsible for the SSM2-Read-Addresses (A8) command. Now we’ve got high-speed full RAM access.
Euro4 stock ROMs prevent RAM access (0xFF**** addresses) via CAN (ISO15765 actually). Previously we had to resort to slow SSM2 via Serial protocol.

The static screenshot does not really tell the difference though. This Linux application can do both modes. Speed in comparison is like this: logging roughly 120 items using SSM2 via CAN updates all values fluently – no noticable delay. In serial mode, it takes multiple seconds for a single refresh – really major difference!

Planned: Implementing CAN block read command for even more performance e.g. quick RAM snapshots. Either command “A0” like SSM2 via Serial or Extended OBD-II mode 0x23 (stock Euro5 diesels have this), or both.

Electrical Power Steering

Normally power steering control unit only activates steering assist when engine is running.
Now we have found a way to activate this while keeping the diesel engine off, used method needs CAN software though.
This way one can listen to any steering noises that would otherwise be drowned out by the engine, useful for diagnostics. The electrical motor is pretty quiet but noticable at engine off.
Update: There’s also a harsh method – just stall the engine deliberately – power steering keeps ON till ignition off.

Coolant Temperature

Like all or most engine related sensors, coolant temperature is being digitised by ECU. There’s a 2-dimensional table to convert measured sensor voltage to temperature result inside ROM:

Calibration curve is typical for a NTC (Negative Temperature Coefficient) thermistor.
Moving on to combination meter, coolant temperature lights are driven by ECU CAN output, precisely CAN-ID 0x600 byte 3. That byte contains coolant temperature, conversion formula is “x-40 [°C]“.
There are no additional flags for the dashboard lights. Meaning combination meter computer parses coolant temperature from CAN frame and decides on its own.

EXACT conditions, confirmed by testing: 1

Light Coolant
Boxer Diesel combination meter light when coolant is cold. < 50 °C (122 °F)
≥ 112 °C (234 °F)

A possible way to change stock thresholds is to modify ECU ROM resulting in faked 0x600 coolant temperature value output. This has already been tested working. However, other control units then read wrong temperature, too, resulting in possible side effects – especially if the offset is significant.

Coolant temperature certainly has effect on:

  • A/C (can hear actuator move depending on temperature)
  • BIU (copies data onto low speed bus)
  • Combination Meter

Didn’t have time to investigate low-speed CAN bus and BIU (Body Integrated Unit) yet. In theory, BIU could transform data from high-speed (ECU, VDC/ABS etc.) to low-speed bus instead of just copying it. Anyone knows? BIU is the gateway, the only control unit connected to both CAN busses. Combination meter is on low speed bus for sure.

1) No hardware has been harmed, we’ve used CAN injection/simulation.

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).

New Diagnostic Protocol

Started documentation on page Extended OBD-II.
So far only Euro5 Boxer Diesel models support/need this.