7 - Pour aller plus loin
Raspberry Pi (maître) Arduino (esclave) Communication I2C avec WiringPi
Il faut pour utiliser le protocole I²C :
- Un Raspberry Pi 3, 3B, 3B+ qui sera configuré en maître,
- Un Arduino en esclave.
Vous verrez comment configurer la communication, lire une écriture, grâce à la bibliothèque WiringPi. Je vais également vous montrer les différences entre l'utilisation de WiringPi pour un capteur typique et une carte Arduino.
Assurez-vous de lire cette introduction à WiringPi avant si vous ne connaissez pas bien la bibliothèque.
Table des matières
- Installer
- Programme esclave Arduino I2C de base
- Programme maître Raspberry Pi I2C avec WiringPi
- Assurez-vous que le Raspberry Pi détecte la carte Arduino sur le bus I2C
- Code Raspberry Pi avec WiringPi I2C
- WiringPi Code expliqué
- Installer
- Initier la communication I2C
- Envoyer des données à Arduino via I2C
- Recevoir des données d'Arduino via I2C
- Compile et éxecute le programe
Installer
Schémas du matériel

- Reliez le GND du Raspberry Pi au GND de l'Arduino.
- Connectez le SDA (données I2C) du Pi (broche 2) à l'Arduino SDA.
- Connectez le SCL (horloge I2C) du Pi (broche 3) à l'Arduino SCL.
Note importante : le Raspberry Pi 4 (et antérieur) fonctionne sous 3,3V, et l'Arduino Uno fonctionne sous 5V !

Vous apprenez à utiliser le combo Raspberry Pi + Arduino pour construire vos propres projets ?

Vous devez vraiment faire attention lorsque vous connectez 2 broches entre ces cartes . Habituellement, vous devez utiliser un convertisseur de niveau entre 3,3 V et 5 V. Mais dans ce cas précis, nous pouvons éviter d'en utiliser un.
Si le Raspberry Pi est configuré en maître et l'Arduino en esclave sur le bus I2C, vous pouvez alors connecter directement les broches SDA et SCL. Pour faire simple, dans ce scénario le Raspberry Pi imposera 3,3V, ce qui n'est pas un problème pour les broches Arduino.
Pour en savoir plus sur les en-têtes gpio : Guide de brochage Raspberry Pi | Guide de brochage Arduino Uno .
Configuration du logiciel
Si vous n'avez pas encore utilisé I2C sur votre Raspberry Pi, cela signifie probablement que la communication I2C n'est pas activée. Pour l'activer, recherchez le fichier "/boot/config.txt".
Ouvrez ce fichier (avec sudo), trouvez la ligne
#dtparam=i2c_arm=on
, et supprimez le « # » de début pour le décommenter.
Après cela, redémarrez votre Pi et I2C sera activé tant que vous ne commentez pas à nouveau la ligne I2C dans le fichier de configuration.
Programme esclave Arduino I2C de base
Écrivons le programme le plus basique pour utiliser Arduino comme esclave I2C.
#include <Fil.h>
#define SLAVE_ADDRESS 0x08
octet data_to_echo = 0 ;
configuration vide ()
{
Fil. commencer ( SLAVE_ADDRESS ) ;
Fil. onReceive ( recevoirDonnées ) ;
Fil. onRequest ( sendData ) ;
}
boucle vide () { }
void receiveData ( int bytecount )
{
for ( int i = 0; i < nombre d'octets; i++ ) {
data_to_echo = Fil. lire () ;
}
}
void sendData ()
{
Fil. écrire ( data_to_echo ) ;
}
Téléchargez ce code sur votre carte Arduino. L'Arduino est maintenant configuré en tant qu'esclave I2C et son ID de périphérique est 8.
Lors de la réception d'un octet via I2C, l'Arduino conservera les données dans une variable globale et les renverra lorsqu'il lui sera demandé d'envoyer un octet.
Programme maître Raspberry Pi I2C avec WiringPi
Assurez-vous que le Raspberry Pi détecte la carte Arduino sur le bus I2C
Après avoir configuré le matériel, le logiciel et téléchargé le code Arduino, il est temps de se concentrer sur la partie Raspberry Pi et d'écrire le programme WiringPi !
Mais avant cela, vérifions simplement que le Raspberry Pi peut détecter la carte Arduino sur le bus I2C.
$ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 abcdef
00 : -- -- -- -- -- 08 -- -- -- -- -- -- --
10 : -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20 : -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30 : -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40 : -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50 : -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60 : -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70 : -- -- -- -- -- -- -- --
Bon, écrivons maintenant le code !
Code Raspberry Pi avec WiringPi I2C
#include <iostream>
#include <câblagePiI2C.h>
#define DEVICE_ID 0x08
int main ( int argc, char **argv )
{
// Configurer la communication I2C
int fd = câblagePiI2CSetup ( DEVICE_ID ) ;
si ( fd == -1 ) {
std::cout << "Impossible d'initialiser la communication I2C.\n" ;
retour -1 ;
}
std::cout << "Configuration réussie de la communication I2C.\n" ;
// Envoi des données à l'arduino
uint8_t data_to_send = 17 ;
câblagePiI2CWrite ( fd, data_to_send ) ;
std::cout << "Données envoyées : " << ( int ) data_to_send << "\n" ;
// Lire les données de l'arduino
int receive_data = câblagePiI2CRead ( fd ) ;
std::cout << « Données reçues : « < données_réceptionnées << "\n" ;
if ( receive_data == data_to_send ) {
std::cout << "Succès !\n" ;
}
renvoie 0 ;
}
WiringPi Code expliqué
Décomposons le code ligne par ligne.
Installer
#include <iostream>
#include <câblagePiI2C.h>
Nous incluons ici l'en-tête WiringPiI2C, qui fait partie de la bibliothèque WiringPi. Vous pouvez trouver le fichier d'en-tête complet sur GitHub .
#define DEVICE_ID 0x08
Sur Arduino, nous avons choisi de définir l'ID sur 8. Donc ici, sur Raspberry Pi, nous devons utiliser le même ID pour trouver le périphérique Arduino sur le bus I2C.
Notez que c'est assez différent lorsque vous utilisez I2C pour lire les données d'un capteur. Lorsque vous utilisez un capteur, l'ID est généralement déjà défini et vous devez le trouver dans la fiche technique. Ici, vous pouvez choisir l'ID que vous voulez.
Initier la communication I2C
int main ( int argc, char **argv )
{
// Configurer la communication I2C
int fd = câblagePiI2CSetup ( DEVICE_ID ) ;
si ( fd == -1 ) {
std::cout << "Impossible d'initialiser la communication I2C.\n" ;
retour -1 ;
}
std::cout << "Configuration réussie de la communication I2C.\n" ;
Avec le câblagePiI2CSetup(), votre Raspberry Pi essaiera de détecter et de se connecter à votre carte Arduino. Le paramètre que vous devez donner à la fonction est l'ID de périphérique de l'esclave I2C sur le bus.
Une fois la communication établie avec succès, nous pouvons commencer à envoyer et à recevoir des données.
Envoyer des données à Arduino via I2C
// Envoi des données à l'arduino
uint8_t data_to_send = 17 ;
câblagePiI2CWrite ( fd, data_to_send ) ;
std::cout << "Données envoyées : " << ( int ) data_to_send << "\n" ;
Pour envoyer un octet à Arduino, nous utilisons la fonction wirePiI2CWrite(). Notez que le type de données que j'ai choisi ici est uint8_t, qui correspond à un nombre non signé de 8 bits (0-255).
Il y a ici une différence par rapport au moment où vous écrivez des données sur un capteur typique. Habituellement, avec un capteur, vous devez vérifier le tableau des registres dans la fiche technique de l'appareil. Ensuite, lors de l'écriture d'un octet via I2C, vous devez indiquer l'ID de l'appareil, l'adresse du registre et les données. Dans ce cas, vous utiliserez les fonctions wirePiI2CWriteReg8 () et wirePiI2CWriteReg16() WiringPi.
Ici, avec wirePiI2CWrite(), vous n'avez pas besoin de donner d'adresse de registre. Vous venez de mettre l'ID de l'appareil et les données à envoyer. Cela ira directement dans la fonction de rappel que vous avez définie sur Arduino à l'aide de Wire.onReceive().
Recevoir des données d'Arduino via I2C
// Lire les données de l'arduino
int receive_data = câblagePiI2CRead ( fd ) ;
std::cout << « Données reçues : « < données_réceptionnées << "\n" ;
Pour recevoir un octet d'Arduino, nous utilisons la fonction wirePiI2CRead().
Ceci est également différent lorsque vous utilisez un capteur, pour lequel les données sont définies dans différents registres, avec des adresses différentes. Avec un capteur typique, vous auriez utilisé le câblagePiI2CReadReg8 () et le câblagePiI2CReadReg16 (), où vous devez donner l'ID de l'appareil et l'adresse du registre.
Ici, avec le câblagePiI2CRead(), tout ce que vous devez donner en paramètre est l'ID de périphérique de l'esclave Arduino. L'Arduino déclenchera le rappel de la fonction que vous avez définie avec Wire.onRequest().
if ( receive_data == data_to_send ) {
std::cout << "Succès !\n" ;
}
renvoie 0 ;
}
Enfin, nous comparons les données envoyées et reçues pour voir si elles sont identiques. En cas de succès, nous imprimons un message sur le terminal.
Compile et éxecute le programe
N'oubliez pas de vous connecter à la bibliothèque wireingPi en utilisant -lwiringPi.
$ g++ -o rpi_arduino_wiringpi_i2c rpi_arduino_wiringpi_i2c. cpp -lwiringPi
$ ./rpi_arduino_wiringpi_i2c
Communication I2C configurée avec succès.
Données envoyées : 17
Données reçues : 17
Succès!
Ça marche!
Avec seulement 3 fonctions WiringPi, vous avez configuré la communication I2C, envoyé un octet et reçu un octet.
Pour aller plus loin, vous pouvez ajouter d'autres cartes Arduino au bus I2C (en utilisant un identifiant de périphérique différent pour chacune), également configurées comme esclaves. Votre carte Raspberry Pi, en tant que maître sur le bus, devrait configurer la communication pour chaque appareil. Après, tout est pareil : il vous suffit de modifier le paramètre Device ID dans les fonctions WiringPi, selon l'appareil esclave auquel vous vous adressez.
Créé avec HelpNDoc Personal Edition: Transformez votre processus de création de fichier d'aide CHM avec HelpNDoc