Comprendre et utiliser le protocole CAN de Marklin

Bonjour Pierre,
Si je puis me permettre :

Un Bit (binary element) est l’unité la plus petite et il en faut 8 pour faire un Octet (en Français), ou Byte (en Anglais).

Je pense qu’il y a deux méthodes pour obtenir le résultat final

  1. Soit la mise au point est faite par chacun (individuellement) et dans ce cas il faut comprendre ce qui se passe pour pouvoir corriger les erreurs. C’est ce que je fais, à mon rythme évidement.
  2. Soit vous attendez un “Dossier de fabrication”, fiabilisé, comme l’a suggéré @Psuchaud il y a quelques jours. Dans cette optique, et si @BobyAndCo est d’accord, il faut attendre que la mise au point soit terminée d’une part, et que le “Dossier” soit écrit d’autre part.

Bref, c’est ce qui me vient à l’esprit; mais ce n’est qu’un regard parmi d’autres.
Cordialement.
Alain

1 « J'aime »

Bonjour à tous,
Petite manipulation de ce matin :

Ci-dessous le montage raccordé à la Gleisbox :

On voit bien les trois fils, CAN-L, CAN-H, et le fil de masse.

Avec juste deux lignes de code rajoutées sur le programme de test précédent:

 Serial.print("Identifiant Trame : ");Serial.println (frame.id);
 Serial.print("Commande : "); Serial.println((frame.id & 0x1FE0000) >> 17);

On obtient la capture partielle suivante :

J’ai pu observer les numéros de commande suivants :
0, 4, 5 , 6, et 24 ; suivant le sens de marche de la locomotive ou bien les fonctions sur la MS2.

Ci-dessous le pdf du code. Les deux lignes sont à la fin :
No_LoopBack_FR_v2.pdf (41,4 Ko)

Avec ci-dessous l’algorithme du programme, réalisé par ChatGpt :

Algorithme : Affichage des Identifiants de Messages CAN (29 bits) depuis la GLEISBOX

Initialisation :

Déclarer les bibliothèques nécessaires pour la communication avec le module MCP2515.

Définir les connexions SPI et les broches utilisées pour CS et INT.

Initialiser l'interface CAN avec les paramètres adaptés.

Configuration du Module CAN :

Définir la vitesse du bus CAN.

Activer les filtres de réception si nécessaire.

Vérifier si l'initialisation du module est réussie.

Boucle Principale :

Tant que le programme est en cours d'exécution :

Vérifier si un message CAN est disponible.

Lire le message reçu.

Extraire l'identifiant du message (29 bits).

Afficher l'identifiant du message sur le moniteur série.

Répéter.

Gestion des Erreurs :

Surveiller les erreurs de communication CAN et afficher les messages d'erreur si nécessaire.

Reconfigurer le module en cas d'échec de réception.

Fin de l'algorithme.

Bon WE
Alain

Bonjour Pierre,

Non il n’est pas obligatoire « d’apprendre » l’hexadécimal. C’est juste une manière de présenter une valeur. Mais on peut aussi le faire en binaire ou en décimal comme je l’ai déjà dit.

Maintenant, la présentation en hexadécimal, présente quelques avantages quand on a un peu pratiqué la gymnastique mais c’est aussi la forme de présentation qu’utilise Marklin. Sinon, il faut convertir ce que l’on trouve dans les docs sous le format qui nous va bien.

Il y a des convertisseurs en ligne comme celui-ci que je trouve simple à utiliser : Convertisseur décimal, hexadécimal, binaire

Encore une fois, dans cette première étape, ce qu’il faut surtout comprendre c’est comment est constitué un message (trame ou frame) CAN entre son identifiant et ses datas. Comment est structuré l’identifiant entre la priorité d’une part, la commande etc…

Jouer avec se fera ensuite progressivement.

La démarche d’ALAIN me semble bonne pour avancer progressivement. Relier un Arduino à la Gleisbox et regarder ainsi les messages que celle-ci adresse et plutôt ludique et très formateur.

Relier un Arduino en CAN à la Gleisbox permettra dans un premier temps de traiter cette question de liaisons et de réglages. Ensuite de lire, décomposer les messages CAN de la Gleisbox pour comprendre ce que cela signifie.

Christophe

Christophe,
Je vais passer les interventions d’Alain, elles sont déjà trop techniques.
Ce serait bien d’ailleurs qu’il n’intervienne plus, il amène confusion et alourdit la lecture.
Comment se procure-t-on un arduino ?

Merci Pierre.
Je me retire du fil …

Pierre,

Je ne pense pas que ce soit la bonne solution et de loin. Alain contribue avec une vraie envie de partager et de progresser. De plus nous sommes au début, forcement qu’il faut trouver des calages. Tout le monde ne part pas du même point, Alain a déjà pris un peu d’avance. Je pense qu’il faut juste qu’il prenne cela en compte en s’assurant que toute les étapes sont bien comprises avant de passer à une autre.

Alain apporte aussi beaucoup en ce qu’il réalise les montages et les tests ce qui est une grande contribution.

Pour ce qui est de se procurer le matériel, Arduino en particulier, c’est (malheureusement) les sites chinois qui proposent les meilleurs prix. Je te fournirai des infos en MP.

Tu peux aussi aller dans le magasin d’éléctronique proche de chez toi qui vendra certainement des kits de démarrage mais tu vas payer 30 ou 40€ ce qui en vaut 10 ailleurs.

Pour les informations de base, je pense que vous trouverez sur Locduino pas mal d’infos utiles

Qu’est ce qu’une carte Arduino ?
Un minimum pour jouer rapidement avec un Arduino

Mais en réalité, une carte, son cordon USB pour l’ordinateur, un module CAN comme montré ci-dessus et des fils de liaison Dupont suffisent !

Où acheter ?

Christophe

Bonjour à tous,

Je pense qu’il est temps de commencer les travaux pratique. Alain à ouvert la voie, je vais maintenant montrer (et je ne doute pas qu’il va m’accompagner) comment commencer à communiquer en CAN avec sa centrale.

Tout d’abord, il vous faut un module CAN. Pour le CAN de Marklin dont le débit est de 250 Kb/s, ce petit module à moins de 2€ fait parfaitement l’affaire :

Voici le schéma de branchement de ce petit module sur un Arduino UNO que j’ai extrait de l’article ici qui peut aussi aider à mieux comprendre de quoi on parle : https://www.moussasoft.com/module-bus-can-mcp2515-avec-arduino/

La broche VCC du module doit être connectée à la broche 5V de l’Arduino.
La broche GND du module doit être connectée à la broche GND de l’Arduino.
La broche CS du module doit être connectée à la broche 10 (SS) de l’Arduino.
La broche SO du module doit être connectée à la broche 12 (MISO) de l’Arduino.
La broche SI du module doit être connectée à la broche 11 (MOSI) de l’Arduino.
La broche SCK du module doit être connectée à la broche 13 (SCK) de l’Arduino.
La broche INT du module doit être connectée à la broche 2 de l’Arduino.

Pour la liaison du module CAN sur la Gleisbox, suivez ce qui a déjà été montré à savoir :

image

CAN-L sur pin 8 de la Gleisbox
CAN-H sur pin 4 de la Gleisbox
GND sur pin 2 de la Gleisbox

Ces branchements sont aussi valables pour les autres centrales.

Voici un programme à charger sur l’Arduino qui va nous permettre de lire tout ce que la Gleisbox envoie. Vous pouvez-même « jouer » avec la MS2 à piloter des locomotives et vous verrez avec l’Arduino les commandes envoyées et reçu en décrypter ce qui s’échange.

C’est bien cela svp. Alain, excuse moi pour mes propos trop directs et pas assez nuancés. :pray:

Bonjour, désolé si j’ai loupé une étape, … mais il me semble que le pgme cité est absent :upside_down_face:
JP

Voici un petit programme à charger sur son Arduino qui fonctionne avec le montage matériel que j’ai présenté ci dessus. Arduino + module CAN réliés à la Gleisbox.

A ce stade, ceux qui peuvent être un peu effrayés n’ont pas à l’être. Si vous le souhaitez, vous pouvez ne pas du tout “entrer” dans le programme et vous contenter de le charger tel quel sur la carte.

Comme je ne l’ai pas testé, je vais juste demander à Alain ou JP de le faire et de nous adresser un retour.

Cela me permet de préciser tout de même quelques points car il n’a pas le même module CAN que celui du programme.

Pour ces deux lignes, s’assurer que c’est bien la bonne configuration adoptée par chacun

static const byte MCP2515_CS = 10;  // CS input of MCP2515 (adapt to your design)
static const byte MCP2515_INT = 2;  // INT output of MCP2515 (adapt to your design)

et ici, modifier selon que le module fonctionne à 8 ou 16 Mhz

static const uint32_t QUARTZ_FREQUENCY = 8UL * 1000UL * 1000UL; // 8 MHz

Programme à copier en se servant de l’icone en haut à droite de la fenêtre ci-dessous. On peut aussi agrandir la fenêtre avec l’autre icone. :

#include <ACAN2515.h>

static const byte MCP2515_CS = 10;  // CS input of MCP2515 (adapt to your design)
static const byte MCP2515_INT = 2;  // INT output of MCP2515 (adapt to your design)

//——————————————————————————————————————————————————————————————————————————————
//  MCP2515 Driver object
//——————————————————————————————————————————————————————————————————————————————

ACAN2515 can(MCP2515_CS, SPI, MCP2515_INT);

//——————————————————————————————————————————————————————————————————————————————
//  MCP2515 Quartz: adapt to your design
//——————————————————————————————————————————————————————————————————————————————

static const uint32_t QUARTZ_FREQUENCY = 8UL * 1000UL * 1000UL;  // 8 MHz

void setup() {
  //--- Start serial
  Serial.begin(115200);
  //--- Begin SPI
  SPI.begin();
  //--- Configure ACAN2515
  Serial.println("Configure ACAN2515");
  ACAN2515Settings settings(QUARTZ_FREQUENCY, 250UL * 1000UL);  // CAN bit rate 250 kb/s
  //settings.mRequestedMode = ACAN2515Settings::LoopBackMode ; // Select loopback mode
  const uint16_t errorCode = can.begin(settings, [] {
    can.isr();
  });
  if (errorCode > 0) {
    Serial.print("Configuration error 0x");
    Serial.println(errorCode, HEX);
  }
}


void loop() {
  CANMessage frame;
  if (can.available()) {
    can.receive(frame);
    Serial.print("Received (BIN): ");
    Serial.println(frame.id, BIN); // Affichage sous forme binaire de l'identifiant

    Serial.print("Received (Decimal): ");
    Serial.println(frame.id); // Affichage sous forme decimale de l'identifiant

    Serial.print("Received (HEX): 0x");
    Serial.println(frame.id, HEX); // Affichage sous forme hexadecimale de l'identifiant
  }
}

Pour info, là où le texte commence par ‘//’ et écrit en gris clair est un texte de commentaire. Pas du code informatique.

Christophe

2 « J'aime »

Heu !!! J’ai juste un petit problème pour tester… Je n’ai pas de carte CAN. Je l’ai commandé mais arrivée prévue que pour la fin du mois. Désolé.:sob::hot_face::sob:

Mais avec de la chance, je devrais en récupérer une lundi. Je croise les doigts car je suis impatient de tester !

1 « J'aime »

Bonne nouvelle.

Il faudra juste regarder si c’est un quartz à 8 ou à 16 Mhz et ajuster dans le programme

static const uint32_t QUARTZ_FREQUENCY = 8UL * 1000UL * 1000UL; // 8 MHz

ou

static const uint32_t QUARTZ_FREQUENCY = 16UL * 1000UL * 1000UL; // 16 MHz

Christophe

J’en prends acte. Tu es tout excusé.
Ce que je vais faire; c’est d’attendre d’avoir le feu vert pour réaliser une manip ou une tâche, d’une part et de ne donner en résultat que ce qui est compréhensible pour le plus grand nombre d’autre part.
Cela permettra “d’acrocher tous les wagons” si je puis dire.
Bonne soirée.
Alain

2 « J'aime »

Bonjour à tous,

Je vais être peu disponible encore pendant une quinzaine de jours, mais je vais essayer de vous donner régulièrement des informations et répondre aux questions.

Je pense que la question des liaisons entre le module CAN de l’Arduino et la Gleisbox est maintenant comprise.

L’étape suivante que je propose est d’écouter les communications en CAN. Pour l’instant, pour la seule Gleisbox. Mais vous verrez qu’il circule pas mal de messages.

Le programme ci-dessous ne fait donc que d’afficher ce que la Gleisbox envoie sur le bus. C’est en quelque sorte un sniffer.

Si vos branchements sont bons ainsi que vos paramètres, le moniteur série de l’IDE Arduino doit afficher ceci

Configure ACAN2515
Configuration can ok
Fin du setup
-----------------------------------
Nouveau message
-----------------------------------
Received ID frame (BIN): 1100001000101100100011
Received ID frame (Decimal): 3181347
Received ID frame (HEX): 0x308B23
Received hash (HEX): 0x8B23
Received commande (HEX): 0x18
Received : Demande
-----------------------------------
Ping : Interrogation de tous les participants du bus

Tout d’abord que la configuration c’est (normalement) bien passée Configuration can ok

Ensuite, le moniteur nous indique que l’on vient de recevoir un nouveau message et nous indique l’identifiant sur 29 bits de ce message en binaire, décimal et hexadécimal. Il nous donne également le code de la commande envoyé, ici 0x18 qui est une commande de ping. La Gleisbox envoie toutes les 12 secondes environ, une interrogation pour que tous les participants du bus se fassent connaitre.

Si maintenant vous activez la MS2 en désactivant la touche STOP, vous allez avoir ce message


-----------------------------------
Nouveau message
-----------------------------------
Received ID frame (BIN): 10011001101100011
Received ID frame (Decimal): 78691
Received ID frame (HEX): 0x13363
Received hash (HEX): 0x3363
Received commande (HEX): 0x0
Received : Reponse
-----------------------------------
Commande systeme
data32[0] : 0
data[4] : 1
long : 5

Vous avez cette fois encore les informations sur l’identifiant de 29 bits. Le code de la commande est 0x00, ce sont les commandes système et data[4] est égal à 1 c’est la commande d’activation.

Si vous désactivez, vous aurez le même message mais data[4] sera à 0.

Si vous cherchez à faire rouler une locomotive, vous allez voir ce type de message

-----------------------------------
Nouveau message
-----------------------------------
Received ID frame (BIN): 10010011001101100011
Received ID frame (Decimal): 602979
Received ID frame (HEX): 0x93363
Received hash (HEX): 0x3363
Received commande (HEX): 0x4
Received : Reponse
-----------------------------------
autre commande : 0x4
-----------------------------------

Les commandes qui ont le code 0x04 sont les commande de traction.

Enfin, dernier exemple, ici une commande pour activer les lumières d’une locomotives. Les commandes de fonctions ont pour code 0x06.

-----------------------------------
Nouveau message
-----------------------------------
Received ID frame (BIN): 11001000101100100011
Received ID frame (Decimal): 822051
Received ID frame (HEX): 0xC8B23
Received hash (HEX): 0x8B23
Received commande (HEX): 0x6
Received : Demande
-----------------------------------
autre commande : 0x6
-----------------------------------

Pour connaitre la signification des commandes, reportez-vous au document du protocole Marklin plusieurs fois publié.

Si vous le souhaitez, vous pouvez chercher à avoir plus d’informations en écrivant par exemple des Serial.print() pour les data : Serial.println(frame.data[4]); Serial.println(frame.data[5]); Serial.println(frame.data[6]); Serial.println(frame.data[7]);

ce qui vous permettra de connaitre l’adresse de la locomotive dans Serial.println(frame.data[3]); des commandes de traction et de fonction.

#include <ACAN2515.h>

static const byte MCP2515_CS = 10;  // CS input of MCP2515 (adapt to your design)
static const byte MCP2515_INT = 2;  // INT output of MCP2515 (adapt to your design)

//——————————————————————————————————————————————————————————————————————————————
//  MCP2515 Driver object
//——————————————————————————————————————————————————————————————————————————————

ACAN2515 can(MCP2515_CS, SPI, MCP2515_INT);

//——————————————————————————————————————————————————————————————————————————————
//  MCP2515 Quartz: adapt to your design
//——————————————————————————————————————————————————————————————————————————————

static const uint32_t QUARTZ_FREQUENCY = 16UL * 1000UL * 1000UL;  // 16 MHz

CANMessage frame;
uint16_t thisHash = 0x2f39;

void setup() {
  //--- Start serial
  Serial.begin(115200);
  //--- Begin SPI
  SPI.begin();
  //--- Configure ACAN2515
  Serial.println("Configure ACAN2515");
  ACAN2515Settings settings(QUARTZ_FREQUENCY, 250UL * 1000UL);  // CAN bit rate 250 kb/s
  //settings.mRequestedMode = ACAN2515Settings::LoopBackMode;     // Select loopback mode
  const uint16_t errorCode = can.begin(settings, [] {
    can.isr();
  });
  if (errorCode == 0) {
    Serial.println("Configuration can ok");
  } else {
    Serial.print("Configuration error 0x");
    Serial.println(errorCode, HEX);
  }
  Serial.println("Fin du setup");
}


void loop() {

  memset(frame.data, 0x00, 8);  // On efface les datas

  if (can.available()) {
    Serial.println("-----------------------------------");
    Serial.println("Nouveau message");
    Serial.println("-----------------------------------");
    can.receive(frame);
    Serial.print("Received ID frame (BIN): ");
    Serial.println(frame.id, BIN);  // Affichage sous forme binaire de l'identifiant

    Serial.print("Received ID frame (Decimal): ");
    Serial.println(frame.id);  // Affichage sous forme decimale de l'identifiant

    Serial.print("Received ID frame (HEX): 0x");
    Serial.println(frame.id, HEX);  // Affichage sous forme hexadecimale de l'identifiant

    uint32_t hash = frame.id & 0xFFFF;
    Serial.print("Received hash (HEX): 0x");
    Serial.println(hash, HEX);  // Affichage sous forme hexadecimale de l'identifiant

    uint32_t commande = (frame.id & 0x1FE0000) >> 17;
    Serial.print("Received commande (HEX): 0x");
    Serial.println(commande, HEX);  // Affichage sous forme hexadecimale de l'identifiant

    uint32_t reponse = (frame.id & 0x10000) >> 16;
    Serial.print("Received : ");
    //Serial.println(reponse);  // Affichage sous forme hexadecimale de l'identifiant
    Serial.println(reponse ? "Reponse" : "Demande");  // Affichage sous forme hexadecimale de l'identifiant

    Serial.println("-----------------------------------");

    switch (commande) {
      case 0x18:
        if (frame.len == 0) {  // Ping : Interrogation de tous les participants du bus
          Serial.println("Ping : Interrogation de tous les participants du bus");
          CANMessage frameOut;
          frameOut.id |= 0x18 << 17;
          frameOut.id |= 1 << 16;  // Reponse
          frameOut.id |= thisHash;
          frameOut.len = 4;
          frameOut.data32[0] = thisHash;

          if (can.tryToSend(frameOut)) {
            Serial.println("\nReponse envoyee");
          } else {
            Serial.println("\nEchec de l'envoi");
          }

        } else if (frame.len == 8) {
          Serial.println("Ping :");
          uint32_t expediteur = frame.data32[0];
          Serial.print("ID expediteur : 0x");
          Serial.println(expediteur, HEX);
          uint16_t versLogiciel = frame.data16[4];
          Serial.print("Num version logiciel : 0x");
          Serial.println(versLogiciel, HEX);
          uint16_t typeAppareil = frame.data16[6];
          Serial.print("Type de l'appareil : 0x");
          Serial.println(typeAppareil, HEX);
        }
        break;

      case 0x00:  // Commande systeme
        Serial.println("Commande systeme");
        Serial.print("data32[0] : ");
        Serial.println(frame.data32[0]);
        Serial.print("data[4] : ");
        Serial.println(frame.data[4]);
        Serial.print("long : ");
        Serial.println(frame.len);
        break;

      default:
        Serial.print("autre commande : 0x");
        Serial.println(commande);
    }
    Serial.println("-----------------------------------\n");
  }
}
2 « J'aime »

Bonjour, je viens de recuperer une petite carte Bus CAN arduino et malheureusement il ne se passe rien.
Le moniteur série affiche :
Configuration ACAN2515
Erreur de configuration 0x1

… et rien de plus. J’ai essayé avec le cavalier 120 Ohm en place (et enlevé). Mêmes résultats dans les 2 cas.
Pour mes tests, je suis sur une CS2.
Mauvaise manip de ma part?.
JiPé

Le quartz est bien un 8 et ligne est bien celle active.

J’ai trouvé.
Erreur de branchement de ma part.
Sur la carte Bus CAN : couleurs Vert, Jaune, Orange.
Sur la carte UNO : Vert, Orange, Jaune. J’avais fait : Vert, Jaune, Orange !!
Désolé …

Bon, Il faut bien s’assurer que les broches du module CS et INT vont bien dans les pins 10 et 2 de l’Arduino.

S cela ne fonctionne toujours pas, il faut charger le programme loopBackDemo ci-dessous et voir les messages d’erreur

//——————————————————————————————————————————————————————————————————————————————
//  ACAN2515 Demo in loopback mode
//——————————————————————————————————————————————————————————————————————————————

#include <ACAN2515.h>

//——————————————————————————————————————————————————————————————————————————————
//  MCP2515 connections:
//    - standard SPI pins for SCK, MOSI and MISO
//    - a digital output for CS
//    - interrupt input pin for INT
//——————————————————————————————————————————————————————————————————————————————
// If you use CAN-BUS shield (http://wiki.seeedstudio.com/CAN-BUS_Shield_V2.0/) with Arduino Uno,
// use B connections for MISO, MOSI, SCK, #9 or #10 for CS (as you want),
// #2 or #3 for INT (as you want).
//——————————————————————————————————————————————————————————————————————————————
// Error codes and possible causes:
//    In case you see "Configuration error 0x1", the Arduino doesn't communicate
//       with the 2515. You will get this error if there is no CAN shield or if
//       the CS pin is incorrect. 
//    In case you see success up to "Sent: 17" and from then on "Send failure":
//       There is a problem with the interrupt. Check if correct pin is configured
//——————————————————————————————————————————————————————————————————————————————

static const byte MCP2515_CS  = 10 ; // CS input of MCP2515 (adapt to your design) 
static const byte MCP2515_INT =  2 ; // INT output of MCP2515 (adapt to your design)

//——————————————————————————————————————————————————————————————————————————————
//  MCP2515 Driver object
//——————————————————————————————————————————————————————————————————————————————

ACAN2515 can (MCP2515_CS, SPI, MCP2515_INT) ;

//——————————————————————————————————————————————————————————————————————————————
//  MCP2515 Quartz: adapt to your design
//——————————————————————————————————————————————————————————————————————————————

static const uint32_t QUARTZ_FREQUENCY = 8UL * 1000UL * 1000UL ; // 8 MHz

//——————————————————————————————————————————————————————————————————————————————
//   SETUP
//——————————————————————————————————————————————————————————————————————————————

void setup () {
//--- Switch on builtin led
  pinMode (LED_BUILTIN, OUTPUT) ;
  digitalWrite (LED_BUILTIN, HIGH) ;
//--- Start serial
  Serial.begin (115200) ;
//--- Wait for serial (blink led at 10 Hz during waiting)
  while (!Serial) {
    delay (50) ;
    digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ;
  }
//--- Begin SPI
  SPI.begin () ;
//--- Configure ACAN2515
  Serial.println ("Configure ACAN2515") ;
  ACAN2515Settings settings (QUARTZ_FREQUENCY, 250UL * 1000UL) ; // CAN bit rate 250 kb/s
  settings.mRequestedMode = ACAN2515Settings::LoopBackMode ; // Select loopback mode
  const uint16_t errorCode = can.begin (settings, [] { can.isr () ; }) ;
  if (errorCode == 0) {
    Serial.print ("Bit Rate prescaler: ") ;
    Serial.println (settings.mBitRatePrescaler) ;
    Serial.print ("Propagation Segment: ") ;
    Serial.println (settings.mPropagationSegment) ;
    Serial.print ("Phase segment 1: ") ;
    Serial.println (settings.mPhaseSegment1) ;
    Serial.print ("Phase segment 2: ") ;
    Serial.println (settings.mPhaseSegment2) ;
    Serial.print ("SJW: ") ;
    Serial.println (settings.mSJW) ;
    Serial.print ("Triple Sampling: ") ;
    Serial.println (settings.mTripleSampling ? "yes" : "no") ;
    Serial.print ("Actual bit rate: ") ;
    Serial.print (settings.actualBitRate ()) ;
    Serial.println (" bit/s") ;
    Serial.print ("Exact bit rate ? ") ;
    Serial.println (settings.exactBitRate () ? "yes" : "no") ;
    Serial.print ("Sample point: ") ;
    Serial.print (settings.samplePointFromBitStart ()) ;
    Serial.println ("%") ;
  }else{
    Serial.print ("Configuration error 0x") ;
    Serial.println (errorCode, HEX) ;
  }
}

//----------------------------------------------------------------------------------------------------------------------

static uint32_t gBlinkLedDate = 0 ;
static uint32_t gReceivedFrameCount = 0 ;
static uint32_t gSentFrameCount = 0 ;

//——————————————————————————————————————————————————————————————————————————————

void loop () {
  CANMessage frame ;
  if (gBlinkLedDate < millis ()) {
    gBlinkLedDate += 2000 ;
    digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ;
    const bool ok = can.tryToSend (frame) ;
    if (ok) {
      gSentFrameCount += 1 ;
      Serial.print ("Sent: ") ;
      Serial.println (gSentFrameCount) ;
    }else{
      Serial.println ("Send failure") ;
    }
  }
  if (can.available ()) {
    can.receive (frame) ;
    gReceivedFrameCount ++ ;
    Serial.print ("Received: ") ;
    Serial.println (gReceivedFrameCount) ;
  }
}

//——————————————————————————————————————————————————————————————————————————————

1 « J'aime »

Je pense que c’est OK.
Les valeurs varient bien dès un changement de vitesse par exemple.
… avec ou sans la cavalier 120Ohm je ne vois pas de différences, pour le moment.

Par précaution donc, essai du LoopBack Demo.
Pour moi, ca me semble OK, aussi.

Cà tourne encore … Toujours OK à 65.

Bonjour à tous,
C’est OK pour moi également.
Alain