- Qu'est-ce que le protocole de communication I2C?
- Comment fonctionne I2C Communication?
- Où utiliser la communication I2C?
- I2C dans Arduino
- Composants requis
- Schéma
- Explication de travail
- Programmation I2C dans Arduino
- Explication de la programmation Master Arduino
- Explication de la programmation Arduino esclave
Dans notre tutoriel précédent, nous avons appris la communication SPI dans Arduino. Aujourd'hui, nous allons découvrir un autre protocole de communication série: I2C (Inter Integrated Circuits). En comparant I2C avec SPI, I2C n'a que deux fils tandis que SPI en utilise quatre et I2C peut avoir plusieurs maîtres et esclaves, tandis que SPI ne peut avoir qu'un seul maître et plusieurs esclaves. Il y a donc plus d'un microcontrôleur dans un projet qui doivent être maîtres, puis I2C est utilisé. La communication I2C est généralement utilisée pour communiquer avec le gyroscope, l'accéléromètre, les capteurs de pression barométrique, les écrans LED, etc.
Dans ce tutoriel Arduino I2C, nous utiliserons la communication I2C entre deux cartes Arduino et nous enverrons des valeurs (0 à 127) l'une à l'autre à l'aide d'un potentiomètre. Les valeurs seront affichées sur l'écran LCD 16x2 connecté à chacun des Arduino. Ici, un Arduino agira en tant que maître et un autre agira en tant qu'esclave. Commençons donc par l'introduction de la communication I2C.
Qu'est-ce que le protocole de communication I2C?
Le terme IIC signifie « Inter Integrated Circuits ». Il est normalement désigné comme I2C ou I au carré C ou même comme protocole d'interface à 2 fils (TWI) à certains endroits, mais cela signifie tous la même chose. I2C est un protocole de communication synchrone, ce qui signifie que les deux appareils qui partagent les informations doivent partager un signal d'horloge commun. Il n'a que deux fils pour partager les informations dont l'un est utilisé pour le signal du robinet et l'autre est utilisé pour l'envoi et la réception de données.
Comment fonctionne I2C Communication?
La communication I2C a été introduite pour la première fois par Phillips. Comme dit précédemment, il a deux fils, ces deux fils seront connectés entre deux appareils. Ici, un appareil est appelé maître et l'autre appareil est appelé esclave. La communication doit et se produira toujours entre deux un maître et un esclave. L'avantage de la communication I2C est que plus d'un esclave peut être connecté à un maître.
La communication complète s'effectue via ces deux fils à savoir, Serial Clock (SCL) et Serial Data (SDA).
Serial Clock (SCL): partage le signal d'horloge généré par le maître avec l'esclave
Serial Data (SDA): envoie les données depuis et vers le maître et l'esclave.
A tout moment, seul le maître pourra initier la communication. Puisqu'il y a plus d'un esclave dans le bus, le maître doit se référer à chaque esclave en utilisant une adresse différente. Lorsqu'il est adressé, seul l'esclave avec cette adresse particulière répondra avec les informations tandis que les autres continueront de quitter. De cette façon, nous pouvons utiliser le même bus pour communiquer avec plusieurs appareils.
Les niveaux de tension de I2C ne sont pas prédéfinis. La communication I2C est flexible, ce qui signifie que l'appareil qui est alimenté par 5v volts peut utiliser 5v pour I2C et que les appareils 3.3v peuvent utiliser 3v pour la communication I2C. Mais que se passe-t-il si deux appareils fonctionnant sur des tensions différentes doivent communiquer via I2C? A 5 V bus I2C ne peut pas être connecté avec le dispositif 3.3V. Dans ce cas, des décaleurs de tension sont utilisés pour faire correspondre les niveaux de tension entre deux bus I2C.
Il existe un ensemble de conditions qui encadrent une transaction. L'initialisation de la transmission commence par un front descendant de SDA, qui est défini comme une condition «START» dans le diagramme ci-dessous où le maître laisse SCL haut tout en réglant SDA bas.
Comme indiqué dans le diagramme ci-dessous, Le front descendant de SDA est le déclencheur matériel de la condition START. Après cela, tous les appareils du même bus passent en mode d'écoute.
De la même manière, le front montant de SDA arrête la transmission qui est montrée comme condition «STOP» dans le diagramme ci-dessus, où le maître laisse SCL haut et libère également SDA pour passer à HIGH. Le front montant du SDA arrête la transmission.
Le bit R / W indique le sens de transmission des octets suivants, s'il est HIGH signifie que l'esclave émettra et s'il est bas, le maître émettra.
Chaque bit est transmis à chaque cycle d'horloge, il faut donc 8 cycles d'horloge pour transmettre un octet. Après chaque octet envoyé ou reçu, le neuvième cycle d'horloge est maintenu pour l'ACK / NACK (acquitté / non acquitté). Ce bit ACK est généré par l'esclave ou le maître en fonction de la situation. Pour bit ACK, SDA est réglé à faible à 9 par le maître ou l' esclave ème cycle d'horloge. Donc c'est bas qu'il est considéré comme ACK sinon NACK.
Où utiliser la communication I2C?
La communication I2C est utilisée uniquement pour les communications à courte distance. Il est certainement fiable dans une certaine mesure car il a une impulsion d'horloge synchronisée pour le rendre intelligent. Ce protocole est principalement utilisé pour communiquer avec des capteurs ou d'autres appareils qui doivent envoyer des informations à un maître. C'est très pratique lorsqu'un microcontrôleur doit communiquer avec de nombreux autres modules esclaves en utilisant un minimum de fils uniquement. Si vous recherchez une communication longue portée, vous devriez essayer RS232 et si vous recherchez une communication plus fiable, vous devriez essayer le protocole SPI.
I2C dans Arduino
L'image ci-dessous montre les broches I2C présentes dans Arduino UNO.
Ligne I2C | Broche dans Arduino |
SDA | A4 |
SCL | A5 |
Avant de commencer à programmer I2C en utilisant deux Arduino. Nous devons en savoir plus sur la bibliothèque Wire utilisée dans Arduino IDE.
La bibliothèque
1. Wire.begin (adresse):
Utilisation: Cette bibliothèque est utilisée pour établir la communication avec les appareils I2C. Cela lance la bibliothèque Wire et rejoint le bus I2C en tant que maître ou esclave.
Adresse: L'adresse esclave 7 bits est facultative et si l'adresse n'est pas spécifiée, elle rejoint le bus en tant que maître comme ceci.
2. Wire.read ():
Utilisation: Cette fonction permet de lire un octet qui a été reçu d'un appareil maître ou esclave, soit qui a été transmis d'un appareil esclave à un appareil maître après un appel à requestFrom (), soit a été transmis d'un maître à un esclave.
3. Wire.write ():
Utilisation: Cette fonction est utilisée pour écrire des données sur un appareil esclave ou maître.
Slave to Master: Slave écrit des données sur un maître lorsque Wire.RequestFrom () est utilisé dans master.
Master to Slave: Pour la transmission d'un appareil maître à esclave, Wire.write () est utilisé entre les appels à Wire.beginTransmission () et Wire.endTransmission ().
Wire.write () peut être écrit comme suit:
- Wire.write (valeur)
valeur: une valeur à envoyer en un seul octet.
- Wire.write (chaîne):
string: une chaîne à envoyer sous la forme d'une série d'octets.
- Wire.write (données, longueur):
data: un tableau de données à envoyer sous forme d'octets
length: le nombre d'octets à transmettre.
4. Wire.beginTransmission (adresse):
Utilisation: Cette fonction permet de démarrer une transmission vers le périphérique I2C avec l'adresse d'esclave donnée. Ensuite, créez une file d'attente d'octets pour la transmission avec la fonction write () , puis transmettez-les en appelant la fonction endTransmission () . L'adresse 7 bits de l'appareil est transmise.
5. Wire.endTransmission ();
Utilisation: Cette fonction est utilisée pour terminer une transmission vers un périphérique esclave qui a été commencée par beginTransmission () et transmet les octets qui ont été mis en file d'attente par Wire.write ().
6. Wire.onRequest ();
Utilisation: Cette fonction est appelée lorsqu'un maître demande des données à l'aide de Wire.requestFrom () à partir du périphérique esclave. Ici, nous pouvons inclure la fonction Wire.write () pour envoyer des données au maître.
7. Wire.onReceive ();Utilisation: cette fonction est appelée lorsqu'un appareil esclave reçoit des données d'un maître. Ici, nous pouvons inclure Wire.read (); fonction pour lire les données envoyées par le maître.
8. Wire.requestFrom (adresse, quantité);
Utilisation: Cette fonction est utilisée dans le maître pour demander des octets à un appareil esclave. La fonction Wire.read () est utilisée pour lire les données envoyées par l'équipement esclave.
adresse: l'adresse 7 bits de l'appareil auquel demander des octets
quantité: le nombre d'octets à demander
Composants requis
- Arduino Uno (2-Nos)
- Module d'affichage LCD 16X2
- Potentiomètre 10K (4-Nos)
- Planche à pain
- Connexion des fils
Schéma
Explication de travail
Ici, pour démontrer la communication I2C dans Arduino, nous utilisons deux Arduino UNO avec deux écrans LCD 16X2 reliés l'un à l'autre et utilisons deux potentiomètres sur les deux arduino pour déterminer les valeurs d'envoi (0 à 127) du maître à l'esclave et de l'esclave au maître en faisant varier le potentiomètre.
Nous prenons la valeur analogique d'entrée à la broche arduino A0 de (0 à 5V) en utilisant un potentiomètre et les convertissons en valeur analogique en numérique (0 à 1023). Ensuite, ces valeurs ADC sont ensuite converties en (0 à 127) car nous ne pouvons envoyer que des données 7 bits via la communication I2C. La communication I2C s'effectue via deux fils aux broches A4 et A5 des deux arduino.
Les valeurs sur l'écran LCD de l'esclave Arduino seront modifiées en faisant varier le POT du côté maître et vice versa.
Programmation I2C dans Arduino
Ce tutoriel comporte deux programmes, l'un pour le maître Arduino et l'autre pour l'esclave Arduino. Des programmes complets pour les deux côtés sont donnés à la fin de ce projet avec une vidéo de démonstration.
Explication de la programmation Master Arduino
1. Tout d'abord, nous devons inclure la bibliothèque Wire pour utiliser les fonctions de communication I2C et la bibliothèque LCD pour utiliser les fonctions LCD. Définissez également les broches LCD pour 16x2 LCD. En savoir plus sur l'interface LCD avec Arduino ici.
#comprendre
2. Dans void setup ()
- Nous commençons la communication série au débit en bauds de 9600.
Serial.begin (9600);
- Ensuite, nous commençons la communication I2C à la broche (A4, A5)
Wire.begin (); // Commence la communication I2C sur la broche (A4, A5)
- Ensuite, nous initialisons le module d'affichage LCD en mode 16X2 et affichons le message de bienvenue et effaçons après cinq secondes.
lcd.begin (16,2); // Initialise l'écran LCD lcd.setCursor (0,0); // Définit le curseur sur la première ligne de l'affichage lcd.print ("Circuit Digest"); // Imprime CIRCUIT DIGEST dans LCD lcd.setCursor (0,1); // Définit le curseur sur la deuxième ligne de l'affichage lcd.print ("I2C 2 ARDUINO"); // Imprime I2C ARDUINO dans le délai LCD (5000); // Délai de 5 secondes lcd.clear (); // Efface l'écran LCD
3. Dans une boucle vide ()
- Nous devons d'abord obtenir des données de l'esclave donc nous utilisons requestFrom () avec l'adresse esclave 8 et nous demandons un octet
Wire.requestFrom (8,1);
La valeur reçue est lue à l'aide de Wire.read ()
byte MasterReceive = Wire.read ();
- Ensuite, nous devons lire la valeur analogique du POT arduino maître attaché à la broche A0
int potvalue = analogRead (A0);
Nous convertissons cette valeur en termes d'un octet de 0 à 127.
byte MasterSend = map (valeur du pot, 0,1023,0,127);
- Ensuite, nous devons envoyer ces valeurs converties afin que nous commencions la transmission avec arduino esclave avec 8 adresses
Wire.beginTransmission (8); Wire.write (MasterSend); Wire.endTransmission ();
- Ensuite, nous affichons ces valeurs reçues de l'arduino esclave avec un retard de 500 microsecondes et nous recevons et affichons en permanence ces valeurs.
lcd.setCursor (0,0); // Définit Currsor sur la première ligne de LCD lcd.print (">> Master <<"); // Imprime >> Master << sur LCD lcd.setCursor (0,1); // Définit le curseur sur la deuxième ligne de l'écran LCD lcd.print ("SlaveVal:"); // Imprime SlaveVal: dans LCD lcd.print (MasterReceive); // Imprime MasterReceive dans l'écran LCD reçu de l'esclave Serial.println ("Master Received From Slave"); // Imprime dans Serial Monitor Serial.println (MasterReceive); retard (500); lcd.clear ();
Explication de la programmation Arduino esclave
1. Comme pour le maître, nous devons tout d'abord inclure la bibliothèque Wire pour utiliser les fonctions de communication I2C et la bibliothèque LCD pour utiliser les fonctions LCD. Définissez également les broches LCD pour 16x2 LCD.
#comprendre
2. Dans void setup ()
- Nous commençons la communication série au débit en bauds de 9600.
Serial.begin (9600);
- Ensuite, nous commençons la communication I2C à la broche (A4, A5) avec l'adresse esclave comme 8. Ici, il est important de spécifier l'adresse esclave.
Wire.begin (8);
Ensuite, nous devons appeler la fonction lorsque l'esclave reçoit la valeur du maître et lorsque le maître demande la valeur de l'esclave
Wire.onReceive (receiveEvent); Wire.onRequest (requestEvent);
- Ensuite, nous initialisons le module d'affichage LCD en mode 16X2 et affichons le message de bienvenue et effaçons après cinq secondes.
lcd.begin (16,2); // Initialise l'écran LCD lcd.setCursor (0,0); // Définit le curseur sur la première ligne de l'affichage lcd.print ("Circuit Digest"); // Imprime CIRCUIT DIGEST dans LCD lcd.setCursor (0,1); // Définit le curseur sur la deuxième ligne de l'affichage lcd.print ("I2C 2 ARDUINO"); // Imprime I2C ARDUINO dans le délai LCD (5000); // Délai de 5 secondes lcd.clear (); // Efface l'écran LCD
3. Ensuite, nous avons deux fonctions une pour l'événement de demande et une pour l'événement de réception
Pour demande événement
Lorsque le maître demande la valeur de l'esclave, cette fonction sera exécutée. Cette fonction prend la valeur d'entrée du POT esclave et la convertit en termes de 7 bits et envoie cette valeur au maître.
void requestEvent () { int potvalue = analogRead (A0); byte SlaveSend = map (valeur de pot, 0,1023,0,127); Wire.write (SlaveSend); }
Pour recevoir l'événement
Lorsque le maître envoie des données à l'esclave avec l'adresse d'esclave (8), cette fonction sera exécutée. Cette fonction lit la valeur reçue du maître et la stocke dans une variable de type octet .
void receiveEvent (int howMany { SlaveReceived = Wire.read (); }
4. Dans la boucle Void ():
Nous affichons la valeur reçue du maître en continu dans le module d'affichage LCD.
boucle vide (void) { lcd.setCursor (0,0); // Définit Currsor à la première ligne de LCD lcd.print (">> Slave <<"); // Imprime >> Esclave << sur LCD lcd.setCursor (0,1); // Définit le curseur sur la ligne deux de LCD lcd.print ("MasterVal:"); // Imprime MasterVal: dans LCD lcd.print (SlaveReceived); // Imprime la valeur SlaveReceived sur l'écran LCD reçue du Master Serial.println ("Slave Received From Master:"); // Imprime dans Serial Monitor Serial.println (SlaveReceived); retard (500); lcd.clear (); }
En tournant le potentiomètre d'un côté, vous pouvez voir les valeurs variables sur l'écran LCD d'un autre côté:
C'est ainsi que la communication I2C se déroule dans Arduino, ici nous avons utilisé deux Arduinos pour démontrer non seulement l'envoi de données, mais également la réception des données en utilisant la communication I2C. Vous pouvez donc maintenant interfacer n'importe quel capteur I2C avec Arduino.
Le codage complet pour Arduino maître et esclave est donné ci-dessous avec une vidéo de démonstration