Communication entre cartes Arduino

Lorsqu’on se retrouve à l’étroit sur une unique carte Arduino, ou bien que l’on souhaite ajouter des sous systèmes indépendants à son simulateur, il peut être nécessaire d’utiliser plusieurs cartes Arduino dans son projet. A titre d’exemple, sur le simulateur CC72000 V2, une première carte Arduino Due gère l’ensemble des commandes du pupitre et l’émulation de clavier. 3 cartes méga sont par ailleurs utilisées :
– une pour la commande des voyants lumineux, du tachro et des voltmètres/ampèremètres,
– une pour le KVB,
– une pour la radio sol-train.

Toutes ces cartes, à l’exception pour l’instant de la radio sol-train, exploitent les variables de simulation fournies par OpenRails dans leur programme (la carte méga du KVB en a besoin pour l’affichage des survitesse, celle du tachro pour l’affichage de la vitesse…). Par ailleurs, des informations doivent également pouvoir circuler d’une carte à l’autre (le KVB doit par exemple informer la carte Due qu’il commande un freinage d’urgence, etc.). Il existe plusieurs architectures pour réaliser ces fonctions.

Architecture en étoile, avec PC au centre

Cette première architecture est celle qui était utilisée sur le simulateur CC720000 V1. Chacune des cartes est reliée à l’ordinateur par un câble USB, avec une liaison série mise en place entre chacune des cartes Arduino et le programme Python sur le PC (partiellement présentée ici). Cela fonctionne très bien pour envoyer à toutes les cartes les variables de simulation, mais il est plus compliqué de faire communiquer deux cartes entre elles (toute information doit être dans un premier temps envoyée au programme Python puis être renvoyée à la carte de destination). L’installation est également plus lourde car il faut connecter plusieurs câbles USB au PC. C’est pour cela que cette architecture n’a pas été retenue pour le simulateur CC72000 V2.

Architecture en étoile avec le PC au centre.

Architecture en étoile, avec une carte Arduino au centre

Une deuxième architecture possible pour l’utilisation de plusieurs carte consiste à ne réaliser qu’une seule liaison série USB entre une des cartes et le PC, puis à construire un réseau en étoile entre cette carte et les autres. Pour la liaison PC-Arduino (en noir ci-dessous), on reprend la méthode décrite dans l’article dédié (Envoyer les variables de simulation à une carte Arduino). Pour la communication avec les autres cartes, le protocole sera adapté mais on gardera un principe similaire.

Pour la suite on nommera la carte reliée au PC « maitre », et les autres cartes « esclaves ». Cette architecture a l’avantage de permettre l’échange direct de données entre la carte « maitre » et les cartes « esclaves ». Par contre, la carte « maitre » doit rediriger toutes les communications entre carte « esclave » et le PC ou entre les cartes « esclave » elles-mêmes. A vu du faible nombre de telles communications, c’est finalement cette architecture qui est retenue pour le simulateur CC72000 V2, puis reconduite sur BB26000.

Câblage de la liaison Série

Détaillons désormais la communication entre deux carte Arduino (représentée en orange ci-dessus). Avant toute chose, il faut préciser que la technologie de communication retenue est une simple liaison Série. Il est également possible d’utiliser d’autres technologies/protocoles de communications plus haut niveau, tels l’I2C par exemple, mais la technologie Série présente l’avantage d’être facile à comprendre et à mettre en œuvre.

Une liaison Série se compose de deux conducteurs : RX et TX, pour les deux sens de communication. Les masses (GND) des différentes cartes doivent être reliées.

Sur une carte Arduino Mega ou Due, les ports suivants permettent d’établir une liaison Série :

  • 14-15 : Serial 3
  • 16-17 : Serial 2
  • 18-19 : Serial 1

Les pins 0 et 1 correspondent à la liaison Serial 0, la même que celle du port USB de la carte, et en particulier les téléversements depuis le PC. Il n’est donc pas possible d’utiliser ces pins. Au total, il est donc possible de relier 3 cartes « esclave » à la carte « maitre ».

Ports Série de l’Arduino

Pour établir la liaison série entre deux cartes, il suffit de relier le pin RX d’une des cartes au TX de l’autre carte, et inversement, sans oublier de relier entre elles les masses des deux cartes. Par exemple, pour établir une liaison entre le port Sérial 2 de le carte « maitre » avec le Sérial 1 de la carte « esclave », il faut relier les pins de la façon suivante :

  • pin 16 maitre (TX2) – pin 19 esclave (RX1)
  • pin 17 maitre (RX2) – pin 18 esclave (TX1)
  • GND maitre – GND esclave

Autre remarque, certaines cartes Arduino (en particulier la carte Due) fonctionnent en 3.3V, lorsque la plupart des autres sont en 5V. Afin de réaliser une liaison série sans risque entre deux cartes de tension différentes (Mega et Due) par exemple, il faut donc intercaler un convertisseur de niveaux logiques (ci-dessous). Sur FerroviSim, le modèle utilisé est le TXS0108E qui permet de convertir 8 signaux, soit 4 liaisons séries à 2 fils.

Convertisseur de niveaux logiques

Ce module est à câbler selon le schéma suivant, en reliant les RX et TX en 5V sur les pins A1 à A8 du module, et en face les RX et TX en 3.3V sur les pins B1 et B8 du module. Les pins OE et GND doivent être reliés à la masse. Vcca et Vccb fixent les tensions de fonctionnement des deux côté du module.

Schéma de câblage du TXS0108E issu et adapté de la Datasheet du composant.

Pour plus d’informations, vous pouvez contacter la datasheet au lien suivant : TXS0108E

Le code pour la communication

La dernière étape pour terminer le système de communication entre les deux cartes, et d’écrire sur chacune des cartes le code d’envoi et de réception des données. Côté réception, le code sera le même que pour la réception des données depuis le programme Python, en remplaçant « Serial » ou « SerialUSB » par « Serial1 », « Serial2 » ou « Serial3 » selon le port utilisé. Vous pouvez donc utiliser le code présenté à la page dédiée.

Le protocole de communication peut être le même qu’avec le programme Python : une lettre pour identifier la variable envoyée, la variable numérique du 1 à 4 chiffres, puis le délimiteur « / ». Par exemple pour envoyer une vitesse de 100 km/h, on enverra « V100/ » sur le port série.

Pour l’envoi d’une variable, par exemple ici la vitesse stockée dans la variable arduino « speed », il suffit d’utiliser le code suivant (ici pour le port Serial3).

Serial3.print("V");
Serial3.print(speed);
Serial3.print("/");

En combinant le code de réception et le code d’émission, on peut ensuite par exemple rediriger des données envoyée par une carte « esclave » à la carte « maitre » vers une autre carte « esclave ».

Parallèle avec les simulateurs FerroviSim CC72000V2 et BB26000

Afin de mieux comprendre les cas d’utilisation de l’architecture décrite ci-avant, on peut se pencher sur la façon dont elle est mise en œuvre sur les simulateurs FerroviSim.

Sur la CC72000 V2 et la BB26000, la carte « maitre » est une carte Due. Celle-ci communique avec le PC (programme Python) part le port série « SerialUSB », et fonctionne en 3.3V. On compte ensuite 2 cartes « esclaves » : une pour la commande des voltmètres, ampèremètres et voyants du pupitre (esclave 1), et une seconde pour le KVB (esclave 2). Ces deux cartes « esclaves » sont des cartes « Mega » fonctionnant en 5V, nécessitant d’intercaler un module convertisseur de niveaux logiques. Les variables échangées sont les suivantes (liste simplifiée, à titre indicatif) :

  • Maitre => Esclave 1 : intensité moteurs, tensions, état des lampes
  • Maitre => Esclave 2 : état des afficheurs KVB, état de LSSF, état des voyants
  • Esclave 2 => Maitre : état d’appui du BPFU (à venir : état d’appui sur BP FC)

Laisser un commentaire