Site icon AranaCorp

Gérez plusieurs Arduino avec un bus I2C

4.4
(14)

Il peut être pratique, notamment dans des projets de domotique, de communiquer entre plusieurs appareils. Une des techniques couramment utilisée est le protocole I2C (ou TWI). Le protocole I2C est une méthode qui permet de connecter plusieurs cartes « Maîtres » et plusieurs cartes « Esclaves » et de faire communiquer jusqu’à 128 appareils. Elle permet des connexions asynchrones entre plusieurs composants pour partager des informations via un « bus commun ».  Nous avions vu la communication via le port Série (dit UART) qui est utilisée pour envoyer le code à l’Arduino par un ordinateur ou pour connecter deux appareils notamment en Bluetooth.

N.B.: Il est bon de noté que la communication I2C est prévue, au départ, pour de la communication carte à carte. De ce fait, elle n’est pas adaptée pour la communication sur de longues distances (>1m)

Matériel

Schéma de connexion du bus I2C entre cartes Arduino

Avec le protocole I2C, il est aussi possible de communiquer entre différents systèmes (capteurs, écran LCD, Raspberry Pi, etc.). Un exemple intéressant est la communication entre plusieurs cartes Arduino. Pour cela, il nous faut écrire au moins deux programmes, un pour la carte « Maîtresse » (Master) et l’autre pour les cartes « Esclaves » (Slaves).

Une communication I2C est défini par un bus de deux fils (parfois appelé TWI, Two Wire Interface) et une adresse. Les broches utilisées par la communication I2C sont généralement fixé pour chaque appareil. L’une sur laquelle sont envoyées les données (SDA Serial Data Line) et sur l’autre l’horloge de synchronisation (SLC Serial Clock Line).

Broches I2C/TWI:

Dans cet exemple nous utilisons une carte Arduino Uno, donc, les broches A4 et A5.

Afin que les deux cartes communiquent entre elles il faut les relier correctement (A4 avec A4 et A5 avec A5) et ne pas oublier de relier les masses (GND) comme indiqué sur le schéma suivant.

Attention : Si les broches A4 et A5 sont reliées aux broches d’une carte non alimentée, le code se figera au moment de la transmission.

Généralement, une carte va envoyer des informations (Writer) et une autre va les recevoir (Reader).

Code de configuration du bus I2C

La libraire Wire.h permet de les définir simplement la communication série sur le bus I2C. Les fonctions sont similaires à la librairie Serial.

Code de la carte « Maîtresse »

#include <Wire.h>
# define I2C_SLAVE1_ADDRESS 11
# define I2C_SLAVE2_ADDRESS 12
#define PAYLOAD_SIZE 2
int n=0;
void setup()
{
 Wire.begin();        
 Serial.begin(9600);  
 Serial.println(F("-------------------------------------I am the Master"));
 delay(1000);
 //Request value of n to slave
 Wire.requestFrom(I2C_SLAVE1_ADDRESS, 1);   
 n = Wire.read(); 
 Serial.print(F("recieved value : "));
 Serial.println(n);
 //Send value 12 to slave
 Wire.beginTransmission(I2C_SLAVE1_ADDRESS); 
 Wire.write(12); 
  Serial.print(F("sending value : "));
 Serial.println(12);              
 Wire.endTransmission();   
 Serial.print(" ");
 //Request value of n to slave after change
 Wire.requestFrom(I2C_SLAVE1_ADDRESS, 1); 
 n = Wire.read();
 Serial.print(F(" new recieved value : "));
 Serial.println(n); 
}
void loop()
{
 delay(100);
}

Code de la carte « Esclave »

#include <Wire.h>
# define I2C_SLAVE_ADDRESS 11 // 12 pour l'esclave 2 et ainsi de suite
#define PAYLOAD_SIZE 2
void setup()
{
Wire.begin(I2C_SLAVE_ADDRESS);
Serial.begin(9600); 
Serial.println("-------------------------------------I am Slave1");
delay(1000);               
Wire.onRequest(requestEvents);
Wire.onReceive(receiveEvents);
}
void loop(){}
int n = 0;
void requestEvents()
{
Serial.println(F("---> recieved request"));
Serial.print(F("sending value : "));
Serial.println(n);
Wire.write(n);
}
void receiveEvents(int numBytes)
{  
Serial.println(F("---> recieved events"));
n = Wire.read();
Serial.print(numBytes);
Serial.println(F("bytes recieved"));
Serial.print(F("recieved value : "));
Serial.println(n);
}

Ouvrez le moniteur série des cartes esclaves avant le moniteur de la carte maître.

Dans le moniteur série de la carte « Maîtresse »:

Dans le moniteur série de la carte « Esclave 1 »:

Nous pouvons voir que les deux cartes échangent des informations. Il est très facile d’étendre cet exemple à plusieurs cartes Arduino (Leonardo, Mini, etc.) en adaptant le câblage et l’adresse du composants dans le code « Esclave ».

Code pour identifier les périphériques branchés sur le bus I2C

Un bon test pour savoir si vos appareils communiquent bien entre eux est d’utiliser le code ci-dessous (I2CScanner) qui retourne toutes les adresses des appareils branchés à la carte Maîtresse.

    #include <Wire.h>
    
    
   void setup()
   {
     Wire.begin();
     Serial.begin(9600);
     while (!Serial);             // Leonardo: wait for serial monitor
     Serial.println(F("\nI2C Scanner"));
   }
    
    
   void loop()
   {
     byte error, address;
     int nDevices;
    
     Serial.println(F("Scanning..."));
    
     nDevices = 0;
     for(address = 1; address < 127; address++ )
     {
       // The i2c_scanner uses the return value of
       // the Write.endTransmisstion to see if
       // a device did acknowledge to the address.
         Wire.beginTransmission(address);
         error = Wire.endTransmission();
         
       
       if (error == 0)
       {
         Serial.print("I2C device found at address 0x");
         if (address<16)
           Serial.print("0");
         Serial.print(address,HEX);
         Serial.println("  !");
    
         nDevices++;
       }
       else if (error==4)
       {
         Serial.print("Unknown error at address 0x");
         if (address<16)
           Serial.print("0");
         Serial.println(address,HEX);
       }    
     }
     if (nDevices == 0)
       Serial.println(F("No I2C devices found\n"));
     else
       Serial.println(F("done\n"));
    
     delay(5000);           // wait 5 seconds for next scan
   }

Si vous avez des difficultés pour mettre en place une communication I2C entre différents appareils n’hésitez pas à nous laisser un commentaire ou à nous contacter.

Sources

Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie

How useful was this post?

Click on a star to rate it!

Average rating 4.4 / 5. Vote count: 14

No votes so far! Be the first to rate this post.

Quitter la version mobile