The screen has multiple inputs: HDMI, VGA and analog video. There is even a specific pin on the board to automatically switch to the analog video input, which is perfect for a backup camera. This will allow me to display the car’s informations via HDMI or VGA, and switch to the backup camera video feed when I switch to reverse gear. Next step: retrieving the car’s informations.

Interfacing with the car

This is where the Arduino comes in. But how can I connect an Arduino to my car? The obvious candidate would be to use the OBD-II port. In Europe, car manufactured after 2004 are required to include it. It’s a standard port used to perform diagnostics and retrieve various informations about the car (like the battery voltage, oil temperature, …).

Sadly, it doesn’t return data about the current tuned FM station, or the trip computer’s informations (distance travelled, fuel estimate), at least not on my car.

After some digging, it turns out that every piece of electronic of my car is connected to a CAN bus. The CAN bus is present in most car nowadays because it allows to have much less cables than before. It requires only two cables and every node connected on it can talk to each other. Nodes send and receives frames with a numeric ID and up to 8 bytes of data.

As I expected, there is not much information online about my car’s CAN bus. The content of each frame is not publicly documented and probably unique to each brand of car, since this is not standardized like the OBD-II protocol. Luckily, I found the website of a university teacher who taught a course on CAN buses, and the students did practical work on… a Peugeot 207! This is perfect, as I could find valuable information in this PDF (in French).

It did not contain information on the frames I needed, but I learned that my car actually has 3 different CAN buses:

The “confort” bus, which controls air conditioning, the radio, speedometer, fuel gauge…

The “body” bus, which controls stuff like headlights, turn signals, wipers…

The “inter-systems” bus, which connects the different control modules for the engine, the brakes and so on…

The bus I’m interested in is the first one, where the radio and the old display are connected.

I found an unused connector on the back of my radio unit. Apparently, its purpose is to connect an optional CD changer. But a quick search revealed that the connector has 2 pins exposing the “confort” bus. So I wired the Arduino to the radio using a CAN bus shield. And to my delight, I started receiving CAN frames!

Decoding CAN frames

At first, I tried printing every frame I could read on the bus. But I couldn’t make sense of anything because there was too much data being sent at the same time. It turns out, each node broadcast its status a few times every second, even if it didn’t change since the last time. So I made a Python script to have a better visualization of the frames:

The frames are ordered by ID. Being able to see bytes changing in real-time made it much easier to decode the frames:

By turning the volume of the radio up and down, I immediately found that the volume level was in frame 421

Shifting to reverse gear flips a bit in frame 246. This is perfect as I could connect the Arduino to the LCD controller board to switch to the backup camera video automatically. I was lucky this information was on the confort bus, as far as I know there is nothing which displays the current gear on the dashboard

Current radio station: the name of the tuned radio station is encoded in ASCII in frame 677

Opening and closing doors revealed that frame 417 contained information about which door was currently open

However, some data was more difficult to find:

The outside temperature can be negative, which means they had to find a way to represent negative numbers. I put my finger on the temperature sensor and tried to see which value was slowly going up. Turns out the temperature value is offset by 40 . So 0 is -40ºC, 40 is 0ºC, and so on… This means that the car can’t display temperatures below -40ºC (but by then the car would probably have died already…)

. So is -40ºC, is 0ºC, and so on… This means that the car can’t display temperatures below -40ºC (but by then the car would probably have died already…) FM frequency was offset by 500 and multiplied by 10. For example, 577 represents the 107.70MHz frequency ( (577 + 500) / 10 = 107.7 )

represents the 107.70MHz frequency ( ) Information messages. Sometimes the car displays messages such as “low exterior temperature”, “passenger door open”, etc… I tried to reproduce each of those cases to see which frame was causing the messages to appear on the screen. However, some were difficult to reproduce (like the low gas warning). So instead of trying to map every message manually, I tried to send manually the frame which made the message appear on the display. The frame would contain a number corresponding to a specific message to display on the screen. So I sent frames with every numbers from 0 to 255 and I successfully mapped all the messages the display could show (even those who did not apply to my car such as messages about the sunroof being stuck!)

Radio text. Many radio stations send some text over RDS containing a slogan or the name of the song currently playing. This text can contain up to 64 characters, way more than can be sent using a 8-bytes CAN frame. To work around this limitation, the radio cuts the text and send it in separate frames. Putting the frames together would reconstruct the original text. This was all working fine until I unplugged the screen. I would then receive only the first frame, then nothing. It turns out, the screen actually has some built-in logic and sends an acknowledgment frame when it receives the first part of the text. Once I made the Arduino send this special frame, I managed to reconstruct the full text even when the screen was unplugged!

There is some data I still miss, such as the oil temperature (I have no gauge displaying it, so it’s almost impossible to reverse-engineer!)

Displaying the data on screen

Once I gathered all the informations I needed to replace my old display, I had to find a way to display it on the color LCD screen. The Arduino is not powerful enough to drive a 7" color screen, so I needed to find another way.

I’m an iOS developer, so I figured: why not use an iOS device? This is probably less cost-efficient than using a Raspberry Pi but it had a few advantages over it. Being a mobile device, it’s optimized for low power consumption, which will avoid draining my car’s battery too fast. It has Wi-Fi and Bluetooth built-in (the Pi 3 was not released yet when I began working on this project). It can also temporarily run on battery when the car is starting (the 12V power to all nonessential elements during ignition).

These problems could still have been solved with a Raspberry Pi, by adding dongles and a battery. But iOS devices already contains everything needed, in a small form factor. I was also more familiar with iOS development, and UIKit is notoriously great to build nice user interfaces!

So I went on Leboncoin (basically France’s Craigslist) and bought an old iPod Touch with a broken screen for around 20€. I did not care about the screen since I’d use it exclusively through the HDMI output.

But how could I make an iPod Touch and an Arduino talk to each other? Little known fact: the Dock connector on iOS devices has a serial interface! However, it wasn’t easy to make my own serial cable. I did not have a male connector with all the necessary pins. So I decided to solder wires directly on the iPod’s logic board: