fbpixel
Étiquettes : , ,
5
(1)

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

How useful was this post?

Click on a star to rate it!

Average rating 5 / 5. Vote count: 1

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?