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.
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
Bonjour Sylvain,
Quelle version d’ESP8266 utilises tu ?
Pourquoi utiliser un arduino alors qu’à priori un ESP8266 suffirait à lui seul?
bonjour,
j’ai deux questions, quelle distance maxi entre les cartes et combien de carte peux-t-on interfacer ??
merci
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é.