Close

Reverse engineering the Renault Update List display - Part 3

A project log for 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.

ManuManu 09/28/2017 at 11:332 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 Renault car radio attached!

Discussions

Kerwin_weng wrote 09/10/2020 at 11:20 point

What is the connecting definition for this cluster?

  Are you sure? yes | no

Németh Csaba wrote 11/26/2017 at 13:53 point

Do you have to send 3df (keepalive) messages to use the display?

I cannot compile your .ino :(

Arduino: 1.8.5 (Linux), Alaplap:"Arduino Leonardo"

Felépítés beállítások megváltoztak, egész újraépítése
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino: In function 'void setup()':
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:156:40: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
   CAN.sendMsgBuf(0x5C1, NULL, 8, msg5c1);
                                        ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:157:40: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
   CAN.sendMsgBuf(0x4A9, NULL, 8, msg4a9);
                                        ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino: In function 'void loop()':
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:188:46: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
         CAN.sendMsgBuf(0x5C1, NULL, 8, msg5c1);
                                              ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:191:46: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
         CAN.sendMsgBuf(0x4A9, NULL, 8, msg4a9);
                                              ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino: In function 'void do_send_to(uint16_t, uint8_t*, uint8_t, uint8_t)':
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:248:56: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
     CAN.sendMsgBuf((unsigned long)(id), NULL, 8, packet);
                                                        ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino: In function 'void startSync()':
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:329:46: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
   CAN.sendMsgBuf(0x3DF, NULL, 8, startSyncMsg);    
                                              ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino: In function 'void syncOK()':
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:333:41: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
   CAN.sendMsgBuf(0x3DF, NULL, 8, pingMsg);
                                         ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino: In function 'void syncDisp()':
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:338:45: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
   CAN.sendMsgBuf(0x3DF, NULL, 8, syncDispMsg);
                                             ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino: In function 'void registerDisplay()':
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:343:49: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
   CAN.sendMsgBuf(0x1B1, NULL, 8, registerDispMsg);
                                                 ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino: In function 'void enableDisplay()':
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:348:47: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
   CAN.sendMsgBuf(0x1B1, NULL, 8, enableDispMsg);
                                               ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino: In function 'void initDisplay()':
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:353:45: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
   CAN.sendMsgBuf(0x121, NULL, 8, initDispMsg);
                                             ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino: In function 'void messageTest()':
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:362:39: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
   CAN.sendMsgBuf(0x121, NULL, 8, msg11);
                                       ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:364:39: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
   CAN.sendMsgBuf(0x121, NULL, 8, msg12);
                                       ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:366:39: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
   CAN.sendMsgBuf(0x121, NULL, 8, msg13);
                                       ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:368:39: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
   CAN.sendMsgBuf(0x121, NULL, 8, msg14);
                                       ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino: In function 'void messageTextIcons()':
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:379:38: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
   CAN.sendMsgBuf(0x121, NULL, 8, msg1);
                                      ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:381:38: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
   CAN.sendMsgBuf(0x121, NULL, 8, msg2);
                                      ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:383:38: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
   CAN.sendMsgBuf(0x121, NULL, 8, msg3);
                                      ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:385:38: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
   CAN.sendMsgBuf(0x121, NULL, 8, msg4);
                                      ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:387:38: warning: passing NULL to non-pointer argument 2 of 'byte MCP_CAN::sendMsgBuf(long unsigned int, byte, byte, byte*)' [-Wconversion-null]
   CAN.sendMsgBuf(0x121, NULL, 8, msg5);
                                      ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino: In function 'void setupBlueToothConnection()':
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:465:43: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
   sendBlueToothCommand("\r\n+STWMOD=0\r\n");                 // Configuration en esclave
                                           ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:466:59: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
   sendBlueToothCommand("\r\n+STNA=ERMABOARD_Bluetooth\r\n"); // Définir le nom du périphérique 
                                                           ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:467:43: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
   sendBlueToothCommand("\r\n+STAUTO=1\r\n");                 // autorise à se connecter automatiquement au dernier périphérique lié
                                           ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:468:43: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
   sendBlueToothCommand("\r\n+STOAUT=1\r\n");                 // Autorise les appareils liés à se connecter
                                           ^
/home/masina/Arduino/autoradio-interface-master/UpdateListDisplay/UpdateListDisplay.ino:471:40: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
   sendBlueToothCommand("\r\n+INQ=1\r\n");                    // Module visible en cas de recherche
                                        ^
/home/masina/Arduino/libraries/NeoSWSerial/src/NeoSWSerial.cpp: In member function 'void NeoSWSerial::listen()':
/home/masina/Arduino/libraries/NeoSWSerial/src/NeoSWSerial.cpp:155:7: error: 'TCCR2A' was not declared in this scope
       TCCR2A = 0x00;
       ^
/home/masina/Arduino/libraries/NeoSWSerial/src/NeoSWSerial.cpp:156:7: error: 'TCCR2B' was not declared in this scope
       TCCR2B = 0x03;  // divide by 32
       ^
exit status 1
Hiba a(z) Arduino Leonardo alaplapra fordításra.

  Are you sure? yes | no