Parked in front of my house is an old BMW E36 325i. When I bought it, it came loaded with cassette tapes from the previous owner, like a time capsule from a different era. Although I quite like Johnny Cash and Kenny Rogers, it gets repetitive after a while. So I set myself to work to make my radio Spotify enabled.
These casettes will soon go unused
First of all you might think these interfaces already exist, and this is partially true. Bluetooth interfaces from companies like Yatour and others are indeed available, but only for head units that support the IBUS protocol. There is only one head unit for the E36 that fits the bill, which is the CD43. But probably exactly for this reason, second hand prices for this unit are a lot higher than its alternatives.
A second route could be to modify the radio itself and for instance solder a Bluetooth module to the audio connections of the tape deck. A drawback of this is that it is less straightforward to control your music from the buttons on the radio. Therefore I went with a head unit with a CD Changer interface which I could then use. The added benefit of this is that I do not need to open up the radio which makes it a more elegant solution.
The radio I chose is the BMW Business RDS, also known as the Philips PH7850. This head unit can be connected to BMW 6 CD Changer A, and I managed to find a set with the two for a good price. Now that I have selected the right head unit there are two main parts to this project. First of all I need to reverse engineer the CD changer interface, and secondly I need to connect this to a bluetooth audio module.
Philips PH7850 and BMW 6 CD Changer A
The CD Changer connects to a 10 pin connector below the main radio connector. This connector is very conveniently compatible with standard breadboard jumper wires. From the little I found online, this protocol is also known as Pioneer M-bus. Therefore this product will most likely work with more period BMW, and even non-BMW head units. I also found the pinout of the connector online. Looking at the back of the radio the pinout is:
|Audio L -
|Audio R -
|Audio L +
|Audio R +
The magic is happening in the four connections on the right, which make up the data interface. Luckily, the reverse engineering proved less complicated than expected. After hooking up the logic analyzer I quickly found that the interface resembled some form of SPI communication albeit with a single data line. Typically SPI has two data lines, one for each direction. But as it turns out this bi-directional approach also exists and is known as 3-wire SPI.
No secret is safe for my Saleae
The head unit is acting as a master and periodically sending a message to the CD Changer. After the transmission is complete, the CD Changer responds with its current status. I did not figure out the meaning of every single byte transmitted, but at least enough to mimick and implement my own interface.
First there is some kind of handshake. I am not sure what it means but I observed this to be the same every time so I just hardcoded it. First the head unit sends 0x06 0x00, to which the CD Changer responds with 0x60 0x01 0x18. Then there is a second handshake which looks quite similar with the head unit sending 0x06 0x00 0xF6 and the CD Changer responding with 0x60 0x02 0x18 0x00. After the handshake was successfull there is a periodic communication according to the tables below. There might be some more functions not listed, but this is at least everything I need for my implementation.
|Constant head unit identifier
|The head unit is turned off
|The head unit is turned on
|0x31 - 0x36
|CD1 to CD6 button
|CD mode entered
|CD mode left
|No CD playback
|Other values than 0x04 set predefined display texts
|0xF1 - 0xF6
|Fx in which x is the displayed CD number
|0x00 - 0x99
|Hex value is the playback time in minutes
|0x00 - 0x99
|Hex value is the playback time in seconds
|0x00 - 0x99
|Hex value is the active track number
|0x00 - 0xFF
|Binary combination of which CD's are present
I implemented this communication protocol on an arduino pro mini. And used a breadboard compatible bluetooth module with a CSR8635 chip. With this I do not need to get involved on the Bluetooth side. The module I picked has some pins for play/pause controls and next/previous track. I connected these to the Arduino to link them to the actual head unit buttons. Finally I used an isolated DC/DC converter to give the Bluetooth module its own ground in an attempt to improve the audio quality.
Not the prettiest, but hey, it works!
This module is currently running in my car, and except for some minor issues it is working flawlessly! As a next step I will turn this into a custom PCB design.