close-circle
Close
0%
0%

Smart car radio

I reversed engineered the canbus screen in my Clio and created a bluetooth remote control to listen to webradios without touching my phone.

Similar projects worth following
close
I like to listen to a webradio from my smartphone when I'm driving my car (Renault Clio). I love the playlist but it's not as comfortable as a regular car radio. My smartphone is connected to the car radio via bluetooth but I cannot do anything from the head unit to control the webradio app.
As a matter of fact, I replaced the stock radio from Renault about ten years ago for a better Alpine unit. Doing that, I lost the possibility of using the steering wheel remote control for the radio unit.
My project consist in two things:
- using the integrated display of the Clio (Update List model) to display the song title and the artist. For that, I revered engineered the canbus protocol that drive the display and used a bluetooth serial port to send the datas from the smartphone to the display
- repurposing the steering wheel remote control as a HID bluetooth keyboard to drive the smartphone. Thus I can drive my smartphone and keep my eyes on the road.

- The smartphone is connected to a (pretty crappy, but only 10 bucks) bluetooth audio receiver which is connected  with a stereo jack to the cd charger input of my Alpine car radio. I had nothing to modify on this part.


- The display receives the song title and the artist name from the smartphone using a bluetooth communication. The Tasker app for Android is used to extract text from the notification (A notification is sent from the webradio every time a new song starts). I had to slightly modify an existing plugin from Tasker to send the text to a bluetooth spp module. An arduino board relays the text from the bluetooth module to a canbus module. The canbus protocol used to drive the display has to be reverse engineered.


- The steering wheel remote control (3x3 keypad matrix) is repurposed to a HID bluetooth keyboard to drive the smartphone (Home, ESC, Alt+Tab and Alt+Shift+Tab). I added a DPAD in a 3D printed case (up, dow, left, right and Enter) with a scrolling wheel to change the volume on the smartphone. (As a bonus, I'd like to use the + and - buttons of the remote control to the Apline radio unit). The HID bluetooth part is managed by a RN42 module connected to an arduino board (for keypad matrix decoding, encoder and dpad inputs)

Licensing

Electronic hardware design : CERN OHL

The firmware and software are licensed under the GNU GPL

rmt_gerbers.zip

gerbers files from Easy EDA for the remote control bluetooth interface

x-zip-compressed - 21.17 kB - 10/18/2017 at 21:58

download-circle
Download

can_gerbers.zip

gerbers files from Easy EDA for the CAN bus bluetooth interface

x-zip-compressed - 21.91 kB - 10/18/2017 at 21:58

download-circle
Download

Adobe Portable Document Format - 32.87 kB - 10/16/2017 at 09:05

eye
Preview
download-circle
Download

Grove Bee Socket V0.9a.sch.pdf

Xbee form factor socket with 5V <-> 3.3V level converters

Adobe Portable Document Format - 43.50 kB - 09/28/2017 at 10:45

eye
Preview
download-circle
Download

RN42_bluetooth_cr_UG-v1.0r.pdf

RN42 bluetooth module (user guide)

Adobe Portable Document Format - 1.27 MB - 09/28/2017 at 10:40

eye
Preview
download-circle
Download

View all 7 files

  • 1 × Renault "Update List" display 8200380298 stock Clio II display (with canbus interface)
  • 1 × Arduino Uno (5V) Transfer text from bluetooth to canbus display
  • 1 × Canbus shield (5V) MCP2515 on SPI and MCP2551 or other canbus driver
  • 1 × bluetooth bee SPP bluetooth profile: receive text to display from the smartphone
  • 1 × Renault steering wheel remote control 820058695 arranged in 3x3 matrix keypad (the rotary switch on the back is not used) - BT keypad

View all 9 components

  • Fails with 3.3V and 8MHz (and bonus)

    Manu6 hours ago 0 comments

    Before I decided to make pcb's for my canbus and remote control boards, I wanted to use a 3.3V CAN SPI Mikroelktronika's Click board.

    The Click board needs to be modified to 16MHz for the MCP2515 Can interface to be compatible with the Arduino library. No big deal.

    To make the project smaller, I'd go to the Arduino Fio boards as I'm using bluetooth modules in a Xbee from factor:

    At first glance, it has only pros:

    - small form factor (compared to a stack of Arduino Uno + shield(s))

    - Xbee header

    - 3.3V like the bluetooth module and the CAN SPI Mikroelktronika's Click board...

    The last thing bited me: at 3.3V Arduino board usually have a 8MHz oscillator. It seems that the canbus library for Arduino doesn't like to work at 8MHz. I'm not sure of that, if you know where I failed, please contact me...

    I then tried to use a overclocked 3.3V 16MHz Arduino board by replacing the Arduino 8MHz resonator with a 16MHz one. I doesn't work neither as the bootloader is now at 115200 bauds instead 57600. I gave up at this stage and decided to make my own pcb to achievemy small form factor goal.

    Bonus fail:

    Murphy's law: when you do wiring, the only screw you have is inserted between your wire and the spacer:

    use double sided tape!

  • 2$ pcbs and gerber merging

    Manu6 hours ago 0 comments

    I'm evaluating the jlcpcb.com service. It's basically free : 2$ for 5 pcbs (100x100mm max). As I have 2 boards, the first one should be 2$ (for 5 pieces), but the 2nd one is 5$ (for 5 pieces). It isn't that much but the 2 boards combined are less than the 100x100mm authorized surface. I also wanted to try the GerberPanelizer.exe software discussed on the hackaday blog: https://hackaday.com/2017/06/21/panelizing-boards-the-easy-way/)

    So I took the gerbers from EasyEDA from the can and the remote boards and merged them on a single 100x100mm pcb. Here is the resulting image with 2 canbus and 2 remote control boards panelized:

    Here are 10 canbus and 10 remote control pcbs for 2$...

  • PCB for the bluetooth HID remote control

    Manu7 hours ago 0 comments

    I'm not a huge fan of the 0.1" dupont headers as they are not super reliable (no retaining clip, no keying for idiot proofing...):

    So, I made a PCB with IDC headers (10-pin header for the D-pad with clickable rotary encoder; 6-pin header for the Renault 3x3 matrix remote control).

    Here is the link to the EasyEDA project (where you can download gerber files and BOM):

    https://easyeda.com/moimeme4/mergeBT-4f19506c93c54159ba06ac12d7cdefa4

  • PCB for Canbus and bluetooth SPP

    Manu7 hours ago 0 comments

    i have a working prototype that displays everything I want from the bluetooth link of my smartphone to the canbus of the Renault "Update List screen". But as it is, it needs:

    - 1 Arduino Uno board

    - 1 Canbus shield (Seeedstudio)

    - 1 bee shield + BT module in Xbee form factor

    The stack is pretty bulky.

    So I decided to integrate all of this on a pcb (except the Arduino board: I will use a Pro mini as a module to solder on the pcb).

    It is an excuse to try the EasyEDA online editor. The "user experience" is pretty good except I don't like the fact that you need to be connected to use it. Here is the link to the project:

    https://easyeda.com/moimeme4/can-1577f49e7cb848ee872ee9e1ce39179f

    and a screenshot of the schematic and the pcb:

    (if you want to reproduce it, you can download gerbers and BOM from the link of the project).

    I'm using a automotive 5V regulator TPS7A6550 to prevent nasty spikes from the 12V accessory rail.

    The pcb's are ordered, I'm waiting for them to check if there is no mistake...

  • Car wiring

    Manu12 hours ago 0 comments

    I have 2 Arduino boards to fit in my car:

    - one is driving the CANbus display => it will be fitted in the glove box for ease of debugging

    - the second one is the bluetooth remote control for the smartphone => it will be fitted near the stearing wheel (where the remote control buttons are attached)

    The easiest is the remote control: a ribbon cable is running between the remote control attached to the steering and a compartment near the fuse box:

    The arduino board will sit here waiting for a firmware update.

    For the display, it is trickier as I have to remove the dashboard bezel. I runned a 4-wire cable (+12V acc, GND, CANH, CANl) between the display and the glove box:

    The arduino board with the canbus interface and the bluetooth spp module will be in a case in the glove box.

    It's time to find some box for my boards...

  • BT remote shrinkification

    Manu12 hours ago 0 comments

    I've modified the bluetooth remote control of the smartphone to be smaller. I did that with :

    - an Adafruit Pro Trinket board

    - a Xbee socket for the RN42 BT HID module

    I intend to fit this module wrapped in shrink tube inside a compartment of the car. It is near the fuse box and I can open it by just removing a bezel (no screws!) : it is pretty mandatory for the future updates of the firmware.

  • Retrieving infos from smartphone bluetooth

    Manu10/09/2017 at 21:51 0 comments

    Now I have a working canbus display, but how to get song titles from my smartphone and send it to the display:

    Here is a screenshot of the webradio (ouifm, but it should work with any music player that send notifications) app that I like to listen to:



    And a notification of the current song:

    The config for the autonotification interception in Tasker:


    The corresponding task that fires a bluetooth message at every new notification:


    The bluetooth serial plugin config (after this discussion: https://github.com/giech/arduinotaskerbluetooth/issues/2, the plugin is modified to my purpose and is available on google play https://play.google.com/store/apps/details?id=com.giechaskiel.ilias.bluetoothserialfromtasker, than you Ilias!):


    (The MAC address of the bt moule is blurred, I don't know if it really matters...)

    And finally, the Tasker profile on top of that:


    My first intention was to plug the SPP BT module on the hardware UART of the Arduino board to use indiffrently the USB or the BT link without code changes. But, as I still have some issues (some notifications are lost, ...), I finally plugged the SPP BT module as a software serial interface and I use the USB link to debug my program.

    The corresponding Github commit: b287b22

    I don't know yet why I'm dropping some notifications... I'm suspecting:

    • the notifications interception plugin: I may have configurate it poorly
    • the bluetooth module: there is so little data on this that I don't know if I'm using it properly: I will probably switch to another RN-42 (like on the bluetooth remote control) but as a SPP link this time
    • the software serial code: the NeoSWserial library gives a handler that I might call too slowly

    If anyone had dropping characters on this kind of SPP module, please let me know how do you solved that issue.

  • Reverse engineering the Renault Update List display - Part 3

    Manu09/28/2017 at 11:33 0 comments

    At this time, I can send text to my display on the canbus but I need the Renault car radio attached to the display to make it function properly. My goal is to throw away this head unit and use my Alpine one. I logged some canbus packets and I discovered a few things:

    - The 0x121 ID is acknowledged by the display with a 0x521 ID packet


    - There is a keep alive dialog between the head unit and the display: Can ID's 0x3CF and 0x3DF are send on a regular basis to check if the other one is attached on the canbus.


    For the other Can ID's, I was stucked. At this moment, I was fortunate enough to find a guy who did the same thing with the opposite goal: he wanted his custom display to work as the Renault one. His work is based on a very similar Megane AFFA3 display.

    I didn't understand everything despite the google trad, but most of the infos I was missing was here:

    https://translate.googleusercontent.com/translate_c?anno=2&depth=1&hl=fr&rurl=translate.google.com&sl=pl&sp=nmt4&tl=en&u=http://megane.com.pl/topic/47797-wyswietlacz-radia-update-list-protokol/page__hl__wy%25C5%259Bwietlacz%2520radia%2520update%2520list&usg=ALkJrhgGbHh_iqpb54xLhMpq9wUkCJVQuA

    Here is a log:

    FRAME 3cf :ID=975: LEN=8:69:01:A2:A2:A2:A2:A2:A2
    FRAME 3cf :ID=975: LEN=8:61:11:00:A2:A2:A2:A2:A2
    FRAME 3cf :ID=975: LEN=8:61:11:00:A2:A2:A2:A2:A2
    FRAME 3df :ID=991: LEN=8:7A:01:81:81:81:81:81:81 // start sync
    FRAME 3df :ID=991: LEN=8:79:00:81:81:81:81:81:81 // sync ok
    FRAME 3cf :ID=975: LEN=8:61:11:00:A2:A2:A2:A2:A2
    FRAME 3df :ID=991: LEN=8:7A:01:81:81:81:81:81:81
    FRAME 3df :ID=991: LEN=8:70:1A:11:00:00:00:00:01 // sync display
    FRAME 1c1 :ID=449: LEN=8:70:A2:A2:A2:A2:A2:A2:A2
    FRAME 4a9 :ID=1193:LEN=8:74:81:81:81:81:81:81:81 // response to a9
    FRAME 5c1 :ID=1473:LEN=8:74:81:81:81:81:81:81:81 // response to 1c1
    FRAME 3df :ID=991: LEN=8:70:1A:11:00:00:00:00:01
    FRAME 3df :ID=991: LEN=8:70:1A:11:00:00:00:00:01
    FRAME 121 :ID=289: LEN=8:70:81:81:81:81:81:81:81 // init display
    FRAME 1b1 :ID=433: LEN=8:70:81:81:81:81:81:81:81 // register display
    FRAME 5b1 :ID=1457:LEN=8:74:A2:A2:A2:A2:A2:A2:A2 // response to 1c1
    FRAME 521 :ID=1313:LEN=8:74:A2:A2:A2:A2:A2:A2:A2
    FRAME 3cf :ID=975: LEN=8:69:00:A2:A2:A2:A2:A2:A2
    FRAME 1b1 :ID=433: LEN=8:04:52:02:FF:FF:81:81:81 // enable display
    FRAME 5b1 :ID=1457:LEN=8:74:A2:A2:A2:A2:A2:A2:A2
    FRAME 1c1 :ID=449: LEN=8:02:64:0F:A2:A2:A2:A2:A2
    FRAME 121 :ID=289: LEN=8:10:1C:7F:55:55:3F:60:01
    FRAME 121 :ID=289: LEN=8:21:46:4D:20:20:20:20:20
    FRAME 121 :ID=289: LEN=8:22:20:10:52:41:44:49:4F
    FRAME 521 :ID=1313:LEN=8:30:01:00:A2:A2:A2:A2:A2
    FRAME 521 :ID=1313:LEN=8:74:A2:A2:A2:A2:A2:A2:A2
    FRAME 5c1 :ID=1473:LEN=8:74:81:81:81:81:81:81:81 // response to 1c1
    FRAME 3df :ID=991: LEN=8:79:00:81:81:81:81:81:81 // ping
    FRAME 3cf :ID=975: LEN=8:69:00:A2:A2:A2:A2:A2:A2 // pong
    FRAME 3df :ID=991: LEN=8:79:00:81:81:81:81:81:81 //...
    FRAME 3cf :ID=975: LEN=8:69:00:A2:A2:A2:A2:A2:A2
    FRAME 121 :ID=289: LEN=8:10:1C:77:65:55:1F:71:01
    FRAME 521 :ID=1313:LEN=8:30:01:00:A2:A2:A2:A2:A2
    FRAME 521 :ID=1313:LEN=8:30:01:00:A2:A2:A2:A2:A2
    FRAME 121 :ID=289: LEN=8:22:32:10:20:45:55:52:4F
    FRAME 121 :ID=289: LEN=8:24:00:81:81:81:81:81:81
    FRAME 521 :ID=1313:LEN=8:74:A2:A2:A2:A2:A2:A2:A2
    FRAME 121 :ID=289: LEN=8:21:45:55:52:4F:50:45:20
    FRAME 3df :ID=991: LEN=8:79:00:81:81:81:81:81:81
    FRAME 3cf :ID=975: LEN=8:69:00:A2:A2:A2:A2:A2:A2
    FRAME 3df :ID=991: LEN=8:79:00:81:81:81:81:81:81
    FRAME 3cf :ID=975: LEN=8:69:00:A2:A2:A2:A2:A2:A2
    FRAME 3df :ID=991: LEN=8:79:00:81:81:81:81:81:81
    FRAME 3cf :ID=975: LEN=8:69:00:A2:A2:A2:A2:A2:A2
    FRAME 3df :ID=991: LEN=8:79:00:81:81:81:81:81:81
    FRAME 3cf :ID=975: LEN=8:69:00:A2:A2:A2:A2:A2:A2
    FRAME 3df :ID=991: LEN=8:79:00:81:81:81:81:81:81
    FRAME 3cf :ID=975: LEN=8:69:00:A2:A2:A2:A2:A2:A2
    FRAME 3df :ID=991: LEN=8:79:00:81:81:81:81:81:81
    ...

     This init sequence is in the Arduino code https://github.com/manu-t/autoradio-interface/blob/master/UpdateListDisplay/UpdateListDisplay.ino

    With some tries and errors, I finally ended to send text to the display without the...

    Read more »

  • Reverse engineering the Renault Update List display - Part 2

    Manu09/28/2017 at 07:09 0 comments

    My setup to go deeper in the system:

    - the original Renault Update List car radio (I will replace it with an Alpine unit in my car, that's why I want to know the display protocol)

    - AFFA2 canbus display

    - logic analyzer with canbus interpreter

    - canbus sniffer with Arduino Uno & canbus shield (cf. previous log)

    On the PCB of the display, I discovered a PCA82C250 canbus driver on which I probed the canRx and canTx pins (1 & 3) with the logic analyzer and sniffed the CANL and CANH pins (6 & 7):

    To display some text on the screen, four 0x121 Can packets are sent from the head unit to the display. For example, the radio named "Europe 2" on the first preset (button "1" of the head unit, "P1" in the frame) I probed this:

    Corresponding data frames:

    msg11[8] = {0x10, 0x19, '~', 'q', 0x01, 'E', 'U', 'R'};
    msg12[8] = {0x21, 'O', 'P', 'E', ' ', '2', 0x10, ' '}; 
    msg13[8] = {0x22, 'E', 'U', 'R', 'O', 'P', 'E', ' '};
    msg14[8] = {0x23, '2', ' ', 'P', '1', 0x00, 0x81, 0x81};

    The first byte is used as a sort of numbering and follows a sequence: 0x10 -> 0x21 -> 0x22 -> 0x23. The text "Europe 2" is repeated (I don't know why, maybe legacy reasons...) 2 times and spread between the 4 frames.

    The first packet (0x10) starts by a fixed sequence of 5 bytes (0x10, 0x19, ~, q, 0x01) followed 3 bytes of text.

    The second packet starts with 0x21, then the remaining 5 bytes of text (spaces are inserted if less than 8 characters to display) then 0x10 and space.

    The third packets starts with 0x22 followed by 7 chars (spaces are inserted if less than 8 characters to display)

    The fourth packet starts with 0x23 followed by the 8th char (or space), a space, 'P' for preset, one char as preset number ('1' in this example). The frame is ended by 3 bytes 0x00, 0x81, 0x81

    It seems that, whatever the text is in packets 0x10 & 0x11, it is the text that is in packets 0x22 and 0x23 that is displayed.

  • Reverse engineering the Renault Update List display - Part 1

    Manu09/27/2017 at 14:12 0 comments

    I got curious about this display after browsing the web. Many people are having trouble between two versions (the previous one was a i2c display) and the "Update List" display which implements a canbus interface. This is a simple 8 characters display with great contrast. 2 integrated features: a clock and the external temperature.


    This is an AFFA2 model, ref 8200380298

    On different forums, I got the pinout of the display:

    1 - Autoradio {green} [3]
    2 - Autoradio {brown} [1]
    3 - NC
    4 - NC
    5 - NC
    6 - NC
    7 - Steering wheel remote control {violet}
    8 - Steering wheel remote control {green}
    9 - Steering wheel remote control {brown}
    10- Steering wheel remote control {yellow}
    11- Steering wheel remote control {pink}
    12- Steering wheel remote control {grey}
    13- NC
    14- NC
    15- ? Power ( + protected left light ) {blue}
    16- Autoradio {grey} [5]
    17- 12V (After contact) {yellow}
    18- Signal 0V External temparature probe {brown}
    19- Probe {green}
    20- Rheostat {violet}
    21- 12V Permanent {red}
    22- NC
    23- GND (0V) {black}
    24- ?
     

    The useful ones are pins 1 (canbus CANH), 2 (canbus CANL), 17 (+12V after contact), 21 (+12V permanent from battery) and 23 (GND).

    As a side note, the pins 7 to 12 are used to decode the steering wheel remote control matrix 3x3 keypad. I'm not gonna use that for my bluetooth HID smartphone remote control. One reason for that: I want to be able to detect multiple key presses, which is not supported on the original car radio. So, I will have to decode the matrix keypad on an ecternal microcontroller.

    I probed the canbus line (with the original car radio) with a logic analyzer and checked some useful frames. For example, when the screen displays FM 106.2:

    Fortunately, this is plain ASCII, it uses some CAN ID's and it is possible to start hacking.

    The CAN Id is 11 bits, and the baudrate is 500kpbs.

    In order to check how many CAN ID's are useful, I made a sniffer with an Arduino Uno and a seedstudio Canbus shield. A python script updates the datas in a table mode (one line per ID):

    Link to the Github page of the author of this very useful script: https://github.com/alexandreblin/python-can-monitor

    and the corresponding Arduino sketch: https://github.com/alexandreblin/arduino-can-reader

    In my setup, the constants are:

    // CS pin for CAN bus shield
    const int CS_PIN = 9;
    // CAN bus data rate
    const byte CAN_SPEED = CAN_500KBPS;

    We can see that there's only about 10 Can ID's in the protocol. Obviously, the 0x121 is used to send text on the display. As a CAN data frame is only 8 bytes and the display is 8 characters, I hoped that a single 0x121 frame could prints the entire text on the display, but it is not easy as that.

    Each time text changes, four 0x121 frames are send... More on that later.

View all 11 project logs

  • 1
    Overview

    From a high level, this is how the project is done

View all instructions

Enjoy this project?

Share

Discussions

Manu wrote 5 hours ago point

Sorry for the poor video quality, there is so little light at my shop that everything is blurry...

  Are you sure? yes | no

fresouza0 wrote 10/01/2017 at 18:56 point

Awesome project!!

Which logic analyzer did you use?

  Are you sure? yes | no

Manu wrote 10/01/2017 at 19:42 point

Thanks, it's an intronix logicport

  Are you sure? yes | no

janzo wrote 09/28/2017 at 09:10 point

Belle réalisation, impressionnant !!

Nice work, really impressing !!

  Are you sure? yes | no

Manu wrote 09/28/2017 at 09:39 point

Merci !

  Are you sure? yes | no

Manu wrote 09/25/2017 at 15:28 point

Hi,

I tried the esp32 but I'm very familiar (yet) with this chip. There a 2 problems that I cannot solve with the esp32:

- I cannot find a hid bluetooth profile example (https://github.com/espressif/esp-idf/issues/782#issuecomment-331900141)

- I don't know if it's possible to use simultaneously a bt spp and hid profiles (if someone has info about that...)

Once I could overcome these, I will give the esp32 a try.

Beyond that, I already had on hand the different bluetooth modules for Arduino so I made it in "Lego style".

  Are you sure? yes | no

mbt28 wrote 09/25/2017 at 15:04 point

Hi,

Instead of using this relatively complicated circuit, why dont you use ESP32? It is already have mcu + bt + wifi built in. You can talk to canbus through uart. And as far as I see there bluetooth AVCP apis to get playing song info.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates