It's Saturday night and I feel like partying! :D After countless hours and ~3500 lines of code later, I finally managed to connect VIDA successfully to Volvo, launch the diagnostic part related to Combustion Preheater Module and turn on the parking heater with my laptop!
Sorry about the poor image quality here:
![]() |
| Vida correctly identifies most of the vehicle features. Only transmission, steering and body style had to be manually entered. Reason for this can be seen in the next picture.. |
Let's refresh our memories of the general format of module query (from past blog post):
000FFFFE CB xx B9 F0 00 00 00 00
| | | |
| | | |
| | | '---- Identify (?)
| | '----------------- Read Data Block By Offset
| '-------------------- Module id (list below)
'----------------------- Message length
00 0F FF FE: The identifier VIDA (or any other diagnostic module) uses for messaging.
Message length: High nibble seems to be always 'C' in command message. Low nibble: Bit 3 is always on. Bits 0-2 is the actual message length (excluding the first byte). Hence A=2, B=3, C=4, D=5, E=6, F=7
I found this command set somewhere on Swedespeed car forum:
A1 No Operation Performed (keep alive)
A3 Security Access Mode
A5 Read Current Data By Offset
A6 Read Current Data By Identifier
A7 Read Current Data By Address
A8 Set Data Transmission
A9 Stop Data Transmission
AA Dynamically Define Record
AB Read Freeze Frame Data By Offset
AC Read Freeze Frame
AD Read Freeze Frame By DTC
AE Read DTC
AF Clear DTC
B0 Input Output Control By Offset
B1 Input Output Control By Identifier
B2 Control Routine By Offset
B4 Define Read Write ECU data
B8 Write Data Block By Offset
B9 Read Data Block By Offset
BA Write Data Block By Address
BB Read Data Block By Address
And here's the list of all modules that were queried and identified on Volvo S80 MY02.
CAN diag Id ID Description
00 80 00 03 :: 40 CEM, Central Electronic Module
(also answers queries related to CPM(heater)
00 80 00 09 :: 51 DIM, Driver Information Module
00 80 08 01 :: 48 SWM, Steering Wheel Module
00 80 10 01 :: 29 CCM, Climate Control Module
00 80 00 11 :: 43 DDM, Driver Door Module
00 80 00 81 :: 45 PDM, Passenger Door Module
00 80 01 01 :: 2e PSM, Power Seat Module
00 80 04 01 :: 46 REM, Rear Electronic Module
00 80 02 01 :: 58 SRS, Air bag
00 80 20 01 :: 47 UEM, Upper Electronic Module
00 80 00 05 :: 60 AUM, Audio Module
00 80 00 21 :: 64 PHM, Phone Module
These module were queried but didn't reply:
ID Description
50 CEM, Central Electronic Module (Hi-speed interface)
01 BCM, Break Control Module (hi-speed network)
52 AEM, Accessory Electronic Module
11 ECM, Engine Control Module (hi-speed network)
28 SAS, Steering Angle Sensor (hi-speed network)
6e TCM, Transmission Control Module (hi-speed network)
62 RTI, Road Traffic Information module
And here's the sweet sight of hard reverse engineering work coming finally to fruition! Only coolant water temp and heater work status are being correctly queried though. Few software glitches still remain, but I don't care about that for now, since the thing I've been hunting for past few weeks has been now identified! Yes, the command for starting the heater :)
Turn on the diesel heater:
00 0f ff fe | cf 40 b1 5f 3b 01 01 84
And the reply:
00 80 00 03 | cc 40 f1 5f 3b 00 00 00
Turn off diesel heater:
00 0f ff fe | cf 40 b1 5f 3b 01 01 80
Reply:
00 80 00 03 | cc 40 f1 5f 3b 00 00 00
Now, this seems weird, since I had already tried this command before and it didn't work! It is one of the possible permutations of the message I was advised to try earlier by Swedish hackers (thanks again guys!), and I'm quite sure I tried this one before. There are few possible explanations:
1) I somehow managed to screw up sending the message using ELM327 (with its yucky AT command set), but now when using the MCP2515 based Arduino CAN shield the message is constructed correctly.
2) ECU needs something else in addition to the command message itself. When looking at the message log, I see VIDA sending the following message every 1-5 seconds:
00 0f ff fe | d8 00 00 00 00 00 00 00
Could this be some kind of keep alive message needed by ECU?
Also VIDA keeps querying following stats every 3-4 seconds and their presence could be necesssary (although unlikely):
Cmd: 00 0f ff fe | cd 40 a6 1a 04 01 00 00
Reply: 00 80 00 03 | cd 40 e6 1a 04 1e 00 00
The 6th databyte of reply seems to coincide with ignition key lock status:
1e = ignition II, 1d=radio (ignition I), 1c=off, 18=key out
Cmd: 00 0f ff fe | cd 40 a6 1a 02 01 00 00
Reply 00 80 00 03 | cd 40 e6 1a 02 60 00 00
The sixth databyte of reply fluctuates between 5d and 62, and could be the battery voltage. If we assume bits 0-2 consist of fractional part and bits 3-8 the integer part, then the values here would be interpreted as 11.625 and 12.25, and would fit well in our hypothesis. Actually a battery charger was connected during testing, so voltage over 12 volts would not be strange here.
VIDA needs the key to be in ignition II position in order to launch the heater section, but I did try switching the key position and it didn't have any effect on the result itself: Heater can be turned on with diagnostic command even when key is not in the keylock! This is actually quite a relief - spoofing the keylock position in the remote heater starter would require quite a bit of more work, but luckily this doesn't seem to be needed. However what is little bit alarming, is that any indication on the heater status is NOT shown on DIM, nor does the manual on/off functionality on the control stalk work when turning on the heater using this diagnostic command. Thus I will have to put some other kind of stop functionality and warning system in place when designing the box.
Still this isn't a fully functional J2534 device yet: It doesn't support ISO9141 or any other kind of protocols apart from CAN and ISO 15765, nor does it work when connecting it to OBD port, since it's missing the K-line initialization and keep-alive messaging to keep the diagnostic relay open on CAN bus pins. Maybe I will add some more functionality later, but for now, I'm quite happy with the results that I got. Also, no more Win32 programming for a while :)



