Site icon AranaCorp

Comunicação I2C entre Raspberry Pi e Arduino

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

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.

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.

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

Aplicação

Fontes

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

Exit mobile version