Category Archives: SSM2

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


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.

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.

SSM2 Benchmark v2

Ran the old SSM2 benchmark code on a Euro4 diesel ECU again. This time I included 10,400 baud mode as our library already supports this. (We do CAN/ISO15765 high speed mostly so serial stuff is low priority, no continous mode aka “fast poll” support yet.)

Interface device: Tactrix Openport 2.0, drivers installed by EcuFlash 1.43.3252 Beta (2011-04-10).
Same single SSM2 A8 request message as in 2010-Nov test.

Protocol Baudrate [bit/s] Count Samplerate [1/s] P1_MAX [J2534 value] P1_MAX [ms]
SSM2 via Serial 4,800 313 5.22 61 3
313 5.22 40 20
248 4.13 200 100
10,400 338 5.63 81 4
338 5.63 40 20
264 4.40 200 100
SSM2 via CAN 500,000 6001 100.02

1) Tested lowest value to get stable fully correct receive messages.

According to this result, 10,400 baud mode is hardly worth the effort, just 108% speed. Theoretically it should be roughly twice as fast vs. 4,800 baud.

My guess is, the ECU software has not really been designed for higher serial speeds. Not sure why the switch method exists, could be leftover code. It is not uncommon for dead code getting included in software builds. As far as the ECU’s CPU is concerned, serial communication involves more code and overall complexity than CAN. Subroutines responsible for transmitting serial bytes might not be called at a frequent enough interval to cope with higher speeds. I’ve also had to increase P1_MAX (J2534 spec inter-byte timeout) in order to receive correct responses at all times.

There’s a very slight CAN speed improvement compared to 2010-Nov test result. Probably due to J2534 driver improvements.

SSM2 via Serial at 10400 Baud

Standard SSM2 via serial protocol uses 4800 baud = bits/second on “K-Line”, OBD-II Connection pin# 7.

Some (rather recent model year it seems) ECU stock ROM software, both diesel and petrol, support switching to 10400 baud. Btw, 10400 is speed of ISO 14230 (alias KWP 2000) protocol, needed for BIU and several other control units.
It’s relatively easy to do, starting in standard 4800 baud mode, which is the default mode after ignition ON:

Write exact byte 0x5A into SSM2 address 0x000198 in order to switch to 10400 baud (default content is 00 = standard 4800 mode):
W 80 10 F0 05 B8 00 01 98 5A 30
R 80 F0 10 02 F8 5A D4

Ok, above positive response is the last message to receive using 4800 baud. At this point, all further SSM2 commands will fail (no response) because ECU can only understand 10400 baud.
Set interface device to 10400 baud, all other settings as usual, SSM2 is working again, most important commands at least.
Note: In this mode you have to use tester device ID 0xF2 instead of 0xF0! Everything else, including reported data, is the same it seems.

SSM2 Init:
W 80 10 F2 01 BF 42
R 80 F2 10 69 FF A2 10 14 ...

Read single byte, requesting that SSM2 0x000198 byte set above for example:
W 80 10 F2 05 A8 00 00 01 98 C8
R 80 F2 10 02 E8 5A C6
→ 5A, as set before

Read some standard addresses for sampling:
W 80 10 F2 11 A8 00 00 00 08 00 00 0D 00 00 0E 00 00 0F 00 00 10 7D
R 80 F2 10 06 E8 67 62 00 00 00 39
→ coolant temp = 63°C, MAP =98 kPa, engine speed = 0 rpm, vehicle speed = 0 km/h

Block read from address 0xFFB00, length 5. Btw, reflash counter bytes on 1 MiB ROMs live there, word + negated word at 0xFFB00.
W 80 10 F2 06 A0 00 0F FB 00 04 36
R 80 F2 10 06 E0 00 03 FF FC FF 65
→ reflash counter = 3

Write-Single-B8 command does not seem to work, blocked by ROM code! Looks like this mode isn’t gonna meant for maintenance, just faster logging. Don’t know a way to set baudrate back to 4800, except ignition OFF + ON, yet. Also, sending zero byte(s), like turning off continous mode, did not do it for me.
W 80 10 F2 05 B8 00 01 98 00 D8
(no response)

Continous push mode (RomRaider “Fast Poll“) is working, too! Tested working for both read single A8 and read block A0 commands.
So 10400 baud + continous mode should yield even higher sample rates – if someone (RomRaider ?) hacks this stuff into software… Not much fun without proper software support.
Did not do benchmarks yet. Theoretically 10400 vs. 4800 baud might yield factor 2.167 speed improvement.

Still not fast enough and cannot use CAN?
As stock ROMs can be patched, the code that actually does the baudrate settings can be modified. We might test that in the future, e.g. 31250 bits/s or even higher might still work reliably. Thanks to this additional mode, we can try changing that one and leave standard mode intact so any diagnostic software keeps working. Don’t know of any software using SSM2 at 10400 baud. All knowledge about this is derived straight from ROM.

Manual Serial Connection Tutorial


Describes how to use free open source Drew Tech Tool for J2534 in order to setup a SSM2 via Serial connection to the engine control unit (ECU). Diesel or petrol ECU model does not matter. Once set up, one can send and receive messages without any additional software, no programming skills necessary.

IMPORTANT: Interface hardware that comes with J2534 driver is required!
Unfortunately, many cheap devices don’t come with J2534 drivers.

I am using Tactrix OpenPort 2.0 in this example.

Drew Technologies has good infos regarding J2534 on their site:


Drew Tech Tool Software installation

Basically it is a generic tool, uses J2534 API under the hood, supports many protocols.

In category “SUPPORT APPLICATIONS” look for “J2534-1 Bus Analysis Tool” (not sure why they chose this link text), download and install Windows installer file:
Drew Technologies Tool for J2534-1 API v1.07.msi (9 MB)
License is GPLv2+, besides executable binaries the msi also includes Visual Basic source code.

Step 1: Select Device, Open

Tab “Connect”, top left frame.
Note: If you see text like “No information found in the registry” and buttons are disabled, close the app and use “Run as administrator” method!
Select desired hardware interface, should be recognized if your J2534-device had been installed correctly.
Path to DLL is just for info, lists the J2534 driver DLL location.
Click button “Load DLL”

Top right frame. Click button “Open” (API call PassThruOpen)

After “Open” the tool automatically does a PassThruReadVersion to retrieve version information, displays the results in bottom left frame.

Step 2: Protocol Properties

Bottom right frame.

Select ISO9141, ISO14230 would also work, they use the same physical layer (K-Line, OBDII pin 7).
Check baudrate and connect flags. Screenshot shows needed values which are defaults.
We need 4,800 baud which is Subaru SSM2 specific.
Connect Flags, right click for helper dialog.

Setting flag ISO9141_NO_CHECKSUM is important (0x200, bit 9). Since SSM2 is not a standard protocol, we have to turn off automatic checksumming by the device.

ISO9141_K_LINE_ONLY (0x1000, bit 12) can also be set, it’s not required though. I have tested Connect Flags 0x200 and 0x1200 working.

Click button “Connect” (PassThruConnect).
By the way, the statusbar shows latest command result, should be OK. You can also look into tab “Results” which displays a full log of all commands done so far.

Step 3: Config

Tab “Config”. Entries show current settings, the tool has already requested this info (PassThruIoctl GET_CONFIG).
Not important, but I usually work with LOOPBACK=OFF, don’t want to receive loopback messages from the interface device, I know what data I have sent anyway. Might be useful for debugging in case of troubles though.
Click button “Set”
Tool does PassThruIoctl SET_CONFIG, then GET_CONFIG to display actual values.

Step 4: Filters

Tab “Filters”.
Very important – without a filter set up you won’t receive any response, the device would ignore anything received from the control unit.
Fasted way is clicking button Create “Pass All” Filter which fills in the needed data automatically.

Mask: 00
Pattern: 00
Filter: Pass

This filter instructs the interface device to let all incoming messages pass through. Without a pass filter, J2534 specs require blocking everything by default.

Don’t forget to click “Apply”, to acually set the filter (PassThruStartMsgFilter).

Step 5: Messages

Tab “Messages”. Now that everything has been set up we can try to communicate with the control unit.
Top right button column.
“Rate” entry: Specifies delay time in milliseconds for automatic read-message (PassThruReadMsgs) polling. Since we type and send messages manually, fast polling makes no sense. I recommend 1000 = 1 second or more. Otherwise the log in tab “Results” will grow fast, making it harder to use.
Click “Start” (toggles to “Stop”) button to run or stop the automatic read loop. Must be started in order to display received messages. Can be started later, the interface device will store (a limited amount of) incoming messages anyway.

Message content

Scratch Pad entry: type message to be sent as hex bytes in here.
IMPORTANT: You must provide valid checksum (last byte) or ECU won’t respond!

Tx flags: None (0)

Once ready, click button “Send” (PassThruWriteMsgs). On Openport 2.0 device there should be green (send) and red LEDs (receive) flashing shortly.

SSM2 via Serial examples

For protocol details see page SSM2 via Serial.
SSM2Init-Request to ECU usually is: 80 10 F0 01 BF 40
SSM2Init-Request to TCU usually is: 80 18 F0 01 BF 48

SSM2-Init response from a diesel ECU:

Step 6: Disconnect protocol

Tab “Connect”
Bottom right frame, click button “Disconnect” (PassThruDisconnect, current channel). You could set up a new/different protocol.

Step 7: Close connection

Tab “Connect”
Inside top right frame, press button “Close” (PassThruClose). PassThruClose also disconnects all open channels in case you did not do this already. Now you can quit the application or select a different J2534-device and start all over.

Stand-alone logging v2

Tactrix OpenPort 2.0 only!

Updated 2010-04-23: added important switch “DPF_Active_Regeneration”
Updated 2010-04-19: slight logcfg.txt cleanup

Here’s a simple config file for stand-alone logging, designed for diesel models. Pretty simple, very incomplete.
Would be great if Euro5 model owners could give this method a try. Remember: no contributions – no support from us!

Save text below as logcfg.txt on microSD card, root folder. This config causes logging using SSM via CAN, starts immediatly (sending requests = green LED) when device is plugged into OBDII port.
PC must not be connected to interface. You can keep USB cable attached to device – does not matter. When ignition is on it should receive data (red LED), blue LED flashing indicates data is being written to memory card.

; SSM via CAN, Euro4/5: ssmcan
; SSM via Serial (K-Line, may work on Euro4 only): ssmk
type = ssmcan

paramname = Coolant_Temp_[°C]
paramid = 0x08
scalingrpn = x,40,-

paramname = Manifold_Absolute_Pressure_[kPa]
paramid = 0xD

paramname = RPM
paramid = 0x0E
databits = 16
scalingrpn = x,0.25,*

paramname = Vehicle_Speed_[km/h]
paramid = 0x10

paramname = Manifold_Air_Temp_[°C]
paramid = 0x12
scalingrpn = x,40,-

paramname = Mass_Air_Flow_[g/s]
paramid = 0x13
databits = 16
scalingrpn = x,0.01,*

paramname = Throttle_Opening_Angle_[%]
paramid = 0x15
scalingrpn = x,0.3921569,*

paramname = Battery_Voltage_[V]
paramid = 0x1C
scalingrpn = x,0.08,*

; DPF ------------

paramname = Soot_Accumulation_Ratio_[%]
paramid = 0x00027B

paramname = DPF_Active_Regeneration
paramid = 0x0001CE
databits = 1
offsetbits = 3

paramname = Regenerations
paramid = 0x00029D
databits = 16

paramname = Distance_After_Regeneration_[km]
paramid = 0x00029B
databits = 16

; SWITCHES ------------

paramname = clutch_sw
paramid = 0x121
databits = 1
offsetbits = 7

paramname = brake_sw
paramid = 0x121
databits = 1
offsetbits = 3


; trigger commented out, should already log at ignition on
; only log when the engine is running
;conditionrpn = RPM,0,>
;action = start

;conditionrpn = RPM,0,==
;action = stop

Generated logfile is in CSV format, easy to load into spreadsheet app, content looks like this: