ALDL et Arduino

Bonjour à tous !

Le fais appel à vous pour tenter de résoudre mon problème...

Je possède une Pontiac Firebird de 1994, sur laquelle j'essaye de récupérer, via le port ODB1, la vitesse et le nombre de tours par minutes avec un arduino uno, pour afficher le tout sur un écran LCD.

Je précise de de 1986 à 1995, on pouvait communiquer avec les véhicules via un format développé par General Motors. Pas de chance pour moi, l'ODB2 est arrivée deux ans plus tard....

Grace à l'aide d'un américain, j'ai réussi à récupérer les données avec un programme en Visual basic.
Je souhaite désormais pouvoir reproduire cela sur un arduino.

Après avoir écumé le net, j'ai trouvé et adapté un projet correspondant parfaitement à ce que je veux.
J'ai réalisé une version de test, mais ormis la liaison série qui semble s'établir, je ne parviens pas à communiquer avec l'ECU de ma voiture...

Le projet d'origine est ici : http://www.xm381.com/xm381/aldl.html

J'ai réalisé le câblage suivant : http://www.xm381.com/xm381/aldl_files/ALDL_Communication_1.png
La seule différence est que l'arduino est allimenté via un adaptateur usb branché sur l'allume cigare de la voiture.

La doc technique de l'ALDL est ici : http://www.xm381.com/xm381/aldl_files/ALDL%20DataStreams.zip (Pour mon type de véhicule, c'est la A257)

Je joins une copie de mon code à ce post.
Débutant dans la prog, j'implore votre indulgence sur la qualité de mon code :slight_smile:
Un grand merci pour votre aide !
Nitrix

//
// FIREBIRD_9495_ALDL - Version Alpha 2.0


// PARAMETRE DE L'AFFICHEUR LCD
#include <UTFT.h>                  // Lirairie de gestionLCD
UTFT myGLCD(ITDB18SP,9,10,11,7,8); // Parametrega LCD 128x160px
extern uint8_t SmallFont[];          // Parametrage de la police
//extern uint8_t BigFont[];          // Parametrage de la police


// PARAMETRE DE CONFIGURATION DE LA COMMUNICATION AVEC L'ECU
// MODE 1 (TRANSMIT FIXED DATA STREAM) MESSAGE 0
const byte Mode1Request[] = { 0xE4, 0x57, 0x01, 0x00 }; // Mode 1 Request byte string 
const byte Mode1Header[] = { 0xE4, 0x99, 0x01 };        // This is the header returned with the ALDL data
//const byte Mode1DataBytes = 63;                        // This is the number of data bytes returned (not including the header)
const byte Mode1DataBytes = 67;                         // This is the number of data bytes returned (not including the header)
// Dans le DATA STREAM A257, le Mode1DataBytes est a 67. On laisse a 63 mais si bug, le passer a 67.


// Parametrage des BYTES
// Dans cette version alpha, on ne prend que la Vitesse en miles (MPH), Les tours par minutes (RPM), Le voltage de la batterie (BAT)
// Status Bytes: ValueName = byte position in ALDLStream 
// must offset location in ALDLStreamBuffer, offset = Mode1RequestSize + Mode1HeaderSize

const byte BAT = 4;    // (BATTERY VOLTAGE, VOLTS = N/10)
const byte MPH = 11;   // (FILTERED MILES PER HOUR)
const byte RPM = 14;   // *25 (ENGINE RPM)


// CONFIGURATION DU HARDWARE
// ALDL
#define ALDLSerial Serial // Initialisation de la communication serie

// ***** Variables for ALDL data *****
const byte Mode1RequestSize = sizeof(Mode1Request)/sizeof(Mode1Request[0]); // Calculate how many bytes long is the Mode 1 request string.
const byte Mode1HeaderSize = sizeof(Mode1Header)/sizeof(Mode1Header[0]); // Calculate how many bytes long is the Mode 1 header string.
const byte ALDLStreamSize = (Mode1RequestSize + 1 + Mode1HeaderSize + Mode1DataBytes + 1);  // # of Request bytes + checksum byte + header bytes + data bytes + checksum byte
byte offset = Mode1RequestSize + Mode1HeaderSize; //starting location of ALDL in buffer (after request and header data)
byte ALDLStream[ALDLStreamSize]; // Array for verified ALDL data
byte ALDLStreamBuffer[ALDLStreamSize]; // Array to store ALDL for verification 
byte checkSum;
byte Mode1RequestcheckSumByte; // Checksum of Mode 1 bytes
byte ALDLValidity;
unsigned long timeout;



// PARAMETRAGE DU PROGRAMME
void setup() {
  
// initialisation de l'ecran
InitScreen();  // Initialisation de l'ecran LCD

ALDLSerial.begin(8192); // Initialisation de la communication serie

// ***** Mode 1 checksum calculation *****
  checkSum = 0;
  for (byte Requestbytes=0; Requestbytes < Mode1RequestSize - 1; Requestbytes++) {
    checkSum += Mode1Request[Requestbytes];
  }
  Mode1RequestcheckSumByte = 0 - checkSum;


}

// BOUCLE PRINCIPALE
void loop() {
  
    myGLCD.setFont(SmallFont); // initialisation de la police de caractere
    myGLCD.setColor( 255 , 255 , 255 ); // BLANC
    
    // request mode 1
    beginMode1();

  
    // get ALDL data
    getALDLStream(); 

     
    // Verify ALDLStream    
    VerifyALDLStream();

}


void InitScreen() {
  //myGLCD.setColor(B,G,R);
  
  myGLCD.InitLCD(); // initialisation de l'ecran LCD
  myGLCD.clrScr(); // Effacement de l'ecran LCD
  myGLCD.setFont(SmallFont); // initialisation de la police de caractere

}




// ALDL: INITIALISATION DU MODE 1 
void beginMode1() {
  //myGLCD.print("BeginMode1 :", 1, 0);
  
  while(ALDLSerial.available() != 0){ // empty serial buffer
    byte bitbucket = ALDLSerial.read();
  }
myGLCD.print("#", 1, 0);  
myGLCD.print(" ALDLSerial1:" + String(ALDLSerial.available()), 1, 0);
  
  
  for(byte bytesRead = 0; bytesRead <= Mode1RequestSize - 1; bytesRead++) { // send request  
    ALDLSerial.write (Mode1Request[bytesRead]);
    
myGLCD.print("#", 1, 15);    
myGLCD.print(" bytesRead:" + String(bytesRead), 1, 15);
myGLCD.print("#", 1, 30);
myGLCD.print(" ReqSize:" + String(Mode1RequestSize - 1), 1, 30);
  }
myGLCD.print("#", 1, 45);
myGLCD.print(" ReqchkSumByte:" + String(Mode1RequestcheckSumByte), 1, 45);
  ALDLSerial.write (Mode1RequestcheckSumByte); // send checksum
}


// ALDL: RECUPURATION DU FLUX DE DONNEES
void getALDLStream() {
  
  for (byte Clearbytes=0; Clearbytes < ALDLStreamSize; Clearbytes++) { // empty ALDL Stream array
    ALDLStream[Clearbytes] = 0x00;
myGLCD.print("#", 1, 60);    
myGLCD.print(" ALDLStream:" + String(ALDLStreamSize), 1, 60);
  }
        
  for (byte Clearbytes=0; Clearbytes < ALDLStreamSize; Clearbytes++) { // empty ALDL Stream Buffer array
    ALDLStreamBuffer[Clearbytes] = 0x00;
myGLCD.print("#", 1, 75);  
myGLCD.print(" ALDLStrBuff:" + String(ALDLStreamBuffer[Clearbytes]), 1, 75);
  }
  
  byte bytesRead = 0;      
  timeout = millis();
  
  while((millis() - timeout) < 100){

    if (ALDLSerial.available()) 
    { // retrieve ALDL response data from ECU in buffer, if any
      byte dataByte = ALDLSerial.read();
      ALDLStreamBuffer[bytesRead] = dataByte;   
//    BluetoothSerial.write (dataByte);
      bytesRead++;
      
myGLCD.print("#", 1, 90);  
myGLCD.print(" ALDLSerial:Yes " + String(ALDLStreamBuffer[bytesRead]), 1, 90);

    }else{
      
myGLCD.print("#", 1, 90); 
myGLCD.print(" ALDLSerial:No ", 1, 90);
    }
    
    if(bytesRead >= ALDLStreamSize){

      break;
    } 
  }
}


// ALDL: CONTROLE DES DONNEES
// Total Of Mode1Request + checksum + header + ALDL data + checksum byte must be equal to 0            
void VerifyALDLStream(){
  // check header string in ALDL data stream: does it match Mode1Header string        
  byte Mode1HeadercheckSum=0;

  checkSum=0;

  for (byte Requestbytes=0; Requestbytes < Mode1HeaderSize; Requestbytes++) {
    Mode1HeadercheckSum += Mode1Header[Requestbytes];
    checkSum += ALDLStreamBuffer[Requestbytes + Mode1RequestSize + 1];
    
    myGLCD.print("#", 1, 105);   
    myGLCD.print(" Check Stream :"+ String(Requestbytes), 1, 105);
   // delay(1000);
  }



  if (Mode1HeadercheckSum != checkSum) {
    ALDLValidity = 2;
    
myGLCD.print("#", 1, 105);   
myGLCD.print(" Check Stream : 2", 1, 105);
    
    return;
  }

  // check ALDL data stream: header + ALDL data + checksum byte should equal 0               
  checkSum=0;
  
  for (byte Requestbytes=0; Requestbytes < ALDLStreamSize - (Mode1RequestSize + 1); Requestbytes++) {
    checkSum += ALDLStreamBuffer[Requestbytes + (Mode1RequestSize + 1)];
  }

  if (checkSum != 0) {
    ALDLValidity = 1;
myGLCD.print("#", 1, 105);       
myGLCD.print(" checkSum : 1    ", 1, 105);
    
    return;
  }

  if (checkSum == 0) {
  ALDLValidity = 0;
myGLCD.print("#", 1, 105);   
myGLCD.print(" checkSum : 0    ", 1, 105);
    
    for(byte bytesRead = 0; bytesRead < ALDLStreamSize ; bytesRead++){
      ALDLStream[bytesRead] = ALDLStreamBuffer[bytesRead]; // transfer good data to ALDLStream     
    }
  }
}

FIREBIRD_9495_ALDL_8192-alpha2.ino (7.06 KB)

A257.txt (62.1 KB)

j'ai réussi à récupérer les données avec un programme en Visual basic

Bonjour,
peux-tu nous communiquer ce programme ainsi que le câblage utilisé ?

Et une photo de la Pontiac ? :smiley:

trimarco232:
Bonjour,
peux-tu nous communiquer ce programme ainsi que le câblage utilisé ?

Merci de votre réponse.
Pour le cable utilisé avec le prog en Visual basic 2010 express, c'est un Connecteur 12 Pin vers usb.

J'essaye de l'adapter pour un MEGA 2560 (Officiel) mais n'étant pas encore familier avec la prog sur arduino, la tâche n'est pas simple :confused:
Pour le cable de liaison avec l'arduino, j'ai réalisé celui-ci : http://www.xm381.com/xm381/aldl_files/ALDL_Communication_1.png

Je joins le code en pièce jointe

Code Source VB Express 2010.txt (15.3 KB)

BrUnO14200:
Et une photo de la Pontiac ? :smiley:

Voici le modèle que je possède :slight_smile:
http://gtcarlot.com/colors/car/25247873-14.html

Bonjour,

Nitrix, nous avons un problème d'ergonomie de travail :

  • ton code est trop long, aucune chance (du moins pour moi) de le faire fonctionner par retouches hasardeuses. Pour commencer, il faut faire le minimum, puis continuer après validation des étapes précédente

  • il ne sera pas possible de se passer d'un moyen de débogage : écran de pc, en fait. Le port série de l'arduino étant pris par l'ODB1, il faudrait utiliser software serial et un adaptateur usb - série pour monitorer ce que l'arduino reçoit de l'ODB1

  • ce débogage ne pouvant s'effectuer que moteur en marche (?), il faudrait pouvoir s'isoler des gaz d'échappement en mettant une liaison rs485 entre le garage (ouvert) et ton poste de travail

qu'en penses-tu ?

trimarco232:
...

  • il ne sera pas possible de se passer d'un moyen de débogage : écran de pc, en fait. Le port série de l'arduino étant pris par l'ODB1, il faudrait utiliser software serial et un adaptateur usb - série pour monitorer ce que l'arduino reçoit de l'ODB1

bonjour trimarco
il n'est pas non plus interdit d'ajouter/repiquer un autre adaptateur serial/usb pour monitorer "ailleurs/avec autre chose" 8)

Hello trimarco232 !

Je te confirme que c'est un peu hardcore comme développement !

Je suis en train de créer une version ultra minimaliste du projet afin de réussir à interpréter les données que me retourne l'ECU du véhicule, en recroisant les différents code VB et arduino + conseils de leurs auteurs respectifs.

En ce qui concerne le débogage aucun souci, l'arduino MEGA est équipé de 4 serials :slight_smile:
#define Infos Serial // Initialisation de la communication serie message d'infos
#define ALDLSerial Serial2 // Initialisation de la communication serie aldl

J'ai réussi à obtenir dune réponse de l'auteur du programme arduino, il m'explique qu'il faut augmenter la taille du serial buffer, sinon les données seront tronquées, d'où la présence du #define SERIAL_BUFFER_SIZE 128.

Cependant, il semble que cela concerne la partie software, et non le hardware.
J'ai donc modifié la config "core" de mon appli arduino en suivant les instructions de ce site : Internet of Home Things » Expanding Arduino Serial Port Buffer Size , dans la section "Hardware Serial Buffer Expansion"

Entre la grippe et l'avion, j'ai eu pas mal de temps pour analyser les données bruts capturées, du coup je vais tenter de tester à nouveau le flux reçu et voir si le fait d'augmenter le BUFFER change quelque chose.

Je reviendrais vers vous une fois ces nouveaux tests effectués.

trimarco232:
Bonjour,

Nitrix, nous avons un problème d'ergonomie de travail :

  • ton code est trop long, aucune chance (du moins pour moi) de le faire fonctionner par retouches hasardeuses. Pour commencer, il faut faire le minimum, puis continuer après validation des étapes précédente

  • il ne sera pas possible de se passer d'un moyen de débogage : écran de pc, en fait. Le port série de l'arduino étant pris par l'ODB1, il faudrait utiliser software serial et un adaptateur usb - série pour monitorer ce que l'arduino reçoit de l'ODB1

  • ce débogage ne pouvant s'effectuer que moteur en marche (?), il faudrait pouvoir s'isoler des gaz d'échappement en mettant une liaison rs485 entre le garage (ouvert) et ton poste de travail

qu'en penses-tu ?

Bonjour,

la logique voudrait que (n'engage que moi) tu gardes l'uart0 pour l'IDE et le moniteur, et utilises l'uart1 pour la connection avec l'ODB1
dans ce cas il faut que ton programme en tienne compte : ALDLSerial = serial1
pour le buffer, ( #define SERIAL_BUFFER_SIZE 128) c'est moins évident et nécessite peut-être de retoucher une librairie ...

Merci à Artouste d'avoir dézoomé !

C'est ce que je pensais avoir fait en utilisant #define ALDLSerial Serial2
Le serial2 n'est pas sur l'UART2 ?

Sinon j'ai testé une nouvelle version du programme, sans le connecter à mon véhicule. Cette version ultra détaillée du programme m'a permis de bien comprendre le principe de fonctionnement.
Reste donc à tester cette mouture sur le véhicule moteur allumé, en espérant que les données seront bonnes !

A suivre donc, j'espère avoir bientôt le plaisir de coller mon code terminé !

trimarco232:
Bonjour,

la logique voudrait que (n'engage que moi) tu gardes l'uart0 pour l'IDE et le moniteur, et utilises l'uart1 pour la connection avec l'ODB1
dans ce cas il faut que ton programme en tienne compte : ALDLSerial = serial1
pour le buffer, ( #define SERIAL_BUFFER_SIZE 128) c'est moins évident et nécessite peut-être de retoucher une librairie ...

Merci à Artouste d'avoir dézoomé !

Le serial2 n'est pas sur l'UART2 ?

J'ai dit 1 sans avoir vu ton code ...
Reste le #define SERIAL_BUFFER_SIZE 128 qu'il faut corréler à l'uart2

Faire une émulation de ton ordinateur de bord pourrait enrichir tes tests
Choisir l'ordi (interface usb-série) ou l'aruino (3ème uart) selon affinité

J'ai un doute sur le prise en compte de mes modifs de la taille de mon buffer.
J'ai suivi les instructions de ce site : http://internetofhomethings.com/homethings/?p=927

Pour le Software :
Dans \hardware\arduino\avr\libraries\SoftwareSerial\SoftwareSerial.h, je suis passé de 64 à 256 en modifiant la ligne suivante :
#define _SS_MAX_RX_BUFF 256 // RX buffer size

Pour le Hardware:
Dans \hardware\arduino\avr\cores\arduino\HardwareSerial.h , je suis passé de 64 à 256 en modifiant les lignes suivantes :
#define SERIAL_TX_BUFFER_SIZE 256
#define SERIAL_RX_BUFFER_SIZE 256

Ma question est la suivante, y a t'il un moyen d'afficher ses valeurs via un serial.print() pour être certain qu'elles sont bien prise en compte par l'arduino ?

D'avance merci !

Bonjour,

Pour le Software :

pas utile pour l'instant, car tu n'utilises pas la fonction SoftwareSerial

Pour le Hardware:

je ne suis pas certain que chaque uart dispose de ses propres buffers, ce qui me fait craindre un fichu désordre ...
un pro du méga peut-il nous éclairer ?

y a t'il un moyen d'afficher ses valeurs via un serial.print()

oui, sauf pour déboguer ... les fonctions HardwareSerial car elles ne peuvent pas s'appeler elles-mêmes

Hello à tous,

J'ai réalisé un petit tableau qui récapitule les différents états des données mesurés, avec une mise en évidence des groupes de données similaires.

ALDL Datastream

Entre ce que je veux et ce que j'obtiens, c'est l'opposé :o
Si quelqu'un à une idée sur le sujet, je suis preneur...

Entre ce que je veux et ce que j'obtiens, c'est l'opposé

Bonjour,
dis-nous le processus et montre nous le tableau
aucune idée de ce que tu entends par l'inverse ?

Mauvaise formulation, je voulais dire que cela n'avait absolument aucun sens par rapport à ce que j'attends comme type de réponse. J'ai ajouté le lien du tableau dans mon précédent, le script du forum ayant refusé de l'uploader directement à cause du format de fichier...

Il est ici également en version Excel : http://we.tl/nQVolz8wlN

trimarco232:
Bonjour,
dis-nous le processus et montre nous le tableau
aucune idée de ce que tu entends par l'inverse ?

tu reçois des données, c'est déjà ça ...
c'est avec le cordon usb ou avec l'arduino
est-ce que les ([75] = Sumcheck) sont justes ?

Alors je viens d'avoir une réponse du développeur de la version en visual basic !

Les données du tableau correspondent selon lui au trafic "ralenti" du PCM.
Ce mode par défaut contient les infos basiques (tours par minute, vitesse du véhicule et d'autres données)

Il m'explique qu'il faut envoyer non pas trois fois la requête Mode 1 (qui demande à l'ECU de transmettre toutes les données de la voiture) mais 3 fois le mode 8, qui demande à l'ECU de stopper l'envoi du trafic ralenti et d'attendre une transmission d'instructions.

Cette requête est envoyé 3 fois avec 75 millisecondes d'attente entre chaque pour être certain que l'ECU n'est pas en train d'envoyer des données en même temps que nous.

Tant qu'il n'est pas dans ce mode 8, il n'écoute pas, voilà pourquoi ma requête n'aboutit pas et que ce que je reçois des données étranges !

Bref, je suis très impatient de tester cela ce soir... Je vous tiendrai au courant bien entendu !

Voici quelques news des mes tests d'hier.

J'ai créé une version du code en incluant la requête qui demande le mode "silence" avant d'envoyer la seconde requête qui demande cette fois les données du véhicule.

Pour rappel, cette requête de mode silence demande au PCM du véhicule d'arrêter de transmettre les données séries par défaut, et de se mettre en attente d'instruction. Au bout de 2 ou 3 secondes, il repasse en mode normal automatiquement, et reprend l'envoie de données par défaut.

L'auteur du programme en VB express me disait d'envoyer 3 fois cette requête, avec 75ms d'attente entre chacune, afin d'être certain que le pcm la reçoive.

Malheureusement, le PCM reste toujours en mode normal, comme si ma requête n'était pas prise en compte. Une possibilité serait que le PCM la reçoit, mais qu'il la rejette a cause d'une erreur.

Ce matin, j'ai créé une version minimaliste du programme, avec uniquement la requête du mode silence.

// MODE 8 (DISABLE COMMUNICATIONS)
const byte Mode8Request[] = {0xE4, 0x56, 0x08 }; // Mode 8 Request byte string (228, 86, 8 )
const byte Mode8RequestSize = sizeof(Mode8Request)/sizeof(Mode8Request[0]); // Calculate how many bytes long is the Mode 8 request string.
byte checkSum;
byte Mode8RequestcheckSumByte; // Checksum of Mode 1 bytes


byte ALDLValidity;
unsigned long timeout;
byte bitbucket;

// SERIAL DECLARATION
#define ALDLSerial Serial



void setup() {
  // open serial port, sets data rate to 8192 bps
  ALDLSerial.begin(8192); 

  // ***** Mode 1 checksum calculation *****
  checkSum = 0;
  
  for (byte Requestbytes=0; Requestbytes < Mode8RequestSize - 1; Requestbytes++){
    checkSum += Mode8Request[Requestbytes];
  }
  Mode8RequestcheckSumByte = 0 - checkSum;
}

void loop()
{
  SendReqMode8(); // Appel de la fonction de Requete MODE 1
  
  // delay(75); // TOO FAST ???
  delay(300);
}

// ALDL : SEND MODE 8 REQUEST
void SendReqMode8()
{
  // empty serial buffer
  while(ALDLSerial.available() != 0){ 
    byte bitbucket = ALDLSerial.read();
  }

  for(byte bytesRead = 0; bytesRead <= Mode8RequestSize - 1; bytesRead++){ 
   // send request
   ALDLSerial.write (Mode8Request[bytesRead]);
  }
  
  // send checksum
  ALDLSerial.write(Mode8RequestcheckSumByte);
}

J'ai installé Serial port monitor sur mon ordi pour 'écouter' ce que l'arduino envoie.

Voici le format de ma requête :
const byte Mode8Request[] = {0xE4, 0x56, 0x08 };

J'ai remarqué que si j'utilise un délais de 75 ms entre chaque répétition de ma requête, j'ai le flux suivant :
[04/03/2016 11:22:52] Read data (COM3)
e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 äV.ÆäV.ÆäV.ÆäV.Æ
e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 äV.ÆäV.ÆäV.ÆäV.Æ
e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 äV.ÆäV.ÆäV.ÆäV.Æ
e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 äV.ÆäV.ÆäV.ÆäV.Æ
e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 äV.ÆäV.ÆäV.ÆäV.Æ
e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 äV.ÆäV.ÆäV.ÆäV.Æ
e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 äV.ÆäV.ÆäV.ÆäV.Æ
e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 äV.ÆäV.ÆäV.ÆäV.Æ
e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 e4 56 08 c6 äV.ÆäV.ÆäV.ÆäV.Æ

J'ai l'impression que le flux est trop rapide est que la requête est désordonnée

Si j'augmente à 300ms le délais entre chaque répétition de ma requête, j'ai ce résultat :
[04/03/2016 11:20:55] Read data (COM3) e4 56 08 c6 äV.Æ
[04/03/2016 11:20:55] Read data (COM3) e4 56 08 c6 äV.Æ
[04/03/2016 11:20:55] Read data (COM3) e4 56 08 c6 äV.Æ
[04/03/2016 11:20:56] Read data (COM3) e4 56 08 c6 äV.Æ
[04/03/2016 11:20:56] Read data (COM3) e4 56 08 c6 äV.Æ

Cette fois, tout semble correct. A noter que le c6 à la fin correspond au checksum.

Je n'ai pas encore eu la possibilité de tester cette théorie, et je voulais avoir votre avis.

Bonsoir,
je suis perdu, qu'est-ce qui est branché sur quoi dans cette config ?