Dialogue serie arduino DUE our multiplexage

Bonjour,

Je suis en pleine recherche pour faire communiquer deux arduinos DUE pour monter un petit système multiplexé en full duplex (plusieurs échanges de valeurs de capteurs et ordres) si possible (malgré toutes les recherches).
Le tuto super en explications “implémenter un protocole de communication pour arduino” m’a permis de comprendre et progresser dans mes apprentissages mais je me pose plusieurs questions pour l’autodidacte que je suis sur arduino et en programmation :

  • Je me trouve très loin des fonctions prévues par la bibliothèque serial et qui devraient nous permettre d’arriver au même résultat ?
  • Là on se retrouve avec une programmation complète pour quelqu’un d’averti que je ne peux pas transposer avec quelques modifications?
    -Si je dois faire aboutir un projet de multiplexage peut-on le faire avec la librairie serial de base? ou faut-il abandonner le projet car irréaliste pour un autodidacte?

J’aurai bien besoin de vos avis, conseils et aide car là je n’arrive pas à voir si on peut bâtir un tel projet avec les fonctions arduino qui permettent à des autodidactes de faire des choses complexes avec des librairies qui cachent un peu la difficulté ou alors il faut se résoudre à toujours laisser cela à des informaticiens bien formés (je ne peux malheureusement pas envisager d’étudier les fondements de l’informatique pendant des années pour effectuer un tel petit projet, je serai obligé de revenir à des fonctions câblées point à point).

je me croyais aussi sauvé avec la bibliothèque “EasyTransfer Arduino Library” sauf quelle a du mal à s’installer puis elle ne compile pas (dommage) : EasyTransfer Arduino Library « The Mind of Bill Porter.

Merci de vos réponses

Cordialement

Jean-Claude

Pour savoir quel protocole convient il faudrait en dire un peu plus :

  • distances
  • support physique (Serial, I2C, Ethernet, etc.)

J'ai dans mes archives un protocole série : arduino-un-protocole-serie

Ce protocole peut gérer des trames binaires (mode transparent) en toute sécurité avec un CRC, des relances, etc.

Voir exemples : sdltp-serial-protocol/src/master/examples

Bonjour et merci du retour,

Le but c'est de faire dialoguer deux arduino due (je me sers de cette platine car mémoire importante, rapide, nombre d'E/S importantes bus CAN etc.) avec une distance de 1 à deux mètres les séparant.

Au départ je voulais me servir des bus CAN car je voulais le démystifier pour mes élèves car je suis prof de maintenance de matériels TP et agricoles pour y faire quelques mesures. mais impossible avec des petites cartes

Peine perdu le programme écho ne tournait même pas et la tension sur le bus est constante à 1.7V ce qui signifie pas de dialogue.

je me suis rabattu sur la liaison série soi-disant simple et pas besoin d'interface pour débuter, après diverses lectures et début de code pas si simple que ça donc je désespère un peu.

le but de l'exercice : un arduino qui gère différentes acquisitions de capteurs moteurs et réalise certains ordres (démarrage moteur etc) et l'autre qui lui aussi récupère des données de quelques capteurs, gère des affichages et donne des ordres par exemple le démarrage moteur.

Voila en gros mon bût mais que d'épreuves pour un autodidacte de l'informatique....

Je vais éplucher tes différents liens demain, mais si tu as autre chose pour me faire dialoguer ces deux DUE sous protocole série avec leurs ports et dans la foulée le bus CAN peut-être ce serait super.

Encore merci

Jean-Claude

Je ne comprends pas très bien pourquoi ton Bus CAN ne fonctionnerait pas. Pour utiliser ces bus, il faut soit ajouter un transceiver (attention choisir un transceiver CAN 3.3V):

Soit utiliser un simple montage avec 2 diodes et une résistance comme indiqué dans l’Application Note de Siemens, ça fonctionne jusqu’à 2 à 3 mètres. Bien entendu c’est plutôt à réserver à une phase de tests(Attention à relier au 3.3V, PAS au 5V comme sur l’AP):

La bibliothèque CAN à utiliser est celle de Collin80:

A noter que comme la carte DUE dispose de 2 bus CAN, il est possible de réaliser un montage avec une seule carte pour dialoguer du CAN0 au CAN1 (voir les exemples avec la bibiothèque) et dans ce cas le montage avec diodes et résistance se justifie encore plus.

Tu peux par exemple légèrement changer l’un des codes fournis avec la bibliothèque pour lire une entrée analogique (tu liras du bruit qui change tout le temps) et envoyer le résultat d’un CAN vers l’autre:

#include "variant.h"
#include <due_can.h>

#define TEST1_CAN_TRANSFER_ID    0x11AE756A //random 29 bits
#define TEST1_CAN0_TX_PRIO       15
#define CAN_MSG_DUMMY_DATA       0x11BFFA4E

// CAN frame max data length
#define MAX_CAN_FRAME_DATA_LEN   8

uint32_t sentFrames, receivedFrames;

//Leave this defined if you use the native port or comment it out if you use the programming port
//#define Serial SerialUSB

CAN_FRAME frame1, frame2, incoming;

void setup() {

  Serial.begin(250000);
  
  // Verify CAN0 and CAN1 initialization, baudrate is 1Mb/s:
  if (Can0.begin(CAN_BPS_1000K) &&
  Can1.begin(CAN_BPS_1000K)) {
  }
  else {
    Serial.println("CAN initialization (sync) ERROR");
  }
  
  //Initialize the definitions for the frames we'll be sending.
  //This can be done here because the frame never changes
  frame1.id = TEST1_CAN_TRANSFER_ID;
  frame1.length = MAX_CAN_FRAME_DATA_LEN;
  //Below we set the 8 data bytes in 32 bit (4 byte) chunks
  //Bytes can be set individually with frame1.data.bytes[which] = something
  frame1.data.low = 0x20103040;
  frame1.data.high = CAN_MSG_DUMMY_DATA;
  //We are using extended frames so mark that here. Otherwise it will just use
  //the first 11 bits of the ID set
  frame1.extended = 1;
  
  frame2.id = TEST1_CAN_TRANSFER_ID + 0x200;
  frame2.length = MAX_CAN_FRAME_DATA_LEN;
  frame2.data.low = 0xB8C8A8E8;
  frame2.data.high = 0x01020304;
  frame2.extended = 1;
  
  //Both of these lines create a filter on the corresponding CAN device that allows
  //just the one ID we're interested in to get through.
  //The syntax is (mailbox #, ID, mask, extended)
  //You can also leave off the mailbox number: (ID, mask, extended)
  Can1.watchFor(TEST1_CAN_TRANSFER_ID + 0x200);
  Can0.watchFor(TEST1_CAN_TRANSFER_ID);
  
  //test_1();
}

// Test rapid fire ping/pong of extended frames
/*static */void test_1(void)
{
  
  CAN_FRAME inFrame;
  uint32_t counter = 0;
        
  // Send out the first frame
  Can0.sendFrame(frame2);
  //sentFrames++;

  while (1) {
    delay(1000);
    if (Can0.available() > 0) {
      Can0.read(incoming);
      Serial.print(" Received by CAN0 = ");Serial.println(incoming.data.low);Serial.println(" ");
      frame2.data.low = analogRead(A0);
      Serial.print(" Sent by CAN0 = ");Serial.println(frame2.data.low);
      Can0.sendFrame(frame2);
      //delayMicroseconds(100);
      //sentFrames++;
      //receivedFrames++;
      //counter++;
    }
    if (Can1.available() > 0) {
      Can1.read(incoming);
      Serial.print(" Received by CAN1 = ");Serial.println(incoming.data.low);Serial.println(" ");
      frame1.data.low = analogRead(A0);
      Serial.print(" Sent by CAN1 = ");Serial.println(frame1.data.low);
      Can1.sendFrame(frame1);
      //delayMicroseconds(100);
      //sentFrames++;
     // receivedFrames++;
     // counter++;
    }
  }
}

// can_example application entry point
void loop()
{
  test_1();
}

Sinon, tu peux très facilement relier 2 cartes DUE en liaison serie, mais attention à la longueur des câbles (je n’ai jamais essayé avec des câbles de 2 m) par exemple:
Sur la DUE1 tu connectes RX1/TX1 à TX2/RX2 de la DUE2 (croiser les R et T) et bien sur relier les masses. Je te conseille là encore de commencer par un montage dans lequel tu n’utlises qu’une seule carte au départ. Un exemple simple de cette manip:

/*********************************************************************/
/* Jumper between RX1 and TX2, and another one between TX1 and RX2   */
/*********************************************************************/

char c = 0;
void setup() {
 
  Serial.begin(250000);
  Serial1.begin(2500000); // USART0
  Serial2.begin(2500000); // USART1

  Serial2.print("Hello");
}


void loop() {
  String s;
  s.reserve(10);
  s = "";

  while (Serial1.available() > 0) {
    c = Serial1.read();
    s += c;

  }
  if (s.length() > 0) {
    Serial.println(s);
    Serial2.print(s);
  }
  delay(1000);
}

Bonjour,

Merci des retours ça donne du courage pour la suite, pour les cartes CAN c’est bien cela que j’avais utilisé en 3.3V et j’avais aussi utilisé la bibliothèque de collin80.puis l’exemple écho de

J’avais eu des doutes sur le matériel mais comme j’ai plusieurs platines arduino due et trois tranceiver 3.3V je les avais interfacés mais peine perdue j’obtenais le message : “Error during data transmission”

le bout de programme utilisé était celui-ci basé sur la bibliothèque de collin80

#include "DueCANLayer.h"

// CAN Layer functions
extern byte canInit(byte cPort, long lBaudRate);
extern byte canTx(byte cPort, long lMsgID, bool bExtendedFormat, byte* cData, byte cDataLen);
extern byte canRx(byte cPort, long* lMsgID, bool* bExtendedFormat, byte* cData, byte* cDataLen);

void setup()
{
  // Set the serial interface baud rate
  Serial.begin(115200);
  
  // Initialize CAN controller
  if(canInit(0, CAN_BPS_250K) == CAN_OK)
    Serial.print("CAN0 Initialized Successfully.\n\r");
  else
    Serial.print("CAN0 Initialization Failed.\n\r");
  
}// end setup

void loop()
{
  // Declarations
  byte cTxData[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
  int nTimer = 0;
  
  while(1)  // Endless loop
  {
    delay(1);
    
    // Send the message every 1000 milliseconds
    if(++nTimer == 1000)
    {
      if(canTx(0, 0x18FAFE80, true, cTxData, 8) == CAN_OK)
        Serial.print("Data sent successfully.\n\r");
      else
        Serial.print("Error during data transmission.\n\r");
  
      nTimer = 0;

    }// end if

    // Check for received message
    long lMsgID;
    bool bExtendedFormat;
    byte cRxData[8];
    byte cDataLen;
    if(canRx(0, &lMsgID, &bExtendedFormat, &cRxData[0], &cDataLen) == CAN_OK)
    {
      Serial.print("Rx - MsgID:");
      Serial.print(lMsgID, HEX);
      Serial.print(" Ext:");
      Serial.print(bExtendedFormat);
      Serial.print(" Len:");
      Serial.print(cDataLen);
      Serial.print(" Data:");

      for(byte cIndex = 0; cIndex < cDataLen; cIndex++)
      {
        Serial.print(cRxData[cIndex], HEX);
        Serial.print(" ");
      }// end for

      Serial.print("\n\r");
      
    }// end if

  }// end while

}// end loop

je vous mets aussi le plan de l’installation en PJ réalisé pour cet exercice en écho

Bus can test Arduino DUE.pdf (64.5 KB)

Le montage des noeuds d'un bus CAN nécessite l'ajout d'une résistance de 120 Ohms à chaque extrémité, comme indiqué sur le schéma suivant:

Bonjour,

Oui les cartes “tranceiver 3.3V” intègrent ces résistances et j’obtiens bien les 60 Ohms entre canal H et L (hors tension), comme on est pas sur une tension 5 V avec une tension repos de 2.5 V sans dialogue canal H et L, j’ai fais des montages en faisant légèrement varier les résistances mais résultat inchangé.

Mais je reviens vers vous pour la liaison série qui est directe et qui me pose toujours des problèmes :
J’ai téléchargé les différents liens de hbachetti et installé les différents fichiers:
-henri_bachetti-kernel_timers-a6f2191b802b
-henri_bachetti-mpp-console-logger-64fd4e7fcdb8
-henri_bachetti-sdltp-serial-protocol-dab1ae27bff6

j’ai fait reconnaitre toutes ces bibliothèques par l’IDE en appelant une gestion des bibliothèques

1er problème : J’ouvre les fichiers mais lorsque je les fais contrôler (avant un éventuel téléversement) j’obtiens une erreur "Erreur de compilation pour la carte Arduino DUE

voir détail

Arduino : 1.8.12 (Windows 10), Carte : "Arduino Due (Programming Port)"

In file included from C:\Users\jcc\Documents\Arduino\libraries\henri_bachetti-sdltp-serial-protocol-dab1ae27bff6/protocol.h:6:0,

                 from C:\Users\jcc\Documents\Arduino\libraries\henri_bachetti-sdltp-serial-protocol-dab1ae27bff6/sdltp.h:10,

                 from C:\Users\jcc\Documents\Arduino\libraries\henri_bachetti-sdltp-serial-protocol-dab1ae27bff6\examples\serial-test\serial-test.ino:4:

C:\Users\jcc\Documents\Arduino\libraries\henri_bachetti-sdltp-serial-protocol-dab1ae27bff6/serial_core.h:7:28: fatal error: SoftwareSerial.h: No such file or directory

 #include <SoftwareSerial.h>

                            ^

compilation terminated.

exit status 1
Erreur de compilation pour la carte Arduino Due (Programming Port)

Problème 2 : même avec ces fichiers je reste dans le flou car je ne vois pas comment bâtir un dialogue avec deux arduinos suivant l’exemple du chier des charges:

Arduino 1 :

Gère capteur de température cabine
Gère bouton poussoir de démarrage
Gère enclenchement de la clim en fonction de la température cabine
gère les affichage des données
t° de cabine
reçues de l’arduino 2 qui sont:
t° moteur
pression d’huile moteur
température de l’air admis
pression de turbo
t° de l’air de suralimentation
etc.

l’Arduino 2
reçois et exécute l’actionnement et l’arrêt de la mise en route du démarreur suivant ordre reçu de l’arduino 1
collecte et envoi les informations à l’arduino 1
t° moteur
pression d’huile moteur
température de l’air admis
pression de turbo
t° de l’air de suralimentation
etc.

Voilà ce que je ne me représente pas comment architecturer tout cela et bâtir le programme de chaque arduino

Merci de vos éclairages pour ce projet

Il te manque la librairie SoftwareSerial.

L'ARDUINO 2 doit envoyer une structure contenant les différentes données :
t° moteur
pression d'huile moteur
température de l'air admis
pression de turbo
t° de l'air de suralimentation

Cela se fait avec serial_write()

L'ARDUINO 1 reçoit les données de l'ARDUINO 2 avec serial_read()

L'initialisation (setup) : Bitbucket

Personnellement j'adopterais un dialogue question réponse :

  • l'ARDUINO 1 est le maître
  • l'ARDUINO 2 est l'esclave
  • l'ARDUINO 1 pose les questions
  • l'ARDUINO 2 répond aux questions

Rien n'empêche de poser des questions simples pour récupérer chaque donnée séparément.

Les exemples sont simples :

transmitter : un émetteur qui envoie une structure.

receiver : un récepteur qui reçoit la même structure.

Ces deux exemples sont configurés pour dialoguer sur Serial2 de 2 cartes MEGA, mais tu peux aussi configurer autrement.

Il est bien entendu que cette librairie fonctionne sur ligne série (Serial et SoftwareSerial).

Je n'ai pas testé d'autres supports physiques, CAN par exemple.

La page d'accueil décrit l'API : sdltp-serial-protocol