Échanger des données entre un périphérique et une carte Arduino via le protocole i2C

Présentation

Le bus I2C (Inter Integrated Circuit Bus) a été développé par Philips dans les années 80, pour permettre de relier facilement à un microprocesseur divers circuits intégrés (spécialisés dans le stockage et l'affichage de données, dans l'exécution de fonctions numériques ou analogiques diverses), en particulier dans un téléviseur.

Il existe d'innombrables périphériques exploitant ce bus, dans les appareils TV et vidéo (récepteur télécommande, réglages ampli BF, tuner, horloge ...), mais aussi dans les systèmes audio et radio, postes téléphoniques, systèmes électroniques automobiles, PC, appareils électroménagers, etc.

De nombreux fabricants ayant adopté ce système, la variété des circuits disponibles disposant d'un port I2C est énorme :

  • capteurs de température, d'humidité, accéléromètres ou gyroscopes ;

  • convertisseurs A/N et N/A

  • mémoires (RAM, EPROM, EEPROM, etc) ;

  • circuits Audio (Égaliseur, Contrôle de volume, etc) ;

  • autres drivers (LED, Afficheurs LCD, etc)

Le bus I2C permet de faire communiquer, par une liaison série synchrone, entre eux des composants électroniques très divers grâce à seulement trois fils :

  • un signal de donnée (SDA) ;

  • un signal d'horloge (SCL) ;

  • la masse (0V).

Une des particularités de la liaison I2C est que l'on peut faire communiquer le maître (en général le microcontrôleur de la carte Arduino) avec une multitude d'esclaves (les périphériques) en les reliant tous au même bus. Il faut uniquement mettre deux résistances de tirage sur les lignes SDA et SCL.

Chaque esclave est identifié par une adresse unique. Seul le maître peut initier une communication.

Le maître envoie tout d'abord l'adresse du périphérique dont il désire recevoir les données. L'esclave envoie un premier signal de confirmation (acknowledgement) pour signifier qu'il a bien reçu la demande.

Puis le maître envoie l'adresse d'un registre interne du périphérique. Par exemple, pour un accéléromètre, on a trois registres stockant respectivement les données de l'accélération selon X, Y et Z. Un deuxième signal de confirmation est envoyé par le périphérique.

Enfin c'est le périphérique qui émet cette fois le message, en transférant la valeur du registre qui a été sollicité. Il termine avec une dernière confirmation, après quoi le maître envoie un signal spécifique pour mettre fin à la communication.

Le processus est similaire pour l'écriture sur un périphérique par le microcontrôleur, pour piloter un actionneur ou sauvegarder des données par exemple. Dans ce cas une commande spécifique est envoyée lors de l'adressage du registre et c'est le maître qui transmet les données.

Utilisation

La première chose à faire est d'identifier l'adresse des périphériques liés à la carte Arduino, et l'adresse de leur divers registres internes. Ces informations sont données dans la fiche technique. Ensuite, dans le cas d'une connexion de périphériques externes, indépendants ou montés sur d'autres cartes Arduino, il faut identifier les ports attribués aux lignes SDA et SCL de chaque carte ou composants et les relier entre eux.

Ne pas oublier de connecter chaque composant à l'alimentation (5V / GND ou 3,3V / GND).

Les 2 ports de la liaison I2C sur l'Arduino Uno se situent : sur la broche analogique A4 pour SDA et sur la broche analogique A5 pour SCL.

Une bibliothèque Wire() permet de gérer les échanges d'informations entre la carte Arduino et les périphériques. Cette bibliothèque est installée de base dans l'IDE Arduino. Les principales fonctions de cette bibliothèque sont :

  • Wire.begin() : initialise la communication sur le bus I2C, à effectuer au début de votre programme.

  • Wire.beginTransmission(adresse de l'esclave) : débute un échange d'informations entre le maître et l'esclave dont l'adresse est spécifiée.

  • Wire.endTransmission() : arrête l'échange d'informations entre le maître et l'esclave.

  • Wire.write(adresse du registre sollicité) : accède à un registre de l'esclave. Est à appeler avec écrire ou lire des données.

  • Wire.write(octet à écrire) : envoi d'un octet sur le bus. Écrit les données désirées dans le registre sollicité au préalable.

  • Wire.requestFrom(adresse de l'esclave, nb_octets) : le maître demande à l'esclave dont l'adresse est spécifiée de lui transmettre un nombre d'octets.

  • Wire.read() : le maître lit des données en provenance d'un esclave.

  • Wire.available() : renvoie le nombre d'octets présents sur le bus I2C.

Utilisation boussole GY-11

Brancher comme ci-dessous :

Télécharger la bibliothèque : lsm303-arduino-master

Code :

voir lsm303-arduino-master/Examples/Heading (pour la boussole)

voir lsm303-arduino-master/Examples/Serial (pour l'accéléromètre)

Attention : ne pas oublier d'exporter la biblio lsm303-arduino-master