Monorailcat

Autoradio Tuner List (4) : Écran LCD

icon 17/03/2018

J'ai toujours voulu afficher n'importe quoi sur l'afficheur au centre du tableau de bord, qui affiche normalement la station de radio et l'heure, et il se trouve que c'est tout à fait possible.
displaying funny words

Hardware
Ici, on a un autoradio Renault/VDO Tuner List (modèle 22DC259/62T, 77 00 434 422) et un afficheur Renault (82 00 028 364), avec un connecteur gris connecté au tableau de bord et à la radio, et un connecteur rouge connecté aux commandes situées sous le volant.

Je n'ai pas eu confiance dans les documentations que j'ai pu trouver, avec des couleurs de fils incorrectes, des brochages de connecteurs parfois à l'envers, différentes version de l'afficheur ou de l'autoradio.
pin identification
Mais ce n'est pas un problème, il suffit de démonter pour vérifier qu'on ne va rien faire de dangereux. On peut rapidement identifier les pins à la masse, ceux des alimentations, et certains signaux de puissance.

Connecteur Gris :
  1. NTC
  2. GND
  3. NC
  4. NC
  5. GND
  6. Éclairage feux? (in)
  7. Éclairage backlight? (in)
  8. +12V (contact?, in)
  9. +12V (permanent?, in)
  10. NC
  11. GND
  12. LCD_ENABLE (12V, in)
  13. SDA (TTL, io)
  14. SCL (TTL, io)
  15.  !MRQ (TTL, io, active-low)

Connecteur Rouge (TTL) :
  1. NC
  2. NC
  3. NC
  4. NC
  5. NC
  6. NC
  7. NC
  8. NC
  9. Commun 1
  10. Retour A
  11. Commun 2
  12. Retour B
  13. Commun 3
  14. Retour C
  15. NC

Ça permet de comprendre la majorité du câblage :
lcd + stalk + head unit connections

Et on peut aussi reverse-engineerer la matrice des boutons utilisés pour les commandes au volant:
FonctionPin communPin retour
OKA1
VOL-A2
VOL+A3
Source LB1
Source RB2
PauseB3
Molette 1C1
Molette 2C2
Molette 3C3
Curieusement, la molette n'est qu'un interrupteur rotatif à 3 positions, ça suffit à détecter le sens de rotation ça donne l'impression de bien plus de positions (6 par tour).

Câble
Dans ce cas, la solution la plus pratique est de prendre une rallonge avec des câbles mini-ISO branchés sur l'autoradio, de couper chaque fils et de les brancher sur un connecteur à 0.1", pour y mettre des cavaliers pour une connection directe, des fils en Y pour espionner le bus ou bien des fils vers un MCU ou un analyseur logique.
man in the middle cable

Connecteur jaune C1 :
  1. SDA (TTL 5V)
  2. SCL (TTL 5V)
  3.  !MRQ (TTL 5V)
  4. LCD_ENABLE (+12V)
  5. GND
On peut se contenter de n'utiliser que ce connecteur pour afficher ce que l'on veut, et reverse-engineerer une partie du protocole.
tuner list i2c bus reverse engineering in-situ
Comme je ne voulais pas décharger la batterie ni passer plusieurs heures dans le froid, j'ai préféré démonter l'afficheur et l'autoradio pour les utiliser à l'intérieur.
tuner list i2c bus reverse engineering on a bench


Protocole
Ça nous avance bien de connaître le matériel, mais il faut encore comprendre comment l'autoradio communique avec l'écran LCD.
Pour ça, on va utiliser un analyseur logique (Cypress FX2 et sigrok/pulseview) et regarder tout ce qui passe sur le bus i2c.
cheap logic analyzer

On peut voir que le bus i2c fonctionne à 7.14kHz et que le signal !MRQ est constamment tiré à 0 avant que quelque chose ne soit transféré sur le bus.

En débranchant le signal MRQ de chaque côté, on peut voir que l'afficheur le force à 0 en attendant une trame de l'autoradio, mais que l'autoradio le force aussi à 0 avant d'envoyer une tram à l'autoradio. On peut aussi voir que l'autoradio est maître sur le bus i2c, et identifier l'adresse de l'écran LCD (0x23).

On peut voir plusieurs messages de 2 octets de long [0x01, 0x10] ou [0x01, 0x11], demandés au moins toutes les 500ms par l'autoradio (initié par l'afficheur qui tire le signal MRQ à 0, puis répond lorsque l'autoradio envoie une requête).
i2c line on idle

Commandes au volant
Il y a aussi une trame répondue par l'afficheur lorsqu'on appuie sur un bouton des commandes au volant, et qui permet de déduire le code de chacune des commandes au volant. L'afficheur tire le signal MRQ à 0, l'autoradio envoie une requête, puis l'afficheur envoie la trame correspondant aux boutons pressés.
i2c line button
Boutonoctet 0octet 1octet 2octet 3octet 4action
OK0x040x820x910x000x00press
OK0x040x820x910x000x40hold
Source R0x040x820x910x000x01press
Source R0x040x820x910x000x81hold
Source L0x040x820x910x000x02press
Source L0x040x820x910x000x82hold
Volume +0x040x820x910x000x03press
Volume +0x040x820x910x000x43hold
Volume -0x040x820x910x000x04press
Volume -0x040x820x910x000x44hold
Pause0x040x820x910x000x05press
Wheel up0x040x820x910x010x41
Wheel down0x040x820x910x010x01
Les valeurs 0x41 et 0x42 pour le dernier octet sont aussi interprétées par l'autoradio comme les boutons Source R et Source L maintenus appuyés, et il n'y a pas de code lorsqu'on maintient appuyé le bouton Pause ou pour la molette.

Affichage
L'afficheur est rafraichi uniquement en cas de besoin, on peut l'observer en appuyant sur un bouton de l'autoradio, qui va forcer le signal MRQ à 0, puis va envoyer une trame entre 13 et 16 octets avec les caractères à afficher.
i2c line display
Affichage12345678910111213141516
98.50x0f0x900x7f0x290xff0x3f0x350x810x200x200x200x200x390x380x350x20
CASS [=]0x0f0x900x7f0x550xff0xff0x600x010x430x410x530x530x200x040x050x06
BAYERN 30x0f0x900x7f0x550xff0x3f0x750x010x420x410x590x450x520x410x200x33
Bingo ! Les trames à partir de l'octet 9 ressemblent à de l'ASCII (les caractères clignotent si le MSB est à 1), l'octet 7 permet d'afficher le point décimal et le digit de mémoire/piste, et l'octet 6 permet d'afficher les pictogrammes Tuner Preset, Tuner Manu, Dolby et MSS.

Programme
On va remplacer l'autoradio par un Arduino Mega (n'importe quel micro-contrôleur avec un périphérique i2c et des IO TTL suffit), pour pouvoir écrire sur l'afficheur et lire l'état des boutons.

Avec un Atmel AVR, il faut forcer le bitrate/prescaler à environ 7kHz avec les lignes suivantes:
void conf() {
TWBR = 0xff;
TWSR = 0x01;
}


Comme c'est un programme de test qui n'a qu'une seule fonction et un MCU surpuissant pour son utilisation, il est possible d'écrire un code peu optimisé (polling au lieu d'interruptions, copy/paste).

On va initialiser l'écran en envoyant quelques trames [0x01, 0x10] et [0x01, 0x11], puis on peut écrire un peu ce qu'on veut :
void writerandom(byte *data, int len) {
while(digitalRead(2)); // polling the MRQ line
Wire.beginTransmission(0x23);
conf(); // overwrites the bitrate/prescaler after the Wire lib configures the i2c
Wire.write(data, len);
Wire.endTransmission();
}

Dans ce cas, on peut commencer par copier/coller des trames récupérées en sniffant celles envoyées par l'autoradio, puis on va reverse-engineerer le protocole complet en bouclant sur tous les caractères entre 0x00 et 0xFF, et en testant les pictogrammes.

On va aussi pouvoir lire l'état des boutons, qui sont des trames de 5 octets :
void read01() {
while(digitalRead(2)); // polling the MRQ line, pulling the MRQ line low and waiting 500us also works
conf(); // overwrites the bitrate/prescaler after the Wire lib configures the i2c
Wire.requestFrom(0x23, 5);
TWBR = 0xff;
TWSR = 0x01; // 0x00 appears to work as well
for(i = 0; i < 5; i++) {
READDATA[i] = Wire.read();
}
}


Références

icon Tags de l'article : , , , , ,

3 comments

F0cks - 20/09/2018 à 10:21:02

Évidement t as affiché un truc intelligent sinon ça sert à rien« D

@répondre #lien

FHO Corp - 22/10/2018 à 21:58:38

Hello

Je suis intéressé sur comment faire pour afficher du texte sur l'écran LCD

J'ai prévu de faire un dashboard basé sur un raspberry Pi sur ma clio 2. Si jamais tu peux me donner quelques indications« )

@répondre #lien

Xavier Bourgeois - 29/10/2018 à 19:31:45

@ FHO Corp: une autre partie devrait arriver, mais je la posterais quand ça sera fonctionnel et utilisable.
L'article et les références doivent être suffisants pour faire la même chose soi-même.

@répondre #lien

icon Flux RSS des commentaires de cet article

Notice : Your comment will be visible after approbation by the webmaster.