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.
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.
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.
Atualizado em 27-07-2020: veja também como realizar uma conexão wireless entre essas duas placas no post Comunicação Arduino e Raspberry Pi com LoRa.
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).
A conexão das placas então fica assim:
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:
Em seguida, selecione a opção P5 – I2C, e pressione ENTER para habilitar a interface I2C no Raspberry Pi:
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.
//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: %4dn", 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:
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.
Testando a comunicação entre Arduino e Raspberry Pi
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:
#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:
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.
E para enviar 5 valores ao mesmo tempo, é possível?
Bom dia,
É possível sim, até bem mais do que 5. 🙂
Abraço!
Adilson
Como isso poderia ser implementado?
Eu gostaria de passar 3 valores, um inteiro e 2 floats para a rasp
O que a linha 15 no code em python faz?
Bom dia,
Lê os dados do dispositivo I2C. Sintaxe:
read_i2c_block_data(i2c_addr, register, length, force=None)
Abraço!
Adilson
Bom dia Arduino &Cia.
Gostaria de escrever um artigo sobre esse formato de utilização, ou seja Arduino (em meu caso possivelmente o ATTiny85) como módulos de captura de dados para o Raspberry Pi via I2C.
Como tenho de creditar todos os artigos que possa utilizar, vcs poderiam por gentileza me informar o autor deste artigo para o correto credito?
Obrigado.
Marcelo Euler
Oi Marcelo!
Tudo bem? O autor é Adilson Thomsen. Se precisar de informações adicionais, por favor utilize o formulário de contato no lado direito da página.
Abraços e obrigado!
Adilson
Bom dia,
O meu código esta retornando apenas o caractere Y onde deveria ler o potenciômetro
alguém pode me ajudar
[…] que você também confira o post Comunicação Arduino e Raspberry Pi usando I2C, onde mostro uma outra possibilidade de comunicação entre essas duas famosas […]
bom dia! é possivel comunicar via i2c 1 rasp com 4 arduinos? cada arduino com um endereço…
Oi Enio,
Sim, a comunicação I2C permite esse tipo de configuração.
Abraço!
Adilson