ARDUINO – Bus I2C

I2C est un protocole de communication série multi-esclaves multi-maitres. on le trouve parfois sous le nom IIC ou TWI (Two Wire Interface) ou TWSI (Two Wire Serial Interface).

c’est un bus série synchrone bi-directionnel half-duplex.Les échanges ont lieu entre un seul maître et un (ou tous les) esclave(s), à l’initiative du maître (jamais de maître à maître ou d’esclave à esclave) mais rien n’empêche un composant de passer du statut de maître à esclave ou réciproquement.

La connexion est réalisée au moyen de deux lignes :

  • une ligne SDA (Serial Data ) : ligne de données bidirectionnelle,
  • une ligne SCL (Serial Clock ) : ligne d’horloge de synchronisation .

à ces 2 lignes , on rajoute une ligne de masse et une ligne d’alimentation Vdd qui tire les 2 lignes SDA et SCL au niveau Vdd au travers de resistance de Pul Up .

dernier point important , chaque composant du circuit a une adresse hexadécimale du type 0xYZ qui permet l’ échange entre maitre et esclave . le fonctionnement est asses similaire a celui de la distribution du courrier par la poste; l’ expéditeur ( le maitre) envoi un message a l’adresse du destinataire ( l’esclave) . le bus I2C c’est le facteur sur son itineraire de distribution, avec la particularité qu’a chaque fois il rentre a la poste pour aller chercher le courrier suivant et le distribuer a l’adresse suivante.

pour plus d’info voir l’article Wikipedia:

https://fr.wikipedia.org/wiki/I2C

une des utilisation les plus basiques avec ARDUINO concerne les aspect IHM ( Interface Homme Machine) , a savoir la connexion de clavier et d’ecran ceci afin d’économiser des entrées /sorties Analogiques et Numériques sur l’ARDUINO. mais on trouve aussi des Joysticks I2C , des capteurs I2C et tout un tas d’elements compatibles avec ce protocole.

ci dessous un exemple de schéma pour un Interface de commande sur un montage ARDUINO:

le fonctionnement d’un ARDUINO en mode I2C nécessite des Librairies . dont basiquement la Librairie “Wire” qui assure le protocole de communication . a cette librairie , il faut en général ajouter d’autres librairies dédiées aux composants utilisés.

pour la librairie Wire , voici le lien vers le site ARDUINO pour les commandes de base:

https://www.arduino.cc/en/Reference/Wire

pour le fonctionnement en I2C , chaque module ARDUINO possede des broches dédiées, (voir rubrique “generalités/Pinout”) , pour l’ARDUINO UNO il s’agit des broches A4 et A5:

passons maintenant a des cas pratiques , a titre de premier exemple , nous allons traiter le cas de l’afficheur LCD 16 x 2

AFFICHEUR LCD I2C 16×2:

l’utilisation d’un afficheur LCD I2C 16×2 nécessite une librairie spécifique. ici nous utiliserons la librairie “LiquidCrystal_I2C.h” qu’il vous faudra installer avant de téléverser le programme dans l’arduino uno . faire une recherche google pour la trouver .

deuxieme étape préliminaire , il vous faudra trouver l’adresse I2C de votre écran , pour cela , ouvrir l’IDE ARDUINO et charger le programme I2Cscanner ci dessous puis le téléverser et ouvrir le moniteur série . le programme scanne le bus I2C et affiche les adresse I2C connectées trouvées . utiliser le programme avec un seul composant sur le bus a la fois vous permet de trouver l’adresse I2C de celui ci.

une fois l’adresse I2C trouvée , ensuite téléverser le petit programme ci dessous et regarder ce qui s’affiche :

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);   // initialise l'afficheur a l'adresse 0x27  et précise le nbre de caractères et de lignes 

void setup() {
  lcd.init();   // initialise l'afficheur LCD                     
  lcd.backlight();   // allume le rétroéclairage de l'afficheur 
}

void loop(){
  lcd.setCursor(0,0);  // curseur en colonne 0 ligne 0
  lcd.print("apprendre avec");
  lcd.setCursor(0,1);  // curseur en colonne 0 ligne 1
  lcd.print("E-TECHNO-TUTOS");
}

dans le cas d’utilisation d’un afficheur 20×4 , il suffit de remplacer la ligne en rouge par la commande suivante:

LiquidCrystal_I2C lcd(0x27,20,4);

UN CLAVIER MATRICIEL I2C:

voyons maintenant comment faire un clavier matriciel I2C à partir d’un simple clavier 4×4 et d’un Module d’extension PCF8574

le module PCF8574 a pour fonction de convertir les états ( haut/bas) d’une ligne de 8 signaux digitaux arrivant en parallèle en une information série d’une chaine de 8 bits . le module fonctionne egalement dans l’autre sens, si on lui envoie une chaine de 8 bits , il reparti les 8 bits en état de sortie haut ou bas sur les 8 lignes . c’est donc un convertisseur série/parallèle à double sens de conversion.

cette capacité de conversion va pouvoir être utilisée pour convertir l’état des touches clavier en un signal 8 bits qui sera converti en son caractère correspondant via une table de conversion adéquate .

par ailleurs , le module comporte des cavaliers A0-A1-A2 permettant de fixer l’adresse Hexa I2C du module: par exemple sur le module ci dessous , les 3 cavaliers sont positionnés sur la masse soit un niveau 0 pour A0-A1-A2, soit une adresse 8 bit de 0100000 ce qui fait 20 en hexadécimal , l’adresse du module sur le bus I2C sera donc 0x20

une fois l’adresse hexa fixée , le module PCF 8574 peut être connecté au clavier

voyons maintenant un petit programme pour utiliser cet ensemble avec un ecran I2C 16×2 ( il suffit de mettre l’ecran et le PCF8574 en serie sur le port I2C ):

le programme ci dessous affiche sur le LCD les touches appuyées.

#include <Wire.h>
#include <Keypad_I2C.h>   // bibliotheque Keypad I2C
#include <Keypad.h>       // bibliotheque Keypad classique
#include <LiquidCrystal_I2C.h>    // bibliotheque LCD I2C
#define I2CADDR 0x20      // 0x20 adresse exa du clavier
LiquidCrystal_I2C lcd(0x27,16,2);  // 0x27 addresse LCD  16x2

const byte ROWS = 4; // 4 lignes
const byte COLS = 4; //4 colonnes
//definition des valeurs associees aux boutons du clavier
// char hexaKeys[ROWS][COLS] = {{'1','2','3','A'},{'4','5','6','B'},{'7','8','9','C'},{'*','0','#','D'}};
char hexaKeys[ROWS][COLS] = {{'A','B','C','D'},{'3','6','9','#'},{'2','5','8','0'},{'1','4','7','*'}};
byte rowPins[ROWS] = {7, 6, 5, 4};      //connection aux broche de ligne du clavier
byte colPins[COLS] = {3, 2, 1, 0};      // connection aux broche de colonne  du clavier

//initialize une instance de classe NewKeypad
Keypad_I2C customKeypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS, I2CADDR); 

void setup() {  
  Wire.begin( );                // démarre la communication I2C
  lcd.init();                   // initialise l'ecran LCD
  lcd.backlight();              // retro eclairage allumé
  customKeypad.begin( );        // demarre le clavier 
  lcd.clear();
  lcd.setCursor(0,0);           // curseur colonne 0 ligne 1 
  
  
void loop() {
  char customKey = customKeypad.getKey();
  while(customKey == NO_KEY)customKey=customKeypad.getKey();
  	lcd.clear();
  	lcd.setCursor(0,0);           // curseur colonne 0 ligne 1
  	lcd.print(customKey);   
  delay (100);    
}