Le protocole populaire I2C permet à deux ou plusieurs cartes Arduino de communiquer. Découvrez comment les connecter et les coder.

Alors qu'un seul Arduino peut accomplir de nombreuses tâches, certains projets peuvent nécessiter l'utilisation de plusieurs cartes pour gérer différentes fonctionnalités. Ainsi, pour permettre le transfert de données entre les deux microcontrôleurs, un protocole de communication tel que CAN, SPI, I2C ou UART doit être mis en place.

Dans ce guide, nous couvrirons les bases du fonctionnement d'I2C, les connexions matérielles et l'implémentation logicielle nécessaires pour configurer deux cartes Arduino en tant que périphériques maître et esclave I2C.

Qu'est-ce qu'I2C?

Le circuit inter-intégré (I2C) est un protocole de communication largement utilisé dans les systèmes embarqués et les microcontrôleurs pour permettre le transfert de données entre les appareils électroniques. Contrairement à SPI (Serial Peripheral Interface), I2C vous permet de connecter plusieurs appareils maîtres à un bus avec un ou plusieurs appareils esclaves. Il a été utilisé pour la première fois par Philips et est également connu sous le nom de protocole de communication Two Wire Interface (TWI).

instagram viewer

Comment fonctionne la communication I2C?

I2C utilise deux lignes bidirectionnelles: données série (SDA) et horloge série (SCL) pour transférer des données et synchroniser la communication entre les appareils. Chaque appareil connecté au bus I2C possède une adresse unique qui l'identifie lors de la communication. Le protocole I2C permet à plusieurs appareils de partager le même bus, et chaque appareil peut agir en tant que maître ou esclave.

La communication est initiée par l'appareil maître et un adressage incorrect des appareils esclaves peut entraîner des erreurs de transfert. Consultez notre guide détaillé sur comment fonctionnent les communications série UART, SPI et I2C pour vous donner un peu de contexte.

Un avantage majeur de la communication I2C à noter est la flexibilité qu'elle offre en matière de gestion de l'alimentation. Les appareils qui fonctionnent à différents niveaux de tension peuvent toujours communiquer efficacement à l'aide de convertisseurs de tension. Cela signifie que les appareils fonctionnant à 3,3 V ont besoin de décaleurs de tension pour se connecter à un bus I2C 5 V.

La bibliothèque de fils

La bibliothèque Wire est une bibliothèque Arduino intégrée qui fournit des fonctions pour communiquer via I2C. Il utilise deux broches - SDA et SCL - sur la carte Arduino pour la communication I2C.

Broches I2C sur l'Arduino Uno :

Broches Arduino Nano I2C :

Pour utiliser la bibliothèque, vous devez inclure le Fil.h fichier d'en-tête au début de votre croquis Arduino.

#inclure

La bibliothèque Wire fournit des fonctions pour initier une communication avec un périphérique I2C, envoyer des données et recevoir des données. Certaines fonctions importantes que vous devez connaître incluent :

  • Wire.begin(): utilisé pour rejoindre le bus I2C et initier la communication.
  • Wire.beginTransmission(): utilisé pour spécifier l'adresse de l'esclave et commencer une transmission.
  • Wire.write(): utilisé pour envoyer des données au périphérique I2C.
  • Fil.endTransmission(): utilisé pour terminer la transmission et vérifier les erreurs.
  • Wire.requestFrom(): utilisé pour demander des données au périphérique I2C.
  • Fil.disponible(): utilisé pour vérifier si les données sont disponibles pour être lues à partir du périphérique I2C.
  • Wire.read(): utilisé pour lire les données du périphérique I2C.

Utilisez le Wire.beginTransmission() fonction pour définir l'adresse du capteur, qui est insérée comme argument. Par exemple, si l'adresse du capteur est 0x68, vous utiliseriez :

Fil.commencer la transmission(0x68);

Configuration matérielle Arduino I2C

Pour connecter deux cartes Arduino en I2C, vous aurez besoin des composants matériels suivants :

  • Deux cartes Arduino (maître et esclave)
  • Planche à pain
  • Fils de liaison
  • Deux résistances pull-up de 4,7 kΩ

Connectez le SDA et SCL broches des deux cartes Arduino à une planche à pain. Connectez les résistances pull-up entre les SDA et SCL épingles et les 5V rail d'alimentation sur la planche à pain. Enfin, connectez les deux planches à pain ensemble à l'aide de fils de liaison.

Circuit Arduino Uno

Nano-circuit Arduino

Crédit d'image : Documentation Arduino I2C

Configuration des cartes Arduino en tant que périphériques maître et esclave I2C

Utilisez le Wire.requestFrom() fonction pour spécifier l'adresse de l'appareil esclave avec lequel nous voulons communiquer. Utilisez ensuite le Wire.read() fonction pour obtenir des données de l'appareil esclave.

Code appareil maître :

#inclure
annulerinstallation(){
Fil.commencer(); // rejoindre le bus i2c
En série.commencer(9600); // démarre la série pour la sortie
}
annulerrecevoir des données(){
entier adresse = 8;
entier octetsÀLire = 6;
Fil.demande de(adresse, bytesToRead);
alors que (Fil.disponible()) {
carboniser données = Fil.lire();
En série.imprimer(données);
}
retard(500);
}
annulerboucle(){
recevoir des données();
}

Le Wire.onReceive() La fonction est utilisée pour spécifier ce qu'il faut faire lorsque l'esclave reçoit des données de l'appareil maître. Dans le code ci-dessus, le Fil.disponible() la fonction vérifie si les données sont disponibles, et la Wire.read() La fonction lit les données envoyées par l'appareil maître.

Code appareil esclave :

#inclure
annulerinstallation(){
Fil.commencer(8); // rejoindre le bus I2C avec l'adresse 8
Fil.à la réception(recevoirEvénement); // appelez receiveEvent lorsque les données sont reçues
}
annulerboucle(){
retard(100);
}
annulerrecevoirEvénement(entier octets){
Fil.écrire("Bonjour "); // répond avec un message de 6 octets comme prévu par le maître
}

Envoi et réception de données à l'aide d'I2C

Dans cet exemple, lisons la température d'un capteur de température DHT11 interfacé avec l'Arduino esclave et imprimons-la sur le moniteur série de l'Arduino maître.

Modifions le code que nous avons écrit précédemment pour inclure la mesure de température que nous enverrons ensuite à la carte maître via le bus I2C. La carte maître peut alors lire la valeur que nous avons envoyée, puis l'afficher sur le moniteur série.

Code appareil maître :

#inclure
annulerinstallation(){
Fil.commencer();
En série.commencer(9600);
En série.println("Maître initialisé !");
}
annulerboucle(){
Fil.demande de(8, 1); // Demander les données de température à l'esclave
si (Fil.disponible()) {
octet température = Fil.lire(); // Lire les données de température de l'esclave
En série.imprimer("Température: ");
En série.imprimer(température);
En série.println("°C");
}
retard(2000); // Attendre 2 secondes avant de redemander la température
}

Code appareil esclave :

#inclure
#inclure

#définir DHTPIN 4 // Broche connectée au capteur DHT
#définir DHTTYPE DHT11 // Type de capteur DHT
DHT dht(DHTPIN, DHTTYPE);
octet température;

annulerinstallation(){
Fil.commencer(8); // L'adresse de l'esclave est 8
Fil.sur demande(demandeEvénement);
dht.commencer();
}

annulerboucle(){
retard(2000); // Attendez 2 secondes que la DHT se stabilise
température = dht.lireTempérature(); // Lire la température du capteur DHT
}

annulerdemandeEvénement(){
Fil.écrire(température); // Envoi des données de température au maître
}

Vous pouvez personnaliser ce code en fonction des capteurs que vous pouvez avoir dans votre projet, ou même afficher les valeurs des capteurs sur un module d'affichage pour fabriquez votre propre thermomètre d'ambiance et humidimètre.

Adressage esclave avec I2C sur Arduino

Pour lire les valeurs des composants ajoutés à un bus I2C dans un tel projet, il est important d'inclure l'adresse d'esclave correcte lors du codage. Heureusement, Arduino propose une bibliothèque de scanners qui simplifie le processus d'identification des esclaves adresses, éliminant le besoin de passer au crible de longues fiches techniques de capteurs et la confusion en ligne Documentation.

Utilisez le code suivant pour identifier l'adresse de tout appareil esclave présent sur le bus I2C.

#inclure // Inclure la bibliothèque Wire pour la communication I2C

annulerinstallation(){
Fil.commencer(); // Initialiser la communication I2C
En série.commencer(9600); // Initialise la communication série avec un débit en bauds de 9600
alors que (!En série); // Attendre que la connexion série s'établisse
En série.println("\nScanner I2C"); // Affiche un message indiquant le début du scan I2C
}

annulerboucle(){
octet erreur, adresse; // Déclarer des variables pour stocker les erreurs et les adresses des appareils
entier nAppareils; // Déclare une variable pour stocker le nombre d'appareils trouvés

En série.println("Balayage..."); // Affiche un message indiquant le début du scan I2C

nAppareils = 0; // Définit le nombre d'appareils trouvés à 0
pour (adresse = 1; adresse < 127; adresse++) { // Itérer sur toutes les adresses I2C possibles
Fil.commencer la transmission(adresse); // Lancer une transmission vers l'adresse courante
erreur = Fil.finTransmission(); // Termine la transmission et stocke les éventuelles erreurs

si (erreur == 0) { // Si aucune erreur n'a été trouvée
En série.imprimer("Périphérique I2C trouvé à l'adresse 0x"); // Affiche un message indiquant qu'un périphérique a été trouvé
si (adresse < 16) En série.imprimer("0"); // Si l'adresse est inférieure à 16, ajouter un 0 devant à des fins de formatage
En série.imprimer(adresse, HEX); // Affiche l'adresse au format hexadécimal
En série.println(" !"); // Affiche un message indiquant qu'un périphérique a été trouvé

nDevices++; // Incrémente le nombre d'appareils trouvés
}
autresi (erreur == 4) { // Si une erreur a été trouvée
En série.imprimer("Erreur inconnue à l'adresse 0x"); // Affiche un message indiquant qu'une erreur a été trouvée
si (adresse < 16) En série.imprimer("0"); // Si l'adresse est inférieure à 16, ajouter un 0 devant à des fins de formatage
En série.println(adresse, HEX); // Affiche l'adresse au format hexadécimal
}
}
si (nAppareils == 0) { // Si aucun appareil n'a été trouvé
En série.println("Aucun périphérique I2C trouvé\n"); // Affiche un message indiquant qu'aucun périphérique n'a été trouvé
}
autre { // Si des appareils ont été trouvés
En série.println("fait\n"); // Affiche un message indiquant la fin du scan I2C
}
retard(5000); // Attendre 5 secondes avant de lancer la prochaine analyse
}

Développez votre projet aujourd'hui

L'interfaçage de deux cartes Arduino à l'aide du protocole de communication I2C offre un moyen flexible et efficace de réaliser des tâches complexes qui ne peuvent pas être gérées par une seule carte. Avec l'aide de la bibliothèque Wire, la communication entre les deux cartes utilisant I2C est facilitée, vous permettant d'ajouter plus de composants à votre projet.