Skip to content

Repository files navigation

Outdated-Volvo-P2-Nav-Retrofit-Guide-for-Android-Auto-Multimedia

Designed specifically for Volvo P2 models lacking the factory-installed RTI navigation system.

Important

Project Status: v1.0 — Initial Release The hardware and software are fully functional and have been undergoing real-world vehicle testing since July 8th, 2026.

Known observations and field test results are documented in the Field Testing document.

📦 All necessary 3D models for this project can be found here:

Printables

Problem

Older Volvo RTI navigation systems are obsolete:

  • outdated maps
  • poor UI
  • limited connectivity
  • expensive updates

Solution

This project retrofits the original display with a modern computing platform while preserving OEM integration:

  • Steering wheel controls
  • Automatic screen deployment
  • Android Auto / CarPlay

Project Motivation

Modern vehicles increasingly rely on large touchscreen displays for navigation and vehicle controls. While these systems provide extensive functionality, they often replace physical controls with touch-based interfaces that require greater visual attention during operation.

This project is inspired by an older engineering philosophy: placing essential information within the driver's natural field of view while allowing interaction through tactile steering wheel controls.

Rather than replacing the original Volvo RTI concept, the goal is to preserve its ergonomic design and combine it with modern, open-source hardware and software. By bringing new functionality to the factory motorized display and steering wheel controls, this project aims to demonstrate that well-engineered ideas remain valuable regardless of their age.

BOM of Hardware:

Software:

  • OS Debian GNU/Linux 13 "Trixie";
  • Hudiy infotainment system software, github;

Wiring Diagram

The Power Management + Hardware Supervisor

Electronics is nothing more than wires and contacts :). With that in mind, extra care was taken with the physical power connections while integrating the retrofit DIY navigation system into the vehicle. In automotive environments, long-term reliability depends heavily on secure, well-fitting contacts. In this project, I decided to power the RTI monitor and other electronic components directly from the passenger compartment fuse box, just like Volvo designed it from the factory. I also followed the genuine Volvo wiring diagram and kept the fuse layout the same as stock: F12 for the RTI display, F13 for the Raspberry Pi, and other components.


Location of the passenger fuse box

Passenger Compartment Fuse Table

An alternative fuse contact TE Connectivity 880398-2 was sourced as a swap-in for the original Volvo fuse terminals, making it possible to tap new wiring cleanly into the factory harness as if it was built in from day one.


Contact Comparison: Original vs TE Connectivity 880398-2. It looks quite different, but it fits very well.


Wiring before vs after modification with contact terminals integrated directly into the OEM fuse box for retrofit installation.

The RTI display [16/46] requires an ignition signal. Referencing the official Volvo wiring diagram, this connects directly to the Audio Unit Module (AUM)[16/1]:


In the original setup, there’s a direct link between the RTI display [16/46] and the AUM [16/1].

Make sure you're tapping into the correct pin on the AUM, as the ignition trigger (often labeled ACC or 15) is what tells the RTI screen to power on when you turn the key.

Here’s a simple 'mermaid' maps of the power distribution logic I’m working with:

flowchart LR
A[Volvo FuseBox, F12] -->|KL30, 12V| B(RTI - A:1,A:2)
C[AUM - A:2] -->|KL15, 12V| D(RTI - A:3)
Loading
flowchart LR
A[Volvo FuseBox, F13_KL30] -->|12V| B(DC/DC 5.1V)
A[Volvo FuseBox, F13_KL30] -->|12V| C(DC/DC 5V Always-On)
B -->|5.1V| D(RaspberryPi 5)
B -->|5.1V| E(USB 3.0 Y cable)-->|5.1V| F(SSD)
C -->|5V| G(Arduino Uno)
Loading

NOTE: To prevent +5.1 V backfeeding into the Raspberry Pi USB port, the USB 3.0 Y cable (Item No. 83176) needs a simple physical modification. For this setup, the author cut the red wire (+5 V) on the USB branch connected to the Raspberry Pi. Additionally, increasing the USB boot delay in the EEPROM configuration is also recommended:

[sudo rpi-eeprom-config --edit]

BOOT_UART=1
POWER_OFF_ON_HALT=0
BOOT_ORDER=0xf461
PSU_MAX_CURRENT=5000
USB_MSD_STARTUP_DELAY=3000

We're using a non-official PSU here. To prevent the Pi from throttling USB current, you need to manually modify the EEPROM. Throw PSU_MAX_CURRENT=5000 into the bootloader config to force-enable the 5A power profile.

I'm grounding all the electronics to the factory grounding point near the lower door hinge:


Location of the factory ground point.

It’s the perfect spot to keep all the wiring tucked away and properly grounded.

To achieve more robust power management in this project, we implemented an Arduino-based CAN watchdog and power supervisor that allows the Raspberry Pi to boot only after receiving a valid “ignition ON” CAN message continuously for 10 seconds. This ensures the system operates reliably through engine cranking, ECU resets, and voltage fluctuations. The flowcharts below detail the system start-up sequence and control logic:

flowchart LR
    A([Start: Arduino init]) --> B[Enter loop: Arduino always on sleep mode]
    B --> C{Is any CAN frame received?}
    C -->|YES| L[/Execute ISR INT0 & Disable Sleep/]
    L --> D[/Check VALID_MSG/]
    C -->|NO| B
    D --> E{Message IGN_ON ID Correct?}
    E -->|NO| D
    E -->|YES| F[/Activate count down timer 10 sec./]
    F -->G{IGN_ON Active > 10s?}
    G -->|NO| C
    G -->|YES| H@{ shape: hex, label: "Enable DC/DC 5.1V output"}
    H -->J[Raspberry Pi starts]
    J --oK@{ shape: odd, label: "FLAG: POWER_ENABLED" }
Loading

Another important aspect we must pay close attention to is performing a proper, clean shutdown of the Raspberry Pi. Simply cutting the power can easily corrupt the files on the SD card — or in our case, the SSD. To handle this, the Arduino continuously monitors the system even after a successful startup and ensures that the Raspberry Pi shuts down safely when needed.

For this project, we selected the Raspberry Pi 5, which provides a dedicated ON/OFF power button and J2 header pins for an external switch. We decided to take advantage of this new feature by driving the J2 contacts with a relay. This approach lets us keep the Arduino code much simpler and frees up its processing power for other tasks. The flowcharts below detail the system shutdown sequence and control logic with the assumption that the Raspberry Pi is already running (POWER_ENABLED flag being set to TRUE):

flowchart LR
    A([POWER_ENABLED: TRUE])  -->C[/POWER_ON/]
    B([Enable DC/DC 5.1V output])  -->C[/POWER_ON/]
    C -->D{IGN_ON message received?}
    D -->|YES| C
    D -->|NO| E[/Start 5s IGN Loss Timer/]
    E -->F{IGN Loss Duration > 5s?}
    F -->|NO| C
    F -->|YES| G[/Trigger J2 Relay Pulse/]
    G --> H[/Activate RPI_Power_Down_timer 15 sec./]
    H -->J{Is any CAN frame received?}
    J -->|YES| K[CAN BUS runing, keep waiting]
    J -->|NO|L@{ shape: hex, label: "Disable DC/DC 5.1V output" }
    L -->M[POWER_OFF]
    M --oN@{ shape: odd, label: "POWER_ENABLED: FALSE"}
    M -->O[Arduino goes to sleep mode]
Loading

NOTE: CAN ID 0x217FFC, a value of 0x58 in Byte 5 indicates Ignition = ON in the Volvo S60 (P2):

---
title: "CAN Message Mapping for 0x217FFC"
---
packet
0-1: "SOF"
2-29: "CAN IDENTIFIER (29): 0x217FFC"
30-31: "Byte 0"
32-33: "Byte 1"
34-35: "Byte 2"
36-37: "Byte 3"
38-39: "Byte 4"
40-46: "Byte 5 - 0x58 (IGN Status: ON)"
47-48: "Byte 6"
49-50: "Byte 7"
51-52: "CRC"
53-54: "ACK"
55-56: "EOF"
Loading

For CAN ID 0x217FFC, the ignition status byte can change from 0x58 to 0x98 or 0xD8 when cruise control is activated or the set speed is adjusted using + / -. The decoder has been updated to recognize all three values as Ignition ON: 0x58, 0x98, and 0xD8.

Important: the Volvo P2 low-speed CAN communication bit rate is 125 kbps.


Arduino-based CAN watchdog and power supervisor unit.

The Arduino-based CAN watchdog and power supervisor is built using an Arduino Uno and two standard off-the-shelf shields: a CAN Shield and a Prototype Screw Shield Expansion Board used to host the Arduino power supply circuitry. All required hardware can be purchased off the shelf. The only custom assembly required is soldering the DC/DC converter module onto the prototype shield. No custom PCB fabrication is necessary.

The schematic below shows the modifications implemented by the author. It is not intended to be the only correct solution—just one practical implementation that satisfies the design requirements. Feel free to adapt or redesign the hardware to better suit your own application.


Power supply modification for external 5 V DC/DC module.

Final assembly: The completed CAN watchdog and power supervisor unit installed inside the Volvo OEM RTI display housing. The enclosure was originally designed to accommodate the factory speaker, making it an ideal location for the additional electronics.


Final assembly showing the external interfaces: Power Input, CAN Bus, USB (Programming), and Composite Video (PAL)

Top view of the assembled CAN watchdog and power supervisor unit installed inside the Volvo OEM RTI display enclosure.

Making LIN Work

The goal of this project is to retrofit the stock low-res RTI monitor with its simple non-touch LCD. Since there’s no touchscreen, the steering wheel buttons are essential for navigating and controlling the display. There are two ways to get those buttons physically in place: replace the entire wheel, or fit just the nav button module. I chose the second option for this pilot build:

LIN bus sniffing Wiring Diagram
This NAV button installation guide is based on genuine Volvo technical documentation (Instruction No. 30660446) and has been visualized in a comic style using Gemini.

This isn’t straightforward, though. In vehicles without the factory-installed RTI, the steering wheel button events never appear on the CAN gateway (checked). There are several ways to “bring these buttons to life” on the CAN bus. One option is to reconfigure the CEM module, but a cheaper and more practical approach is to sniff the LIN bus directly between the SWM and the CEM. Below is attached electrical schematic showing how the LIN-USB adapter is integrated into the Volvo P2 vehicle:

LIN bus sniffing Wiring Diagram

Note: USB differential lines should be kept as short as possible because USB is a high-speed interface sensitive to signal distortion, reflections, and EMI. Poor routing, long traces, or impedance mismatches can quickly degrade signal integrity and cause communication errors. For noisy or long-distance environments, LIN is a more robust bus.

Vehicle-side connector pinout specifications.

Location Pin Numbering
SWM Connector Vehicle-side connector Signal type
#1 #1 -
#2 #2 Ground
#3 #3 Control module communication cable CAN_L
#4 #4 Control module communication cable CAN_H
#5 #5 -
#6 #6 -
#7 #7 Communication cable LIN central electronic module (CEM)
#8 #8 Power supply
#9 #9 Windshield wipers
#10 #10 Horn

Decoded Steering Wheel Button Signal Table

Signal Name LIN ID Data Bytes Description Example Decode
NO_PRESS 0x01 3F 00 No button pressed
BTN_NEXT 0x01 3D 00 Next track
BTN_PREV 0x01 3E 00 Previous track
BTN_VOL_UP 0x01 37 00 Volume up
BTN_VOL_DOWN 0x01 3B 00 Volume down
BTN_BACK 0x01 3F 10 Back
BTN_ENTER 0x01 3F 20 Enter / Select
BTN_UP 0x01 3F 08 Navigate up
BTN_DOWN 0x01 3F 04 Navigate down
BTN_LEFT 0x01 3F 02 Navigate left
BTN_RIGHT 0x01 3F 01 Navigate right
CLL_ANSWR 0x01 2F 00 Answer call
CLL_HNG_UP 0x01 1F 00 Hang up call

All LIN bus data in this project was captured using the USBlini USB-to-LIN interface and PulseView logic analyzer.

This data is reverse-engineered and may vary depending on vehicle model or manufacturer. Volvo P2 S60 LIN communication baud rate is 9600 bps, frame ID - 0x01.

bridge.py A Python-based hardware-to-software bridge script designed for Raspberry Pi. It captures Volvo Local Interconnect Network (LIN) bus messages via a USBlini adapter and translates OEM steering wheel button presses into virtual Linux keyboard inputs (uinput) for seamless control of the Hudiy media interface. To maximize full control over Hudiy using a limited number of OEM steering wheel buttons, the bridge implements a long-press state machine:

  • Left Arrow (0x3F, 0x02): Short tap outputs KEY_LEFT, while holding for $\ge 700\text{ ms}$ triggers scroll_left_1 (outputs KEY_1).
  • Right Arrow (0x3F, 0x01): Short tap outputs KEY_RIGHT, while holding for $\ge 700\text{ ms}$ triggers scroll_right_2 (outputs KEY_2).

Software Support

More about set up: 📖 Raspberry Pi LIN Setup

See RASPBERRY_PI.md for additional Raspberry Pi configuration.

Volvo OEM navigation control

Bringing the Volvo Pop-up Screen Back to Life

The stock Volvo display is an old-school 20th-century analog device, which actually makes it a great candidate for mods! It’s super easy to hook up to embedded gear like a Raspberry Pi, all you really need is to feed it a basic analog video signal. To pop the screen up and down, you just need to send the right commands over the serial line. Huge thanks to @TymEK49 for sharing the commands to control the RTI screen! RTI_control.

To guarantee a solid connection to the RTI unit, I recommend using a stock OEM harness salvaged from a used car.


Volvo P2 RTI Display.

OEM Wiring Harness.

RTI Display connectors pinout specification:

Pin Numbering
Pin No. Signal type Other
#1 Color signal (red) -
#2 Color signal (green) -
#3 - -
#4 Serial bus to the display using in this project (wire color: pink)
#5 Signal, display remote control -
#6 Color signal (blue) -
#7 Screen ground, video signals using in this project (wire color: black)
#8 Composite sync. -
#9 - -
#10 Video signal to display using in this project (wire color: white)
/ / /
#1 KL30 12V
#2 KL30 12V
#3 KL15 Ignition
#4 KL31 GND
#5 KL31 GND

Here’s the clean Pi 5 setup to turn on composite output in /boot/firmware/config.txt

# Enable DRM VC4 V3D driver
dtoverlay=vc4-kms-v3d,composite

# Disable compensation for displays with overscan
disable_overscan=0

Set PAL in/boot/firmware/cmdline.txton the same single line:

video=Composite-1:720x576i,tv_mode=PAL

Note: PAL uses a higher resolution (720 × 576), so no black border appears around the RTI display in these cases.

Building a Bridge Between New Headunit and Factory Audio system

The headunit in this project is powered by a Raspberry Pi 5. As you might know, the Pi 5 doesn't have an onboard audio jack, so we had to find a way to get sound out of it. While there are many ways to do this, I decided to go with the Pimoroni Audio DAC SHIM, which generates high-quality audio via the I2S interface.

The author also recommends a GPIO header adapter or a 90° connector to offset the Pimoroni Audio DAC. This clears the path for the active cooling setup, ensuring the fans can push fresh air across the SoC without any obstructions. For this build, we’re using the Waveshare Raspberry Pi 400 adapter to keep the airflow path wide open.

First, a quick bit of background: MELBUS (Mitsubishi Electronic Bus) is the proprietary communication protocol Volvo uses to let the main head unit talk to peripherals like factory CD changers, MD players, or RTI navigation units. To get external audio playing through a stock Volvo sound system, one of the cleanest approaches is using a GROM audio adapter (which is exactly what I went with for this project). It basically tricks the car into thinking a factory CD changer is hooked up, allowing you to feed audio straight into the AUM over the MELBUS line without losing that stock look and feel.

Below is attached electrical schematic showing how the Pimoroni Audio DAC and GROM audio adapter is integrated into the Volvo P2 vehicle:

This installation guide is based on the GROM Audio technical documentation: GROM Audio Volvo Installation Guide)

GROM audio EXT2 connector pinout specification:

Pin Numbering
Pin No. Signal type Other
#1 Left Audio (L) -
#2 Right Audio (R) -
#3 - -
#4 - -
#5 Ground (GND) 3.5 mm Sleeve
#6 - -
#7 - -
#8 - -

Here’s the clean Pi 5 setup for a PCM5100A I2S DAC: /boot/firmware/config.txt

# Disable onboard analog audio
# dtparam=audio=on

# Enable I2S
dtparam=i2s=on

# Generic passive I2S DAC overlay
dtoverlay=i2s-dac

Here’s the HUDIY main_configuration.json setup for playing audio through a DAC:

"sound": {
  "volumeSinkName": "alsa_output.platform-soc_107c000000_sound.stereo-fallback",
  "playbackSinkName": "alsa_output.platform-soc_107c000000_sound.stereo-fallback"
}

NOTE: ''alsa_output.platform-soc_107c000000_sound.stereo-fallback'' is the audio sink name for your DAC in PipeWire/PulseAudio terms. You can find it in your case with this simple command:

pactl list sinks

The "Black Box" Build

The Goal: A completely stealth installation, tucking all the Raspberry Pi hardware directly into the factory phone module compartment for a clean, OEM look. The design must also provide easy access to all components, ensuring they are securely fastened using screws or cable ties. Additionally, a screw-secured front lid will provide quick access to the Raspberry Pi’s shutdown button and USB ports.

Here is the final setup:


Side view.

Front view.


Final setup of Raspberry Pi hardware with peripherals into the factory phone module compartment.

Roadmap

See ROADMAP.md for the current development roadmap and planned future features.

About

Modernizing legacy Volvo navigation systems with Raspberry Pi + CAN bus + LIN integration.

Topics

Resources

Stars

8 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages