Como comunicar o Arduino com Raspberry Pi 24

Hoje vamos abordar uma dúvida muito frequente entre os leitores do blog: Como comunicar o Arduino com Raspberry Pi? Utilizando um Arduino Uno e um Raspberry Pi, vamos mostrar como esses dois dispositivos podem se comunicar via interface serial.

Circuito Arduino Uno e Raspberry Pi 2

No Arduino Uno a comunicação será feita por meio dos pinos 0 (RX) e (TX), e no Raspberry Pi pelos pinos 10 (RX) e 8 (TX) da GPIO. Nesse circuito precisamos ter o mesmo cuidado que temos quando ligamos sensores com nível de sinal de 3.3V ao Arduino, já que o Raspberry também trabalha com 3.3V.  Vamos montar um divisor de tensão bem simples, com dois resistores de 10K, mas você pode utilizar uma solução mais precisa e confiável, como o conversor de nível lógico 3,3-5V Bidirecional.

Pinos RX e TX Arduino e Raspberry

A princípio esse divisor será usando apenas no envio de sinais do Arduino (pino TX)  para o Raspberry (pino RX). A ligação no outro sentido (TX do Raspberry => RX do Arduino) não necessita de divisor de tensão, já que o Arduino consegue interpretar corretamente o sinal de 3.3V enviado pelo Raspberry.

Recomendamos que siga os passos deste tutorial e monte o circuito DEPOIS da configuração do Arduino e do Raspberry. Uma ligação incorreta ou a ausência do divisor de tensão pode danificar o seu Raspberry.

Preparação do Arduino Uno

No Arduino Uno, carregue o seguinte programa, que vai aguardar que um caracter (L) seja enviado à partir do Raspberry, e então envia uma mensagem de retorno com o status (Ligado ou Desligado) do led ligado à porta 13:

// Programa: Comunicacao Arduino com Raspberry Pi
// Autor: FILIPEFLOP

const int pino_led = 13;
char buf;
int estado = 1;

void setup()
{
  pinMode(pino_led, OUTPUT);
  Serial.begin(115200);
}

void loop()
{
  while (Serial.available() > 0)
  {
    buf = Serial.read();
    // Caso seja recebido o caracter L, acende o led
    if (buf == 'L')
    {
      // Liga ou desliga o led da porta 13
      digitalWrite(pino_led, estado);
      // Envia a resposta para o Raspberry
      Serial.print("Recebido! - Estado Led: ");
      if (estado == 1)
      {
        Serial.println("Ligado");
      }
      else
        Serial.println("Desligado");
    }
    // Inverte o estado do led
    estado = !estado;
  }
}

Preparação do Raspberry Pi

No Raspian, abra uma janela do LXTerminal e edite o arquivo /etc/inittab utilizando o editor de textos de sua preferência. No nosso caso, utilizamos o leafpad:

$sudo leafpad inittab

Em seguida, vamos desabilitar o getty (o programa que mostra a tela de login) na serial. Faça isso comentando (com o caracter #) a seguinte linha:

T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

O arquivo inittab ficará assim:

Alteração inittab

Salve o arquivo e reinicie o Raspberry.

Programa comunicação Arduino com Raspberry Pi

Após a inicialização, abra o Python 2 como administrador e digite o programa abaixo. A função dele é verificar se o botão ligado à porta 18 foi pressionado. Caso isso aconteça, o Raspberry envia o caractere L pela serial e aguarda a resposta do Arduino, indicando se o led da porta 13 foi acionado:

#Programa : Comunicacao Raspberry e Arduino
#Autor : FILIPEFLOP

import RPi.GPIO as GPIO
import time
import serial

#Configura a serial e a velocidade de transmissao
ser = serial.Serial("/dev/ttyAMA0", 115200)

GPIO.setmode(GPIO.BOARD)

#Define o pino do botao como entrada
GPIO.setup(18, GPIO.IN)

#Mensagem inicial
print ("Pressione o botao...")

while(1):
    #Verifica se o botao foi pressionado
    if GPIO.input(18) == True:
        #Envia o caracter L pela serial
        ser.write("L")
        print("Enviado - L")
        #Aguarda reposta
        resposta = ser.readline()
        #Mostra na tela a resposta enviada
        #pelo Arduino
        print resposta
        #Aguarda 0,5 segundos e reinicia o processo
        time.sleep(0.5)

Salve o programa que você digitou e monte o circuito abaixo, que utiliza  2 resistores de 10k para o divisor de tensão, e mais um resistor do mesmo valor para o pull-down do push-button.

Circuito Arduino Uno e Raspberry Pi 2

Com os dois ambientes configurados e o circuito montado, execute o programa que você salvou anteriormente utilizando a tecla F5 do Python shell. Uma nova janela será aberta, mostrando que os dados foram enviados para o Arduino, e que uma resposta foi  recebida pelo Raspberry:

Python shell

 Gostou? Deixe seu comentário logo abaixo. Em caso de dúvidas, caso queira trocar uma ideia, ou até mesmo dividir seu projeto, acesse nosso Fórum!

CTA_guia raspberry pi para iniciantes

Posts Relacionados

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

24 Comentários

  1. quando vai ter mais sorteios?

    ciro igor barros de lima
  2. Até que enfim, estava esperando por um post assim 😀

  3. Muito bacana o tutorial! Tenho uma dúvida, é possível fazer com que essa aplicação Python envie os dados recebidos para um BD rodando no próprio Raspberry? Pergunto isso porque estou fazendo um projeto caseiro onde queria poder consultar as mudanças de temperatura de tempos em tempos.

    1. Bom dia Ítalo,

      É possível sim, você pode usar por exemplo o mysql: http://raspberrywebserver.com/sql-databases/using-mysql-on-a-raspberry-pi.html

      Abraço!

      Adilson – Equipe FILIPEFLOP

      1. Muito obrigado!

  4. Excelente post.
    Uma pergunta. É possível realizar esta comunicação utilizando o NRF24L01?

    Carlos Bittencourt
    1. Boa tarde Carlos,

      É possível sim, inclusive neste post aqui tem o que você precisa: http://hack.lenotta.com/arduino-raspberry-pi-switching-light-with-nrf24l01/

      Abraço!

      Adilson – Equipe FILIPEFLOP

  5. Boa tarde, primeiramente quero parabenizar pelo site, pois tem me tirado varias duvidas em meus projetos. Agora vem a duvida: É possível adaptar algo desse tutorial para utilizar em um projeto que colhe informação de 3 sensores ligados a 3 pics respctivamente utilizando comunicação i2c?

    Desde já agradeço pela atenção.

    1. Bom dia Paulo,

      Não temos nenhum exemplo ainda utilizando PIC e comunicação I2C, mas você pode encontrar maiores informações sobre o assunto neste link: http://microcontrolandos.blogspot.com.br/2012/12/comunicacao-i2c.html

      Abraço!

      Adilson – Equipe FILIPEFLOP

  6. Ei galera, grande blog adoro o vosso trabalho.

    Será possivel eu não ter o arquivo inittab?
    Aí na minha pasta /etc/
    idmapd.conf
    init
    init.d
    initramfs-tools
    inputrc
    insserv
    insserv.conf
    insserv.conf.d
    iproute2
    issue

  7. Grande tuturial galera.

    Mas me ajuda aí, será possivel eu não ter essa pasta aí do inittab?

    pois não encontro ela no /etc/

    1. Boa tarde,

      Verifique se este link te ajuda, por favor: http://raspberrypi.stackexchange.com/questions/39165/how-can-i-stop-auto-login-console-and-getty-in-raspbian-jessie

      Abraço!

      Adilson – Equipe FILIPEFLOP

  8. Neste exemplo a função Bluetooth do raspberry também faz comunicação com o arduino?, por exemplo uma aplicação mobile que utilize o Bluetooth para acender um led, o raspberry passaria o comando para que o arduino possa ligar ou desligar o led, sem a necessidade de um modulo Bluetooth por parte do arduino?

    1. Boa tarde William,

      Não fiz esse teste ainda, mas acredito que seja possível sim. No caso você receberia os comandos no Raspberry via Bluetooth, e o Raspberry por sua vez enviaria os comandos para o Arduino via “cabo”.

      Abraço!

      Adilson – Equipe FILIPEFLOP

  9. Boa noite! Seguir seus passos… só que ao executar no idle do raspi deu syntaxerror…o que eu faço?
    melhor site informativo sobre raspberry em português!

    Parabéns

  10. Olá,

    Creio que exista um erro no circuito. Me parece que a conexão no protoboard do fio cinza está invertida com a conexão do fio amarelo.

    Abcs,
    Rodrigo Vertulo

    1. Está correto pois o Arduino manda 5V e o Raspberry Pi recebe em 3.3V, logo o RX do Raspberry deve estar no final do divisor de tensão.

  11. no raspberry ate quantos laços de arduino seria possível pelo I2C no caso (NANO).
    ou seria possível montar uma rede ProfBus dentro do raspiberry 3. e no caso qual seria a distancia máxima entre os laços

  12. Olá Adilson, é possível fazer comunicação entre um Raspberry pi3 e um LCD 3.2 Arduíno?

  13. Ao conectar o arduino com a placa raspberry ele também passará a ter o bluetooh e wifi?

  14. Boa noite.
    Ótimo post, mas me resta uma dúvida crucial nisso. Tudo que li a respeito de comunicação serial do arduino com o raspibarry envia apenas 1 informação. Isso é regra ou é possível enviar uma string completa como é possível fazer com o nrf24L01?
    Data.1=accx
    Data.2=accy
    Write(data)…
    Ainda nao possuio o raspibarry para testar mas saber isso é crussial antes de comprar ele

    1. Bom dia,

      Usamos apenas um caracter para facilitar o entendimento e a programação, na maioria das vezes, mas é possível enviar uma string completa, sem problemas.

      Abraço!

      Adilson – Equipe FILIPEFLOP

  15. Olá poderiam me tirar algumas dúvidas? Bom, tentei aqui mas não obtive sucesso, nas versões mais novas do raspbian o arquivo inittab foi incorporado no sysvinit, então para solucionar isso eu usei os seguintes comandos:
    sudo sysctl -p
    sudo systemctl disable serial-getty@ttyAMA0.service
    Além disso habilitei a comunicação serial nas configurações do raspberry. Bom, não sei se seria este o problema ou se isso que eu fiz resolveu. Fiz outro programa no Python sem o botão para simplificar essa comunicação:
    import RPi.GPIO as GPIO
    import time
    import serial
    ser = serial.Serial(“/dev/ttyAMA0”, 115200)
    GPIO.setmode(GPIO.BOARD)
    #Mensagem inicial
    print (“Iniciando programa…”)

    #Teste de comunicação
    print(‘Enviando dados para arduino…’)
    ser.write(“L”)
    print(“Dados enviados!”)
    print(“Aguardando resposta…”)
    resposta = ser.readline()
    print(“Resposta recebida: “)
    print resposta

    A questão é, ainda não consegui, pesquisando um pouco li que o divisor de tensão que nesse tutorial foram utilizados dois resistores de 10K deveriam obedecer uma proporção de 2 pra 1, no caso em de 10k e outro de 5k estaria certo isso?
    Outra pergunta, como eu faria para utilizar um conversor de nível lógico nesse projeto?

  16. Olá Adilson, tentei realizar esta atividade no meu raspberry pi v3, no entanto não encontrei o arquivo /etc/inittab. Com isso, quando tento enviar a letra “L”, o python dá um erro de tipo “TypeError: unicode strings are not supported, please encode to bytes: ‘L'”.

    Você poderia me ajudar com isso?

    Obrigado.