BMW E39 Navigation Retrofit Project
Table of Contents
- Main
- Software Design
- Arduino Power Board
- Video Switch + Backup Camera Install
- Rpi Construction
- Bill of Materials
- References
Main
Introduction
In August 2019, I bought a 2001 BMW 530i with a 5-speed manual to replace my 1992 525i.
From October 2019, I began collecting the parts necessary to retrofit:
- DSP Amplifier and Speakers
- Original Mk4 navigation system
- Backup camera
- Raspberry Pi (for phone bluetooth pairing)
After I sucessfully retrofitted the factory navigation system, I realized I could add auxiluary video inputs into the screen. I then added a backup camera, and a Raspberry Pi.
With software I wrote for the Pi, I can listen to the steering wheel Previous & Next track inputs, and route those to a paired Bluetooth phone to change the track in Google Play Music.
Where there has been previous research and work done to interface with the BMW IBus (a LIN bus), I am the first to do it with Kotlin using co-routines, flows, and channels.
https://github.com/linster/e39-rpi
Project Staging
In building this project, there were several iterations I went through:
- Upgrade the original sound system to the factory DSP system (12 speakers), add adapter harness
- Build Navigation harness (salvaged from a junkyard BMW E46)
- Install navigation harness in car (pictured left)
- Add TV Module to stock system
- Build Video Switch / Auxilliary Video harness.
- Add backup camera to car
- Build RPi box. Build Arduino circuit board to turn Pi on and off with car.
- Write E39-IBus app for RPi.
RPi Software Design (2020)
I was inspired by the work by http://imbmw.net/ which is a .Net Core app / app-framework that allows users to draw menus and listen to button presses.
I decided to re-implement parts of this library in Kotlin as a challenge: I wanted to build a Kotlin app exploring more of the newer coroutine APIs (Flow, Channel). I also wanted to understand the ins and outs of IBus message parsing.
The app itself is a plain-old Kotlin/JVM app. I developed a very light-weight framework to start a number of long-running “services”, each sharing a coroutine. The design was inspired by the Android service lifecycle. Github
The Raspberry Pi app communicates to the phone by making calls to BlueZ over DBus. For the MVP, the phone’s bluetooth mac address is hard-coded to a global object dependency injected into a variety of consumers.
Eventually I want to setup the Pi to continuously show NavIt maps. When the user presses the telephone button on the head unit, the Pi will enable a relay (on the relay board attached to the Pi) to switch the display to Navit. (At left is a picture of Navit showing a recent OpenStreetMap dump).
The factory HMI is showing the Bluetooth track title and artist.
Selected Pictures
Before
This is what the infotainment system looked like when I started the project.
After
This is the nav system in place showing the Main Menu (drawn by the TV Module)
First Test Run
The first time the Navigation Harness was run in the car (Jan 13, 2020)
Raspberry Pi Box
This is an MK3 Navigation Drive with all of it’s parts replaced with:
- Raspberry Pi 3B+
- Relay board
- GPIO breakout board
- Power supply + ignition sense relay
- IBus USB interface