Faire communiquer 2 arduinos entre eux sur 2 fils

arduino2arduino

Pour faire communiquer 2 arduinos entre eux, plusieurs solutions sont possibles: avec des shields (ethernet, bluetooth, wifi) ou avec des circuits externes (comme des nRF2401) par exemple. Ces solutions sont souvent couteuses et bloquent des E/S.

Voici une solution qui permet de faire dialoguer 2 arduinos entre eux, quels que soient leurs types (uno / leonardo, micro, mini etc ..) en utilisant les E/S analogiques. Cette solution permet de conserver les E/S digitales pour d’autres utilisations, ainsi que les E/S D0 et D1 qui peuvent servir à de la communication série.

Apres moultes recherches, je suis tombé sur une librairie : EasyTransferI2C qui permet d’envoyer / recevoir sur plusieurs arduinos (et non pas seulement sur 2 !) des informations avec une vérification du transfert. (la librairie s’assure que si l’on envoie 1 d’un côté, l’autre côté reçoit bien 1)

Pré requis

Il vous faut la libraire wire, ainsi que EasyTransfert bien sur.
Pour archive, je l’heberge sur mon serveur : Librairie EasyTransferI2C

Elle est également accessible sur github : https://github.com/madsci1016/Arduino-EasyTransfer 

Mise en oeuvre

Pour commencer, on déclare la variable EasyTransfert

EasyTransferI2C ET;

ainsi qu’une structure qui va nous servir à échanger plusieurs informations

struct Echange {
    int val1;
    int val2;
} echange;

Ici, on se contente donc d’échanger 2 valeurs de type INT, mais vous pouvez tres bien prendre des types différents.

On démarre une communication en s’identifiant comme étant l’appareil numéro 4 (qui n’a rien à voir avec le fait que l’on utilise A4 et A5) :

void setup()
{
  Wire.begin(4);                // join i2c bus with address #4

  ET.begin(details(echange), &Wire);
  Wire.onReceive(receiveEvent);
}

Et on définit :

  • que l’on va échanger à l’aide de la structure echange (sachant que ce n’est pas obligatoire)
  • que lorsque l’on recoit quelque chose, on appelera automatiquement la fonction receiveEvent. Cette méthode agira alors comme une sorte d’interruption.
    Notez que l’on peut simplement boucler dans le loop au lieu de passer par ce mécanisme.

Dans le loop, on regarde si l’on reçoit quelque chose :

if(ET.receiveData()){
    if(DEBUG) { Serial.print("donnes recues :"); }
    if(DEBUG) { Serial.print("val1:"); }
    if(DEBUG) { Serial.println(echange.val1); }
    if(DEBUG) { Serial.print("val2:"); }
    if(DEBUG) { Serial.println(echange.val2); }
}

On peut également envoyer quelque chose à l’appareil qui s’est identifié comme étant le numéro 3.

echange.val1 = 27;
echange.val2 = 53;
ET.sendData(3);

Et donc l’autre arduino doit s’identifier comme numéro 3 et doivent partager la même structure d’échange :

void setup()
{ 
  Wire.begin(3);
  Wire.onReceive(receiveEvent);
  ET.begin(details(echange), &Wire);
}

 

Pour aller plus loin

On peut surcharger la structure d’échange en décidant d’envoyer directement des données :

string rep = "coucou";
char charBuf[rep.length()+1];
rep.toCharArray(charBuf, rep.length()+1) ;
Wire.beginTransmission(3); // transmit to device #3
Wire.write(charBuf);
Wire.endTransmission();

Bien entendu, il faudra gérer ce cas sur le deuxième arduino :

void receiveEvent(int howMany)
{
  String buffer = "";
  while(1 <= Wire.available()) // loop through all but the last
  {
    char c = Wire.read(); // receive byte as a character
    buffer_rfid += c;
  }
  if(DEBUG) { Serial.print("buffer : ");}
  if(DEBUG) { Serial.println(buffer );}

  if(buffer == "coucou") 
    bla bla bla
}

 

Nous avons vu ici uniquement les événements de réceptions. C’est à dire que l’arduino 3 envoie des informations de sa propre initiative à l’arduino 4 et vice versa. Il est possible de faire en sorte que l’arduino 4 demande des informations à l’arduino 3. Pour cela, on pourra passer par

Wire.onRequest(requestEvent);

dans le setup de l’arduino 3 qui devra alors disposer d’une fonction requestEvent pour répondre aux questions de l’arduino 4.

4 thoughts to “Faire communiquer 2 arduinos entre eux sur 2 fils”

  1. Bonjour,

    je souhaiterais obtenir plus d’information sur ce tuto.

    En effet, j’essaie de faire communiquer deux esp8266, un qui relève une T° et l’autre qui la recoit ouvre ou ferme un relais.

    mon matériel est le suivant :
    – arduino + esp8266 + lm35 pour la relève de T°
    – arduino + esp8266 + relais pour allumage radiateur

    Je peine à créer le code…

    Peut on échanger à ce sujet.

    merci d’avance

    1. Bonjour Sylvain,

      Quelle version d’ESP8266 utilises tu ?
      Pourquoi utiliser un arduino alors qu’à priori un ESP8266 suffirait à lui seul?

  2. bonjour,

    j’ai deux questions, quelle distance maxi entre les cartes et combien de carte peux-t-on interfacer ??

    merci

    1. Bonjour nexen,

      La distance maxi est fonction du support que tu va utiliser. Si tu utilise du RJ45 blindé par ex, tu n’auras pas de difficultés a atteindre plusieurs dizaines de mètres, voire sans doute plus.
      Pour la quantité, c’est pareil, si tu code un système permettant de relayer un message d’un arduino à un autre, c’est potentiellement illimité.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *