The goal of this project is to replace the function of the standard radio head unit with a Raspberry Pi. The Pi will be able to communicate to the User through a display in the instrument cluster that is capable of displaying short text strings. The User will be able to communicate with the Pi by using controls on the steering wheel stock that originally controlled a car phone. The Pi will be able to play music from several sources, such as a flash drive, wirelessly from a smartphone, or even FM radio.
Background: I originally got the car with the head unit bypassed, with the input for the amplifiers connected directly to a headphone cord that can be plugged in to a phone or mp3 player. I got tired of having to plug and unplug and worrying about the charge level of the source device, so I decided to make something better. The original non functional head unit has since been hacked apart and is now serving another purpose, so just getting another more modern head unit is out of the question.
The Raspberry Pi will be able to communicate with the
instrument cluster display to be able to give feedback to the User and show the
current song/artist.This display is originally used to show Check Control
messages (such as "Brake Light Out" or "Fasten Seat Belts",
etc.) and info from the On Board Computer (such as time, MPG, outside
temp,etc). It can show up to 16 characters at a time.
After reading the above link about the cluster
communication, it seems there are two comm wires, the LAC and the DAC. The LAC
seems to be a more of a handshaking/priority line where nothing else is allowed
to transmit on the bus when it is pulled low. The DAC is the data line which
operates at 9600 bps, 8 data bits, Even parity, and 1 stop bit.
Here's the steps for sending data to the cluster (from
i-code link above):
The basic logic is as follows: every 100ms, the CCM/LKM do
their status updates, and this results in a rising edge (0V -> 12V) on LAC.
1. Wait for a rising edge
2. drive LAC low with a transistor, MOSFET, etc
3. send 16 bytes of serial data using 9600 baud, 8 data
bits, Even parity, 1 stop bit
4. send the checksum of the data using the same 9600 baud, 8
data bits, Even parity, 1 stop bit
5. release LAC; stop driving it LOW
The checksum is calculated as follows: take a running sum of
the 16 data bytes in hexidecimal form, take the least significant byte of that
sum, add 1.
Researching the Cluster Comm
I hooked up a USB oscilloscope to the DAC and LAC lines going to the cluster to see what is going on when the cluster is displaying a regular message (fuel range, in this case). In the following screen shots, blue is the the LAC line and red is the DAC line.
While nothing is shown on the display:
While a message is being displayed:
So, as mentioned in the i-code article, it seems that the Check Control Module (CCM) is doing an update every 100ms (shown in the first screen shot, while nothing is being displayed). Note that the LAC line is being pulled down during the CCM update.
Now looking at the screen shot of while a message is being displayed, after the LAC line is returned high, the message data is sent on the DAC after a short delay.
Now in the i-code article, he mentions that he didn't have a delay between the LAC going high and the On Board Computer (OBC) message starting. He got around this by driving the LAC low which would stop the OBC message from being sent. It is also mentioned the delay is meant to be a priority tool, where higher priority messages wait less time after the LAC going high to send their message (and once a device sees another device transmitting, it will not send its message).
Since I do see a delay between the LAC going high and the message data, I think I may be able to get away with not driving the LAC low. It looks like I also have the choice of making my message higher or lower priority than the OBC message. I'm thinking I would like to make it lower priority (wait a long delay before transmitting message) so that I will be able to see the OBC messages over the RPi messages when I want to.
Another interesting thing I see from the o'scope is that the LAC line goes low immediately after the OBC message data is finished transmitting. I suppose this is to prevent any other messages from being transmitted until the next 100 ms cycle. Right now, I...