Etiquetas: , ,

Em alguns projetos, pode ser interessante estabelecer uma comunicação I2C entre Raspberry Pi e Arduino. A potência de computação e as capacidades sem fios do Raspberry Pi, aliadas à capacidade de entrada e saída do Arduino, resultam num sistema de controle completo que permite pilotar qualquer projeto. Se a placa Raspberry Pi e a placa Arduino estiverem próximas, o barramento I2C é uma boa escolha como protocolo de comunicação. Isso também permite adicionar vários dispositivos no mesmo barramento e aumentar em dez vezes as capacidades do RaspberryPi.

Pré-requisitos: comunicação I2C com Arduino, Acesso remoto do Raspberry Pi com VNC

Material

  • Computador
  • Arduino UNO
  • Raspberry Pi 3B+
  • 3 Cabos jumper

Esquema de ligação

Para estabelecer a comunicação I2C entre Raspberry Pi e Arduino, é preciso ligar fisicamente o barramento que utiliza 3 pinos. A comunicação I2C se define por um barramento de dois fios (também chamado de TWI, Two Wire Interface) e um endereço. Os pinos utilizados para a comunicação I2C são normalmente fixados para cada dispositivo. Os dados (SDA Serial Data Line) são enviados para um pino e o relógio de sincronização (SLC Serial Clock Line), para o outro. As terras de ambas as placas devem estar conectadas para estabelecer uma referência comum de potencial.

  • SDA BCM2(RPI) <-> SDA A4(Arduino)
  • SCL BCM3(RPI) <-> SCL A5(Arduino)
  • GND (RPI) <-> GND(Arduino)
raspberry-pi-arduino-i2c-communication_bb Comunicação I2C entre Raspberry Pi e Arduino

Configuração do Raspberry Pi

Para utilizar a interface I2C do Raspberry Pi, deve-se ativá-la no menu de configuração. Para isso, introduza o seguinte comando num terminal:

sudo raspi-config

No menu, selecione “5 – Opções de Interface” e em seguida “P5 I2C”, então valide.

Uma vez efetuada a ligação, é possível verificar os dispositivos conectados ao barramento digitando o seguinte comando no terminal:

i2cdetect -y 1

O Raspberry Pi devolve a lista de endereços detectados no barramento.

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: -- -- -- -- -- -- -- --  

Vamos instalar a biblioteca smbus2, que permite gerenciar a comunicação I2C pelo lado do Raspberry Pi

pip3 install smbus2

Código

Código “Master” Python

Neste tutorial, vamos adotar a linguagem Python para o Raspberry Pi. A biblioteca utilizada para gerenciar a comunicação I2C é a 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()

Código “Slave” Arduino

A biblioteca utilizada para gerir a comunicação I2C no lado Arduino é a 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);
}

Resultado

O Raspberry Pi envia o comando “slave” ao Arduino e recebe um quadro de dados proveniente do Arduino.

raspberry-pi-arduino-i2c-communication-terminal Comunicação I2C entre Raspberry Pi e Arduino

O Arduino recebe o comando “slave” e envia dois valores atualizados assim que recebe um comando do Raspberry Pi

raspberry-pi-arduino-i2c-communication-serial-monitor Comunicação I2C entre Raspberry Pi e Arduino

Aplicação

  • Reconhecimento visual com Raspberry Pi; controle de servomotores e sensores com Arduino

Fontes

Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie