Ordinateur de bord pour Subaru

Bonjour à tous.

Je viens vers vous pour vous présenter mon projet d'une part, et ensuite requérir de l'aide d'autre part. :sweat_smile:

Alors, tout d'abord, afin de pallier au manque d'infos disponible au tableau de bord de ma Subaru Legacy turbo, j'ai entrepris de me faire mon propre ordinateur de bord avec afficheur lcd. Je vous passe les détails pour intégrer tout le basard dans le compte tours, mais en gros, ça n'a pas été simple.

A aujourd'hui, j'ai atteints la 1ère étape de mon projet: Une intégration la plus proche de l'origine possible. J'ai un "menu défilant" (menu est un bien grand mot) sur l'écran actionné par un bouton que j'ai intégré au niveau d'un cache de la commande de ventilation (emplacement d'une option que je n'ai pas). J'ai également intégré 2 leds dans le compte tours: Une RGB informant sur la température d'huile (bleu à vert = trop froid pour attaquer; jaune à rouge = ralentir voir stopper) et une rouge pour le shift light (je vais faire un peu de piste avec donc bon... et puis c'est pour le fun aussi).

En simulant différentes sondes, sur le principe, ça donne ça:

J'ai ensuite recherché et trouvé sur le net des sondes dédiées à l'automobile et non présentes d'origine sur la voiture: Température et pression d'huile. Il a fallu les calibrer, ce qui n'a pas été simple pour la température ( Mais j'arrive à une précision de l'ordre du degré à 100° ce qui est bien mieux que les manos vendus tous près et beaucoup plus chers dans le commerce).

En attendant de passer à l'étape 2 (qui m'apportera un paquets d'infos), et pour faire fonctionner mon shift light, j'ai repiqué l'alimentation du compte tours: La tension varie de façon continue et largement sous les 5V. J'ai moyenné le signal pour le stabiliser et juste ajouté un coefficient pour retomber sur mes pattes.

Ca donne ça, une fois en place:

Sur la vidéo, les sondes ne sont pas encore raccordées. Mais depuis, tout est bien rangé et fonctionnel!

Connections Arduino Leg.xls (1.53 MB)

Je vous mets ci-dessous le programme en question. Il n'est peut être pas super orthodoxe pour les pros, mais il a le mérite de fonctionner correctement! XD

// Sonde pression1301 fonctionnelle
// sonde température Zeitronix fonctionnelle, sonde grove fonctionnelle
// Intro Subaru
// variation affichage avec bouton
// RPM par prise signal sur alim compt tours
// Thuile ok à 75°
// Thuile chaude à 120° et trop chaude à 140°

 #include 

LiquidCrystal lcd(7,8,9,10,11,12);

 byte subaru1[8] = {
 B00100,
 B00100,
 B01110,
 B11111,
 B01110,
 B00100,
 B00100,
 B00000
 };
 byte subaru2[8] = {
 B00000,
 B00000,
 B00000,
 B00000,
 B00000,
 B00010,
 B00111,
 B00010
 };
 byte subaru3[8] = {
 B00000, 
 B00000, 
 B00000,
 B00010,
 B00111,
 B00010,
 B00000,
 B00000
 };
 byte subaru4[8] = {
 B01000,
 B11100,
 B01000, 
 B00010,
 B00111,
 B00010,
 B00000,
 B00000
 };
 byte subaru5[8] = {
 B01000,
 B11100, 
 B01000,
 B00000,
 B00000,
 B00000,
 B00000,
 B00000
 };
 byte subaru6[8] = {
 B10000,
 B01000,
 B00100,
 B00010,
 B00010,
 B00001,
 B00001,
 B00001
 };
 byte subaru7[8] = {
 B00001,
 B00001,
 B00001,
 B00010,
 B00010,
 B00100,
 B01000,
 B10000
 };

 int ledRougePin = 4;
 int ledVertPin = 5;
 int ledBleuPin = 6;

 float Thuile=0;
 float Phuile=0;
 float volthuile=0;
 float varThuile=1;
 int c=0;
 int x=0;
 int y=0;
 int z=0;

 float psi=0;
 float voltPhuile=0;

 float tempin; //calcul température habitacle
 int B=3975; //calcul température habitacle
 float resistance; //calcul température habitacle

 float Thuilemax=-50;
 float Phuilemax=0;
 float Phuilemin=10;
 int bouton=0;
 #define valeurMax 6

 const char* TempIn="T. In";
 const char* TempEx="T. Ex";
 const char* Batt="Batt.";
 const char* Rpm="RPM";
 char Unite='0';
 const char* Intitule=0;
 float t=0;

 int RPM=0;
 float RPMfloat=0;
 int ledRPMPin = 2;


 const int numReadingsR = 1500 ; // Nombre de relevés pour la moyenne rpm
 int readingsR ; // Variable lecture pour le relevé tension
 int indexR = 0 ; // position dans la création de la moyenne 
 float totalR = 0 ; // Total en cours
 float averageR = 0 ; // La moyenne


void setup(){
 pinMode(3, OUTPUT); // 5V pour rétroéclairage (option variation d'intensité)
 digitalWrite(3, HIGH);
 lcd.begin(16, 2); // paramètre lcd

 pinMode(13,INPUT); // bouton sur pin 13
 digitalWrite(13, HIGH); // alimentation pin 13

 pinMode( ledRougePin, OUTPUT );
 pinMode( ledVertPin, OUTPUT );
 pinMode( ledBleuPin, OUTPUT );
 pinMode( ledRPMPin, OUTPUT );


 digitalWrite( ledRougePin, HIGH ); 
 digitalWrite( ledVertPin, HIGH ); 
 digitalWrite( ledBleuPin, HIGH );

 lcd.clear();

 lcd.createChar(1, subaru1);
 lcd.createChar(2, subaru2);
 lcd.createChar(3, subaru3);
 lcd.createChar(4, subaru4);
 lcd.createChar(5, subaru5);
 lcd.createChar(6, subaru6);
 lcd.createChar(7, subaru7);


 lcd.setCursor(0,0);
 lcd.print((char)1); lcd.print((char)2);
 lcd.setCursor(3,0); lcd.print((char)6);
 lcd.setCursor(3,1); lcd.print((char)7);
 lcd.setCursor(6,0); lcd.print("SUBARU");
 lcd.setCursor(0,1); lcd.print((char)3);lcd.print((char)4); lcd.print((char)5);

 delay(3000); // Ecran vide 5 seconde
 lcd.clear();

 for (int positionCounter = 0; positionCounter < 12; positionCounter++) {
 // Décalle le curseur de 12 colonnes vers la gauche
 lcd.scrollDisplayLeft(); 
 }

 lcd.print("LEGACY TURBO");

 for (int positionCounter = 0; positionCounter < 14; positionCounter++) {
 // Décalle le texte vers la droite et le centre
 lcd.scrollDisplayRight(); 
 // wait a bit:
 delay(150); }

 // Réinitialisation de l'affichage et de la position du curseur
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print(" LEGACY TURBO");
 delay(1000);

 lcd.setCursor(16,1);
 lcd.print("Bienvenue a bord");

 for (int positionCounter = 0; positionCounter < 16; positionCounter++) {
 // scroll one position right:
 lcd.scrollDisplayLeft(); 
 // wait a bit:
 delay(150); }

 lcd.clear();
 lcd.setCursor(2,0);
 lcd.print("LEGACY TURBO");
 lcd.setCursor(0,1);
 lcd.print("Bienvenue a bord");
 delay(2000);
 lcd.clear();
}

 void loop(){
 // Interprétation sonde temperature grove
 resistance=(float)(1023-analogRead(A4))*10000/analogRead(A4);
 tempin=1/(log(resistance/10000)/B+1/298.15)-273.15;

 volthuile=analogRead(A1)*5.0/1024.0;
 varThuile=0.5608*volthuile+1.4498;
 if(varThuile<2.02){Thuile=((440.12*pow(volthuile,4)-1493.9*pow(volthuile,3)+1881.8*pow(volthuile,2)-1083.8*volthuile+335.06))/varThuile;}
 if(varThuile>2.02){Thuile=((0.1541*pow(volthuile,4)-2.6435*pow(volthuile,3)+17.306*pow(volthuile,2)-60.03*volthuile+124.59))/varThuile;}

 voltPhuile=analogRead(A0)*5.0/1024.0;
 psi=(37.5*(voltPhuile))-18.75;
 Phuile=psi/14.51; // conversion en bar
 if (Phuile<0) {Phuile==0;}

 if(Thuile<75) {Thuilefroide();}
 if(Thuile>75 and Thuile<110) {Thuileok();}
 if(Thuile>115 and Thuile<130) {Thuilechaude();}
 if(Thuile>130) {Thuiletropchaud();}

 if (Thuile>Thuilemax) {Thuilemax=Thuile;}
 if (Phuile>Phuilemax) {Phuilemax=Phuile;}
 if (Phuile 
 // Convertir le signal du compte tours (moyenné pour lisser l'affichage)
 while(indexR< numReadingsR) { 
 readingsR = analogRead (5) ;
 totalR = totalR + readingsR ; 
 indexR = indexR + 1 ; }

 indexR = 0 ;
 averageR = totalR / numReadingsR ; 
 RPMfloat=averageR*10.3;
 RPMfloat=RPMfloat/10;
 RPM=RPMfloat;
 RPM=RPM*10;
 totalR=0;

 if(RPM<=6000) {delay(200);}
 if(RPM>6800) {delay(300);}
 if(RPM>6000 and RPM<6800) { for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=50) { 
 analogWrite(ledRPMPin, fadeValue); 
 delay(10); 
 } 
 for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=50) { 
 // sets the value (range from 0 to 255):
 analogWrite(ledRPMPin, fadeValue); 
 // wait for 30 milliseconds to see the dimming effect 
 delay(10); 
 } }

 if(RPM>6800) {digitalWrite(2, HIGH); }


 if (digitalRead(13)==HIGH) // incrément x par appui bouton
 { lcd.clear();
 if (bouton delay(200);
 while((digitalRead(13)==HIGH));
 } 

 switch (bouton) { // en fonction de la valeur de x, on modifie l'affichage
 case 0: Intitule=Batt; t=0; Unite='V'; break; 
 case 1: Intitule=TempIn; t=tempin; Unite=(char)223; break;
 case 2: Intitule=TempEx; t=0; Unite=(char)223; break;
 case 3: Intitule=Rpm; t=RPM; Unite=' '; break;
 case 4: lcd.setCursor(0,0); lcd.print("T huile maxi:");
 lcd.setCursor(0,1); lcd.print(Thuilemax);
 lcd.print((char)223); lcd.print("C"); break;
 case 5: lcd.setCursor(0,0); lcd.print("P huile maxi:");
 lcd.setCursor(0,1); lcd.print(Phuilemax);
 lcd.print("b"); break; 
 case 6: lcd.setCursor(0,0); lcd.print("P huile mini.");
 lcd.setCursor(0,1); lcd.print(Phuilemin);
 lcd.print("b"); break;}

 // Affichage sur lcd
 if (bouton<4) { 
 lcd.clear();
 lcd.setCursor(0,0); lcd.print("OilT");
 lcd.setCursor(6,0); lcd.print("OilP"); 
 lcd.setCursor(11,0); lcd.print(Intitule);
 lcd.setCursor(0,1);
 if(Thuile<100) {lcd.print(Thuile, 1);} else {lcd.print(Thuile, 0);}
 lcd.print((char)223);
 lcd.setCursor(6,1); lcd.print(Phuile, 1); lcd.print("b");
 lcd.setCursor(11,1);
 if(Intitule==Batt || Intitule==TempEx) {lcd.print(" No");}
 if(Intitule==TempIn){lcd.print(t, 1);}
 if(Intitule==Rpm){lcd.print(t, 0);}
 if(Intitule==TempIn || Intitule==Rpm){lcd.print(Unite);}
 }
 delay(50);
}


void Thuilefroide(){
 int iBleu = Thuile*3.1875; iBleu>0;
 int iVert = 255 - iBleu;
 analogWrite( ledBleuPin, iBleu );
 analogWrite( ledVertPin, iVert );
 }

void Thuileok(){
 digitalWrite( ledRougePin, HIGH ); 
 digitalWrite( ledVertPin, HIGH ); 
 digitalWrite( ledBleuPin, HIGH );

 if (y==0) {
 x=0;
 y++;
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print(" GO ");
 for (x==0; x<6; x++) {
 lcd.setCursor(0,1);
 lcd.print(" ! ! ! ! ! ! ");
 delay(250);
 lcd.clear(); lcd.setCursor(0,0); lcd.print(" GO ");
 delay(250); lcd.setCursor(0,1); lcd.print(" ! ! ! ! ! ! "); } 
}}

void Thuilechaude(){
 int iVert = Thuile*6-593; iVert>127;
 analogWrite( ledRougePin, 0 );
 analogWrite( ledVertPin, iVert );
 }

void Thuiletropchaud(){
 digitalWrite( ledRougePin, LOW ); 
 digitalWrite( ledVertPin, HIGH ); 
 digitalWrite( ledBleuPin, HIGH );

 if (z==0) {
 x=0;
 z++;
 lcd.print("ARRET IMPERATIF");
 for (x==0; x<6; x++) {
 lcd.setCursor(0,1);
 lcd.print(" ! ! ! ! ! ! ");
 delay(250);
 lcd.clear(); lcd.setCursor(0,0); lcd.print("ARRET IMPERATIF");
 delay(250); lcd.setCursor(0,1); lcd.print(" ! ! ! ! ! ! ");}
 }}

En Pièce jointe, je vous laisse un fichier avec quelques infos sur les branchements, le matériel utilisé et le calibrage de la sonde de température d'huile.

Me reste à aborder la partie 2!

Connections Arduino Leg.xls (1.53 MB)

Concernant la partie 2, c'est là que ça se complique et que je vais avoir besoin de vous...

L'ECU de la voiture récupère un tas d'infos qu'il garde en égoiste: régime, vitesse, température d'eau, pression turbo et plein d'autres trucs.

Concernant la partie physique, pas de soucis: Il y a une prise diagnostique et je sais sur quelles broches brancher le GND, Tx et Rx.
J'ai pu tester avec un câble usb et un logiciel de diag sur mon pc (Evoscan pour ceux qui connaissent) et ça marche avec ces mêmes branchements.

Le problème, c'est le langage, caractéristique de Subaru (pas d'OBD sur les Legacy en 1993). Il s'agit du SSM. Il permet d'échanger des infos avec l'ECU avec un protocole à priori simple: On envoie un ordre à l'ECU pour qu'il renvoie l'info stockée à une adresse donnée dans la mémoire de l'ECU.

Il y a donc un code spécifique à envoyer pour chaque paramètre que l'on veut lire.

Concernant la procédure à suivre, tout est expliqué ici:
http://www.alcyone.org.uk/ssm/protocol.html

Les différentes adresses sont ici:
http://www.alcyone.org.uk/ssm/ecureverse.html

J'ai donc à priori tout ce qu'il me faut. Mais j'atteints mes limites. Je ne sais absolument pas comment rédiger mon code sous Arduino pour ressortir une info exploitable.

Help! Par exemple pour lire la température de l'eau sur l'écran? Le mieux que j'ai réussi à obtenir est un symbole chinois puis plus rien au rafraichissement...

Bonsoir
Joli tuture, joli travail !

Ton problème ne me semble pas trop difficile.

  • Électriquement : d'après la page "Building a PC adapter", l'interface est en niveau TTL puisque pour connecter à un PC ils prposent de fabriquer un convertisseur TTL-RS232. Ca tombe bien, l'Arduino est en TTL. Toutefois ils citent avoir eu des problèmes de qualité de signal et proposent d'utiliser un comparateur basé sur LM358 pour nettoyer le signal. Tu peux reprendre la même chose ou bien utiliser un buffer a trigger de schmidt type 74HC74. Mais comme ce dernier est un inverseur, il te faudra en mettre 2 en série pour retrouver la bonne polarité.

  • Protocole : c'est du protocole série asynchrone standard. Tu peux le gérer soit avec la liaison série standard de l'Arduino, soit avec SoftSerial qui va te permettre de créer une liaison série sur n'importe quelle paire de pin de l'Arduino. Il faudra configurer au bon bitrate (1953, ou sont-ils aller chercher cela).

  • Soft : il va falloir envoyer des trames au bon protocole. Le plus simple est de préparer les trames dans un tableau de byte et d'utiliser la fonction SoftwareSerial::write( (const uint8_t*) buffer, size_t len ); pour envoyer le paquet. Et d'utiliser SoftwareSerial::read() ou l'un des variantes pour recevoir.

Supposons qu'on veuille lire :
F10 128C THROTTLE POSITION SENSOR throttle%=(value*100)/255

Ca pourrait ressembler à cela (j'ai pas la Subaru pour essayer donc c'est du codage en aveugle) :

#include <SoftwareSerial.h>

byte const SerialToECU = 5;
byte const SerialFromECU = 6;

SoftwareSerial ECU( SerialFromECU, SerialToECU);

void setup( void )
{
  ECU.begin( 1953 );
}

byte ECUBuffer[4];
#define THROTTLE_POSITION_SENSOR  0x128C

void loop( void )
{
  Serial.print ( "Reading THROTTLE POSITION SENSOR :" );
  byte data = ReadFromECU( THROTTLE_POSITION_SENSOR );
  Serial.println( data );
  
  delay( 2000 );
}


byte ReadFromECU( uint16_t address )
{
  ECUBuffer[0] = 0x78;
  ECUBuffer[1] = address >> 8; // Address MSB
  ECUBuffer[2] = address & 0xFF; // address LSB
  ECUBuffer[3] = 0x00;
  
  ECU.write( ECUBuffer, 4 );
  
  ECU.readBytes( (char*)ECUBuffer, 3 );
  
  return ECUBuffer[2];
}

Ca compile
Ca manque un peu de gestion des cas d'erreur (timeout sur la lectur du résultat par exemple).

Mais ca devrait te donner des idées.

effectivement, on s'emmerde avec des capteurs puis on découvre qu'on a tout ce qu'il faut sous la main...

[Projet] Un tableau de bord numérisé - Français - Arduino Forum (voir quelques pages plus loin pour l'évolution)

J'ai un vieux calculateur sur ma R21, donc un protocole spécifique renault à 62500bds inversé pas très bien documenté, mais il me fournit tout ce dont j'ai besoin (régime moteur, temp in / out,, avance allumage, temps d'injection...), sauf la vitesse et tout ce qui concerne l'essence. avec un ODBII, tu as plus de chances de trouver des infos et toutes les valeurs dont tu as besoin.

c'est de toutes façon un long projet, mais ça vaut le coup!

Super_Cinci:
effectivement, on s'emmerde avec des capteurs puis on découvre qu'on a tout ce qu'il faut sous la main...

[Projet] Un tableau de bord numérisé - Français - Arduino Forum (voir quelques pages plus loin pour l'évolution)

J'ai un vieux calculateur sur ma R21, donc un protocole spécifique renault à 62500bds inversé pas très bien documenté, mais il me fournit tout ce dont j'ai besoin (régime moteur, temp in / out,, avance allumage, temps d'injection...), sauf la vitesse et tout ce qui concerne l'essence. avec un ODBII, tu as plus de chances de trouver des infos et toutes les valeurs dont tu as besoin.

c'est de toutes façon un long projet, mais ça vaut le coup!

Effectivement. Bien que dans le cas présent, je n'avais pas le choix d'installer des sondes pour l'huile. Par contre, pour le reste...
Si je franchis le cap, mon projet sera abouti.

Beau travail :slight_smile:

supertotof78:
Help! Par exemple pour lire la température de l'eau sur l'écran? Le mieux que j'ai réussi à obtenir est un symbole chinois puis plus rien au rafraichissement...

Alors d'après ce que j'ai compris, il faut faire un truc du genre:

int temperature;

void setup()
{
  Serial.begin( 1953, SERIAL_8E1 );

  //envoyer la commande pour lire la T°
  Serial.write( 0x78 );
  Serial.write( 0x11 );
  Serial.write( 0x85 );
  Serial.write( 0x00 );
}

void loop()
{
  //reception de la réponse:
  if (Serial.available() == 3)
    if ( Serial.read() == 0x11 && Serial.read() == 0x85 )
      temperature = (int)Serial.read() - 50;
}

Enfin je ne suis pas vraiment sûr, il y a une colonne "Mode" mais aucune description.

barbudor:
Bonsoir
Joli tuture, joli travail !

Merci! Mais je suis vraiment un newbee côté programmation. Je me débrouille avec un peu de logique et de vagues souvenirs de programmation sur C. Mais dès qu'il faut approfondir... Par exemple, dans le cas présent, je ne maitrise pas du tout les notions de paquets d'infos à transmettre etc... En regardant ton code (merci au passage, j'essaie de tester ça demain) je vois où ça doit mener globalement, mais dans le détail, j'ai du mal. Je vais m'y repencher à tête reposée.

Si tu pouvais me faire une explication de texte... :sweat_smile:

Pour le convertisseur TTL-RS232, c'est ce que j'ai utilisé pour faire tourner evoscan sur mon portable. Ca fonctionne à priori pas mal.

Je pense que tu as compris l'essentiel
Tu as choisit d'envoyer les octets 1 à 1 alors que moi je les prépare dans un tableau puis j'envoie le tableau d'un coup.
mais le principe est le même.

Par contre : tempC=value-50
value étant la laveur retournée par l'ECU, tu as mis un signe plus alors qu'il faut un signe moins.

Ensuite, pour que ca s'affiche comme il faut, il faut que ce soit dans un int

int temperature = (int)Serial.read.read() -50;

Car un "print" sur un int va afficher la valeur alors que un "print" sur un char ou un byte va afficher le caractère dont le code ASCII est dans la valeur.

Mais un truc m'inquiete : tu utilise Serial et non pas un SoftwareSerial.
Quel Arduino utilises tu ?
Normalement il n'y a qu'un seul Serial, donc où/comment affiches tu la valeur ?

Je pense que tu te trompes de personne Barbudor :wink:

Je ne crois pas que son écran LCD utilise le Serial, donc pas besoin de SoftSerial. Et puis, sur une arduino mega il y a 4 Serials :slight_smile:

Je corrige les petites erreurs dans le code, merci.

Oui, il y a erreur sur les posteurs.

Mais pour info, j'utilise Arduino Uno. À terme, j'utiliserai mon lcd. Mais pour les tests, je peux envoyer vers le pc en utilisant ton code. Si tu peux me faire un cours...

barbudor:
bien utiliser un buffer a trigger de schmidt type 74HC74.

Un petit coup de fatigue barbudor....
Je pense que tu voulais dire:
utiliser un buffer a trigger de schmidt type 74HC14

Oups.
Bug de clavier bien sur. Je n'aurais jamais fait cela consciemment.....
Je suis sûr d'avoir tapé 74HC14 :smiley:

barbudor:
Oups.
Bug de clavier bien sur. Je n'aurais jamais fait cela consciemment.....
Je suis sûr d'avoir tapé 74HC14 :smiley:

je suis bien d'accord avec toi Barbudor , en aucun cas cela ne peut et ne saurait venir de l'interface chaise/clavier :grin:

Bonjour,

Alors j'ai essayé ton code bardudor.

Le moniteur m'affiche bien quelque chose: "Reading THROTTLE POSITION SENSOR :" (normal) puis une valeure: 140.
Par contre, elle ne varie jamais, malgré des accélérations à différents régimes et sur différentes plages de temps.

Ah!

Je n'aime pas ne pas comprendre. STP, peux-tu m'expliquer le rôle de chaque ligne de ton code? :blush:

Tu as testé mon code?

Je suppose que tu as adapté notamment les broches SerialToECU et SerialFromECU à ton cas ?

Il faudrait procéder plus pas à pas. Peut être quelque chose d'autre ne marche pas.
Je suggère d'autre essais :

  1. Essayer d'autres variables en changeant le code hexa.
    la température par exemple.
    ou la tensiond e la batterie

  2. Faire un code moins formel mais plus à même de faire du debug similaire à celui de guix

#include <SoftwareSerial.h>

byte const SerialToECU = 5;
byte const SerialFromECU = 6;

SoftwareSerial ECU( SerialFromECU, SerialToECU);

void setup( void )
{
  // Utilisation de Serial vers le moniteur Arduino pour le debug (affichage des resultats sur l'ecran PC
  Serial.begin(9600);
  // Configuration de SoftwareSerial pour discuter avec l'ECU à la vitesse de 1953 baud
  ECU.begin( 1953 );

  // envoi des 4 octets qui forment le message de lecture
  ECU.write( 0x78 );    // commande lecture
  ECU.write( 0x11 );     // MSB de l'adresse de la variable à lire
  ECU.write( 0x85 );   // LSB de l'adresse de la variable à lire
  ECU.write( 0x00 );  // marqueur de fin
}

void loop()
{
  //reception de la réponse: on affiche en hexa tous les caractère reçus.
  // Pour la requête de lecture ci -dessus, on est sensé recevoir 11 85 XX ou XX est la températeure + 50C
  if (Serial.available() )
  {
    Serial.print( (int)ECU.read(), HEX );
    Serial.print( " " );
  }
}

Je part de l'hypothèse que tu as un PC de connecté et que tu peux afficher le moniteur Arduino (Serial.print)
ECU est un SoftwareSerial pour discuter avec l'ECU.

Je pense que ça aura du mal à fonctionner avec un SoftSerial, puisqu'on ne peut rien configurer à part les bauds.

  // Configuration de SoftwareSerial pour discuter avec l'ECU à la vitesse de 1953 baud

ECU.begin( 1953 );

Je pense que ça ne fonctionnera pas parce que le baud rate est pris dans une table. Qui évidemment ne contient pas 1953.
Il faudrait modifier la librairie pour lui faire accepter une valeur comme celle-ci.