Created
July 13, 2026 10:26
-
-
Save Lillecarl/3c6853bb17958627dae4aeb44dfb28f6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Volvo P2 DIM (Driver Information Module) CAN Protocol Reference | |
| Decoded from [VolvoDIMLib](https://github.com/agabler/VolvoDIMLib) — an Arduino library that reverse-engineers the P2 platform instrument cluster CAN bus. | |
| **Platform:** Volvo P2 (S60, V70, XC70, S80, ~2000–2007) | |
| **Bus speed:** 125 kbps | |
| **CAN format:** 29-bit extended IDs | |
| **Target:** Driver Information Module (instrument cluster) | |
| --- | |
| ## CAN Message IDs | |
| | # | Hex ID | Decimal ID | Description | | |
| |---|--------|------------|-------------| | |
| | 0 | `0x217FFC` | 2197500 | Speed value, odometer mileage, keep-alive heartbeat | | |
| | 1 | `0x2803008` | 2621448 | RPM (tachometer), backlight brightness | | |
| | 2 | `0x3C01428` | 6296680 | Coolant temperature gauge, outdoor temperature display | | |
| | 3 | `0x381526C` | 5882476 | Clock time, fuel/gas level gauge | | |
| | 4 | `0x3600008` | 5672968 | Brake system keep-alive | | |
| | 5 | `0xA10408` | 10552328 | Turn signal indicators (left/right/hazard) | | |
| | 6 | `0x2006428` | 3359784 | Anti-skid / traction control warning light | | |
| | 7 | `0x1A0600A` | 27262986 | SRS airbag warning light — requires init sequence | | |
| | 8 | `0x2616CFC` | 3993852 | 4C active chassis keep-alive — prevents dash errors | | |
| | 9 | `0x1017FFC` | 16875516 | Car equipment configuration (16 frames of option codes) | | |
| | 10 | `0x3200408` | 5245960 | Gear position display + warning light states | | |
| | 11 | `0x3E0004A` | 6488138 | Trailer attached indicator | | |
| | 12 | `0x02A0240E` | 44084238 | DIM text window control | | |
| | 13 | `0x1800008` | 25165832 | DIM custom text content (sent in 7-byte chunks) | | |
| --- | |
| ## Gauge Value Encoding | |
| ### Speed (`0x217FFC`) | |
| | Item | Byte(s) | Encoding | | |
| |------|---------|----------| | |
| | Speed value | Byte 6 | `speed * 6.375` (0–160 km/h → 0–1020 range) | | |
| | Scale quadrant | Byte 5 | `0x58` (0–40), `0x59` (40–80), `0x5A` (80–120), `0x5B` (120–160) | | |
| | Odometer mileage | Byte 7 | Incremented counter, wraps at 255 | | |
| ### RPM / Tachometer (`0x2803008`) | |
| | Item | Byte(s) | Encoding | | |
| |------|---------|----------| | |
| | RPM value | Byte 6 | `floor(rpm * 0.031875 / 32) * 32 + floor(rpm * 0.031875 / 8)` | | |
| | Overhead brightness | Byte 2 | `0`–`255` | | |
| | LCD brightness | Byte 4 | `0`–`63` (input 0–256 is divided by 32; values >250 clamp to `0x3F`) | | |
| ### Coolant Temperature (`0x3C01428`) | |
| | Item | Byte(s) | Encoding | | |
| |------|---------|----------| | |
| | Coolant temp | Byte 3 | 0°C → `88` (0x58), 55°C → `143` (0x8F), 100°C → `173` (0xAD) | | |
| | Outdoor temp range | Byte 4 | `0x0D` (-49–32°F), `0x0E` (33–146°F), `0x0F` (147–176°F) | | |
| | Outdoor temp value | Byte 5 | Scale factor ~2.2× depending on range | | |
| ### Fuel Level (`0x381526C`) | |
| | Item | Byte(s) | Encoding | | |
| |------|---------|----------| | |
| | Fuel gauge | Bytes 6–7 | `level_percent * 0.64` (both bytes identical, 0–100% → 0–64) | | |
| ### Time (`0x381526C`) | |
| | Item | Byte(s) | Encoding | | |
| |------|---------|----------| | |
| | Clock time | Bytes 4–5 | Minutes since midnight (0–1439 encoded as base-256: `byte4 = minutes / 256`, `byte5 = minutes % 256`) | | |
| ### Gear Position (`0x3200408`) | |
| | Gear | Byte 4 (hex) | Byte 4 (decimal) | Byte 6 (hex) | Byte 6 (decimal) | | |
| |------|-------------|-------------------|-------------|-------------------| | |
| | L (Low) | `0x40` | 64 | `0x96` | 150 | | |
| | P (Park) | `0x24` | 36 | `0x10` | 16 | | |
| | R (Reverse) | `0xE4` | 228 | `0x20` | 32 | | |
| | N (Neutral) | `0x24` | 36 | `0x30` | 48 | | |
| | 1st | `0x34` | 52 | `0x40` | 64 | | |
| | 2nd | `0x40` | 64 | `0x70` | 112 | | |
| | 3rd | `0x40` | 64 | `0x60` | 96 | | |
| | 4th | `0x44` | 68 | `0x50` | 80 | | |
| | 5th | `0xBE` | 190 | `0x00` | 0 | | |
| | 6th | `0xD5` | 213 | `0x00` | 0 | | |
| | None (blank) | `0x10` | 16 | `0x40` | 64 | | |
| --- | |
| ## Warning / Indicator Lights | |
| All on **byte 3** of CAN message `0x3200408` (gear position message). | |
| | Light | Hex | Decimal | Description | | |
| |-------|-----|---------|-------------| | |
| | Engine service required | `0x10` | 16 | Orange engine warning | | |
| | Reduced brake performance (orange) | `0x30` | 48 | Orange brake warning | | |
| | Fuel filler cap loose | `0x40` | 64 | Loose/missing fuel cap | | |
| | Slow down or shift up (orange) | `0x01` | 1 | Upshift or reduce speed | | |
| | Reduced engine performance (orange) | `0x0E` | 14 | Orange engine performance limit | | |
| | Engine system service urgent (red) | `0x90` | 144 | Red urgent engine fault | | |
| | Brake performance reduced (red) | `0xAA` | 170 | Red brake system fault | | |
| | Reduced engine performance (red) | `0xBB` | 187 | Red engine performance limit | | |
| | Slow down or shift up (red) | `0xDD` | 221 | Red upshift warning | | |
| --- | |
| ## Turn Signal States | |
| On **byte 7** of CAN message `0xA10408`. | |
| | State | Hex | Decimal | | |
| |-------|-----|---------| | |
| | Off | `0x00` | 0 | | |
| | Left blinker on | `0x0A` | 10 | | |
| | Right blinker on | `0x0C` | 12 | | |
| | Hazard (both) | `0x0E` | 14 | | |
| --- | |
| ## Trailer Attached | |
| On `0x3E0004A`, bytes 4–5. | |
| | State | Byte 4 | Byte 4 (dec) | Byte 5 | Byte 5 (dec) | | |
| |-------|--------|--------------|--------|--------------| | |
| | Not attached | `0x1D` | 29 | `0xE0` | 224 | | |
| | Attached | `0x11` | 17 | `0xE4` | 228 | | |
| --- | |
| ## Custom Text (DIM Message Display) | |
| Displaying custom text on the DIM's message screen requires sending to two CAN IDs: | |
| 1. **Priming the window** (`0x02A0240E`): | |
| - Set byte 7 to `0x31` (49 decimal) | |
| - Send to open/activate the text display area | |
| 2. **Sending the content** (`0x1800008`): | |
| - Text is sent in up to 5 frames, each carrying 7 bytes | |
| - Frame 1: byte 0 = `0xA7` (167), bytes 2–7 = first 6 chars | |
| - Frames 2–5: byte 0 = `0x21` through `0x24` (33–36), bytes 1–7 = 7 chars each | |
| - Max message length: 32 characters | |
| 3. **Closing** (`0x1800008`): | |
| - Final frame: byte 0 = `0x65` (101), remaining bytes = spaces | |
| --- | |
| ## Initialization Sequences | |
| ### SRS / Airbag Light (`0x1A0600A`) | |
| Four messages must be sent on startup to initialize the airbag module and clear the warning light: | |
| | Step | Byte 0 | Byte 6 | Delay | | |
| |------|--------|--------|-------| | |
| | 1 | `0xC0` (192) | `0xDB` (219) | 15 ms | | |
| | 2 | `0x00` (0) | unchanged | 15 ms | | |
| | 3 | `0xC0` (192) | `0xC9` (201) | 15 ms | | |
| | 4 | `0x80` (128) | unchanged | — | | |
| ### 4C Active Chassis (`0x2616CFC`) | |
| Four messages prevent "Chassis settings service urgent" popups: | |
| | Step | Byte 0 | Delay | | |
| |------|--------|-------| | |
| | 1 | `0x09` (9) | 15 ms | | |
| | 2 | `0x09` (9) | 15 ms | | |
| | 3 | `0x0B` (11) | 15 ms | | |
| | 4 | `0x0B` (11) | — | | |
| --- | |
| ## Default CAN Frame Data (Raw) | |
| The 8-byte default payloads the library sends for each message: | |
| | # | CAN ID | Bytes 0–7 (hex) | | |
| |---|--------|-----------------| | |
| | 0 | `0x217FFC` | `01 EB 00 D8 F0 58 00 00` | | |
| | 1 | `0x2803008` | `FF E1 FF F0 FF CF 00 00` | | |
| | 2 | `0x3C01428` | `C0 80 51 89 0E 00 00 00` | | |
| | 3 | `0x381526C` | `00 01 05 BC 05 A0 40 40` | | |
| | 4 | `0x3600008` | `00 00 B0 60 30 00 00 00` | | |
| | 5 | `0xA10408` | `00 00 00 00 00 00 00 00` | | |
| | 6 | `0x2006428` | `01 E3 E0 00 00 00 00 00` | | |
| | 7 | `0x1A0600A` | `00 00 00 00 00 BE 49 00` | | |
| | 8 | `0x2616CFC` | `0B 42 00 00 FD 1F 00 FF` | | |
| | 9 | `0x1017FFC` | `01 0F F7 FA 00 00 00 C0` | | |
| | 10 | `0x3200408` | `11 DE 53 00 24 00 10 00` | | |
| | 11 | `0x3E0004A` | `00 00 00 00 1D E0 00 00` | | |
| | 12 | `0x02A0240E` | `C0 00 00 00 00 00 00 35` | | |
| | 13 | `0x1800008` | `00 00 00 00 00 00 00 00` | | |
| --- | |
| ## Practical Notes for Sniffing & Replay | |
| - The DIM **powers down** if it doesn't receive keep-alive messages on `0x217FFC` and `0x3600008` at regular intervals | |
| - All messages are cycled through in a round-robin loop at ~15ms intervals. If running on an Arduino, the whole 14-message cycle takes roughly 200–250ms | |
| - The car config at `0x1017FFC` is car-specific. The 16 frames in this library were captured from a 2007 S60R with M66 manual transmission, climate package, and rear parking sensors but no navigation. Your car will have different option bytes | |
| - The SRS light will stay on permanently if the 4-step init sequence is not sent at startup | |
| - The 4C suspension message prevents "Chassis settings service urgent" — cars without Four-C may not need this | |
| - Ding/chime sounds are controlled by byte 1 of `0x381526C`: `0x30` (48) disables, `0x18` (24) enables |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment