24 junho 2018

Comunicação Arduino e Raspberry Pi usando I2C

Que tal juntar o melhor dos dois mundos e fazer uma comunicação Arduino e Raspberry Pi? Neste post vamos mostrar como você pode fazer isso usando a interface I2C, presente nas duas placas.

Comunicação Arduino e Raspberry Pi usando I2C

Mas para que eu quero isso mesmo?

Quando utilizar a comunicação Arduino e Raspberry Pi


São vários os motivos pelos quais você pode querer (ou precisar) fazer esse tipo de comunicação entre Arduino e Raspberry Pi. Pode ser um projeto já montado no Arduino, com sensores, módulos e outros componentes, e você deseja apenas ver esses dados na tela do seu Raspberry.

Arduino e Raspberry Pi
Outro motivo seriam sensores e módulos que funcionam melhor com Arduino (ou já tem bibliotecas prontas, por exemplo), que seriam difíceis de ligar no Raspberry Pi. Nesse caso, é melhor colocar os componentes em um Arduino, e enviar os dados de saída desses componentes para o Raspberry Pi, que tem maior poder de processamento e capacidade de lidar com várias informações ao mesmo tempo.

Outra opção é você interligar essas duas placas para coletar os dados pelo Raspberry Pi e armazenar as informações em um banco de dados como o MySQL para uso posterior.


Conectando o Arduino e o Raspberry


Como mencionamos anteriormente, vamos conectar as duas placas utilizando a interface I2C. No Arduino Uno, que é a placa que vamos usar no exemplo, temos os pinos A4 (SDA) e A5 (SCL), que serão conectados em uma Raspberry Pi 3 nos pinos 3 (GPIO02 - SDA) e 5 (GPIO03 - SCL). 

Pinagem GPIO Raspberry Pi Interface I2C

A conexão das placas então fica assim:

Circuito conexão Arduino e Raspberry I2C

No barramento I2C foi usado um conversor de nível lógico I2C, pois o nível de sinal dos pinos do Arduino é de 5V, e no Raspberry é de 3.3V. Esse conversor, como o próprio nome diz, vai converter o sinal que vem do Arduino (nível 5V) para enviar ao Raspberry (nível 3.3V). Os pinos mais à esquerda do conversor, na imagem acima, são bidirecionais, e nele conectamos a interface I2C (SDA e SCL).

Por fim, no pino analógico A0 do Arduino conectamos um potenciômetro, cujos dados serão enviados ao Raspberry quando requisitado.

Habilitando a interface I2C no Raspberry Pi


Como de praxe, antes de qualquer coisa vamos usar os comandos abaixo para atualizar o sistema operacional do Raspberry Pi. Abra uma janela de terminal e digite:

sudo apt-get update
sudo apt-get upgrade

Finalizada a atualização, digite o comando sudo raspi-config para entrar na janela de configuração do sistema. Selecione a opção 5 - Interfacing Options:

Raspi-config Interfacing Options

Em seguida, selecione a opção P5 - I2C, e pressione ENTER para habilitar a interface I2C no Raspberry Pi:

Raspi-config I2C Enable

Por último, vamos instalar o I2C-Tools e o smbus, que vão possibilitar o uso do barramento I2C com Python e uso de ferramentas de configuração. Utilize os comandos abaixo:

sudo apt-get install i2c-tools
sudo apt-get install python-smbus

Reinicie o sistema operacional e vamos para o próximo passo, que é a configuração do Arduino no modo escravo do barramento I2C.

Configurando o Arduino no modo I2C escravo


Carregue o programa abaixo no Arduino, que vai fazer com que ele seja o "escravo" (slave) no barramento I2C, ou seja, ele vai aguardar que o Raspberry Pi peça as informações pela interface e as envie apenas quando solicitado. Na linha 12 configuramos o endereço I2C (nesse caso, 0x18) que será utilizado pelo Arduino para se comunicar no barramento.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//Programa: Comunicacao I2C Arduino e Raspberry Pi
//Autor: Arduino e Cia

#include <Wire.h>

char str[15];
int valor;

void setup()
{
  Serial.begin(9600);
  Wire.begin(0x18);
  Wire.onRequest(requestEvent);
}

void requestEvent()
{
  valor = analogRead(A0);
  Serial.println("Requisicao recebida!");
  sprintf(str, "Valor: %4d\n", valor);
  Wire.write(str);
}

void loop()
{
  delay(50);
}

O programa utiliza a biblioteca Wire para realizar a comunicação, e aguarda uma requisição no barramento para enviar os dados. Quando essa requisição chegar, será executada a rotina requestEvent(), que vai ler o valor da porta analógica A0 onde está ligado o potenciômetro, e vai enviar esses dados para o Raspberry (linha 21).

Você pode acompanhar no serial monitor da IDE do Arduino a mensagem de "Requisição recebida!" (linha 19) assim que a requisição de dados for enviada pelo Raspberry.

Testando a comunicação I2C


Com o circuito montado e o Arduino configurado, utilize o comando abaixo na janela de terminal do Raspberry para verificar se o endereço I2C configurado no Arduino (0x18) aparece na lista de dispositivos I2C:

i2cdetect -y 1

Se tudo estiver ok, você terá uma tela como esta, indicando que o Arduino está ativo no barramento:

I2Cdetect Raspberry Pi

Se o endereço não estiver aparecendo como na tela acima, faça uma checagem nas suas conexões e certifique-se de que a interface I2C foi habilitada corretamente no raspi-config.

Obtendo Dados do Arduino


A última parte é a requisição de dados do Arduino pelo Raspberry Pi. Essa parte será feita por um pequeno programa em Python, que vai realizar uma requisição a cada 5 segundos e mostrar as informações da porta A0 conforme giramos o potenciômetro.

Crie no Raspberry um programa chamado comunicai2c.py. Para fazer isso recomendo usar o editor nano com o comando:

sudo nano comunicai2c.py

Dentro do editor, digite ou copie o programa abaixo, que utiliza a biblioteca smbus que instalamos anteriormente.

Na linha 9, configuramos o endereço I2C do Arduino que estamos usando no barramento (0x18). A cada 5 segundos, a rotina RequisitaDadosArduino é executada, enviando uma requisição para o Arduino e mostrando na tela (linha 19) os dados recebidos:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#Programa: Python Raspberry Pi Comunicacao I2C
#Autor: Arduino e Cia

#!/usr/bin/python

import time
import smbus

slaveAddress = 0x18    

i2c = smbus.SMBus(1)

def RequisitaDadosArduino():
    global msg_recebida
    dados_recebidos_Arduino = i2c.read_i2c_block_data(slaveAddress, 0,11)
    for i in range(len(dados_recebidos_Arduino)):
        msg_recebida += chr(dados_recebidos_Arduino[i])

    print(msg_recebida)
    dados_recebidos_Arduino =""
    msg_recebida = ""

msg_recebida = ""

while 1:
    RequisitaDadosArduino() 
    time.sleep(5)

Salve o programa no editor, e execute-o com o comando

sudo python3 comunicai2c.py

Pronto. Se tudo estiver ok, você verá a tela abaixo com as informações do potenciômetro sendo enviadas a cada 5 segundos:

Dados enviados pelo Arduino para o Raspberry Pi

Neste post vimos que com programas relativamente simples e alguns passos de configuração, conseguimos realizar a comunicação entre Arduino e Raspberry Pi. Você pode adaptar facilmente este programa para enviar dados de sensores e módulos, de acordo com o seu projeto.


2 comentários:

  1. E para enviar 5 valores ao mesmo tempo, é possível?

    ResponderExcluir
    Respostas
    1. Bom dia,

      É possível sim, até bem mais do que 5. :)

      Abraço!

      Adilson

      Excluir