Dans certains projets, il peut être intéressant d’établir une communication I2C entre Raspberry Pi et Arduino. La puissance de calcul et les fonctionnalités sans-fil du Raspberry Pi couplées à la capacité de l’Arduino en entrée sortie, résulte en un système de contrôle complet permettant de piloter n’importe quel projet. Si la carte Raspberry Pi et la carte Arduino sont à proximités, le bus I2C est un bon choix de protocole de communication. Ceci permet aussi de rajouter plusieurs appareils sur le même bus et de décupler les capacités du RaspberryPi.
Prérequis: Communication I2C avec Arduino, Accès à distance du Raspberry Pi avec VNC
Matériel
- Ordinateur
- Arduino UNO x1
- Raspberry Pi 3B+
- Jumper cables x3
Schéma de câblage
Pour établir la communication I2C entre Raspberry Pi et Arduino, il nous faut relier physiquement le bus qui utilise 3 broches. Une communication I2C est défini par un bus de deux fils (parfois appelé TWI, Two Wire Interface) et une adresse. Les broches utilisées par la communication I2C sont généralement fixé pour chaque appareil. L’une sur laquelle sont envoyées les données (SDA Serial Data Line) et sur l’autre l’horloge de synchronisation (SLC Serial Clock Line). Les masses des deux cartes doivent être reliées pour établir une référence commune de potentiel.
- SDA BCM2(RPI) <-> SDA A4(Arduino)
- SCL BCM3(RPI) <-> SCL A5(Arduino)
- GND (RPI) <-> GND(Arduino)
Configuration du Raspberry Pi
Pour utiliser l’interface I2C du Raspberry Pi, celle-ci doit être activée dans le menu de configuration. Pour cela entrez la commande suivante dans un terminal:
sudo raspi-config
Dans le menu, sélectionnez « 5 – Interfacing Options » puis « P5 I2C » et validez.
Un fois le branchement fait, vous pouvez vérifier les appareils branchés sur le bus en tapant dans le terminal la commande:
i2cdetect -y 1
Le Raspberry Pi retourne la liste des adresses détectées sur le bus
pi@raspberrypi:~ $ i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- 0b -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
Nous allons installer la librairie smbus2 qui permet de gérer la communication I2C côté Raspberry Pi
pip3 install smbus2
Code
Code Python Maître
Dans ce tutoriel, nous allons utiliser le langage Python côté Raspberry Pi. La librairie utilisée pour la gestion de la communication I2C est la librairie smbus2.
#!/usr/bin/env python # -*- coding: utf-8 -*- # Raspberry Pi to Arduino I2C Communication #i2cdetect -y 1 #library import sys import smbus2 as smbus#,smbus2 import time # Slave Addresses I2C_SLAVE_ADDRESS = 11 #0x0b ou 11 I2C_SLAVE2_ADDRESS = 12 I2C_SLAVE3_ADDRESS = 13 # This function converts a string to an array of bytes. def ConvertStringsToBytes(src): converted = [] for b in src: converted.append(ord(b)) return converted def main(args): # Create the I2C bus I2Cbus = smbus.SMBus(1) with smbus.SMBus(1) as I2Cbus: slaveSelect = input("Which Arduino (1-3): ") cmd = input("Enter command: ") if slaveSelect == "1": slaveAddress = I2C_SLAVE_ADDRESS elif slaveSelect == "2": slaveAddress = I2C_SLAVE2_ADDRESS elif slaveSelect == "3": slaveAddress = I2C_SLAVE3_ADDRESS else: # quit if you messed up print(slaveSelect== "1") print(type(slaveSelect)) print("no slave selected") quit() BytesToSend = ConvertStringsToBytes(cmd) print("Sent " + str(slaveAddress) + " the " + str(cmd) + " command.") print(BytesToSend ) I2Cbus.write_i2c_block_data(slaveAddress, 0x00, BytesToSend) time.sleep(0.5) while True: try: data=I2Cbus.read_i2c_block_data(slaveAddress,0x00,16) print("recieve from slave:") print(data) except: print("remote i/o error") time.sleep(0.5) return 0 if __name__ == '__main__': try: main(sys.argv) except KeyboardInterrupt: print("program was stopped manually") input()
Code Arduino Esclave
La librairie utilisée pour la gestion de la communication I2C côté Arduino est la librairie Wire.h.
#include <Wire.h> # define I2C_SLAVE_ADDRESS 11 // 12 pour l'esclave 2 et ainsi de suite #define PAYLOAD_SIZE 2 void setup() { Wire.begin(I2C_SLAVE_ADDRESS); Serial.begin(9600); Serial.println("-------------------------------------I am Slave1"); delay(1000); Wire.onRequest(requestEvents); Wire.onReceive(receiveEvents); } void loop(){} int n = 0; void requestEvents() { Serial.println(F("---> recieved request")); Serial.print(F("sending value : ")); Serial.println(n); Wire.write(n); } void receiveEvents(int numBytes) { Serial.println(F("---> recieved events")); n = Wire.read(); Serial.print(numBytes); Serial.println(F("bytes recieved")); Serial.print(F("recieved value : ")); Serial.println(n); }
Résultat
Le Raspberry Pi envoie la commande « slave » à l’Arduino, puis réceptionne un tableau de données provenant de l’Arduino.
L’Arduino réceptionne la commande « slave » puis envoie deux valeurs mises à jour dès qu’il reçoit une requête du Raspberry Pi
Application
- Reconnaissance visuel géré par le Raspberry Pi, actionneurs et capteurs gérés par l’Arduino
Sources
Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie