Como comunicar o Arduino com Raspberry Pi 46

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á usado 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 a sua placa.

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 liga ou desliga o led conectado na porta 13 enviando de volta para a Raspberry uma mensagem de status (Ligado ou Desligado):

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

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

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

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.

Faça seu comentário

Acesse sua conta e participe

46 Comentários

  1. Excelente! Muito legal! Parabéns pelos post’s!👏👏👏👏

  2. Boa tarde, preciso fazer um Raspberry Pi se comunicar via porta serial com um roteador cisco para poder fazer acesso remoto e configurar ele, sera que com esse esquema ele rodaria ?

    1. Olá Wagner,

      Acredito que sim, porém é necessário saber os comandos e o nível de tensão da serial do Roteador.

      Se for maior que 5V, pode ser preciso um conversor de nível lógico e não simplesmente um divisor de tensão.

      Abraços!
      Vinícius – Equipe MakerHero

  3. Olá, agradeço o tutorial, muito bom 🙂

    Uma dúvida surgiu: é possível alimentar o arduino via GPIO da Raspberry?

    Agradeço desde já

    1. Olá Marina,

      É possível sim, certeza de conectar os pinos de forma correta. Qualquer conexão errada poderá danificar o Arduino ou a RPi.

      Abraço!
      Rosana – Equipe MakerHero

  4. Adilson,
    Se eu tenho um haspebrry pi e um arduino com ethernet shield, posso fazer os dois se comunicarem via ethernet? Conectando os dois em um modem ou em switch?

    1. Lorentz,

      Se ambos estiverem configurados de forma corretinha, funciona sim.

      Abraços, e cuide-se com o COVID-19!
      Diogo – Equipe MakerHero

  5. É possível fazer essa comunicação com o modulo RF ? Tel algum tutorial ?

    1. Olá, Yuri,

      É possível sim, com o módulo nRF24L01: https://www.makerhero.com/produto/nrf24l01-wireless-transceiver-24ghz/

      Abraços!
      Diogo – Equipe MakerHero

  6. Boa tarde.
    No meu Raspberry, não existia o arquivo inittab. Isso é um problema?
    Também verifiquei que não possuo o arquivo dev/ttyAMA0. Posso usar outro? Qual?

    1. Olá Luis,

      Você está usando o Raspbian como sistema operacional?

      Abraço!
      Rosana – Equipe MakerHero

      1. Oi. Sim.
        O Hardware é esse:
        https://www.makerhero.com/produto/raspberry-pi-3-model-b/
        Quero fazer a comunicação serial através dos pinos 8 e 10, não da USB. Não estou conseguindo configurar.

        1. O Arquivo ttyAMA0, agora está presente. Mas não consigo configurar para essa saída.

          1. Olá Luis,

            Provavelmente sua distribuição deve ser baseada no mecanismo de inicialização systemd. Neste caso, ao invés de editar o arquivo inittab, abra um terminal na Raspberry Pi e execute os comandos abaixo:

            $ sudo systemctl mask [email protected]
            $ sudo reboot

            Depois é só continuar o tutorial 😀

            Abraço!
            Rosana – Equipe MakerHero

  7. Através da porta TX e RX da Raspberry tem como eu conectar mais de um Arduíno?
    Estou com um projeto e preciso conectar 3 arduinos a uma Raspberry.

    1. Olá Igor,

      Usando o protocolo de comunicação I2C você pode conectar mais de um Arduino em uma Raspberry. Também há a possibilidade de fazer a conexão dos Arduinos com a Raspberry através das portas USB.
      Boa sorte com o projeto!

      Abraço,
      Rosana – Equipe MakerHero

  8. Eu gostaria de saber se esse mesmo procedimento pode ser feito com a placa Orange Pi ao inves da Raspberry Pi, e o que precisa ser mudado para utilizar essa outra placa ?

    1. Olá,

      Acredito que o procedimento deva ser o mesmo.

      Abraço,
      Rosana – Equipe MakerHero

  9. Opa sou novo nesse mundo. Vou ligar o arduino com raspberry usando USB. A dúvida é: a fonte do raspberry de 5v de 3a já basta para alimentar inclusive o arduino, porque quando liguei já vi que a placa acendeu? Ou eu coloco uma fonte externa no arduino (inclusive tenho uma de 9v 1a)?

    1. Olá Cristovão,

      Recomendo usar uma fonte para cada placa para garantir o bom funcionamento de cada uma.

      Abraço!
      Rosana – Equipe MakerHero

  10. 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.

    1. Olá Maycon!

      Já tentou dar uma pesquisada no Google sobre este erro?

      Veja o que encontrei pra você no Google:
      https://stackoverflow.com/questions/35642855/python3-pyserial-typeerror-unicode-strings-are-not-supported-please-encode-to
      https://www.experts-exchange.com/questions/29074181/TypeError-unicode-strings-are-not-supported-please-encode-to-bytes-'AT-r-n‘.html
      https://python-forum.io/Thread-Pyserial-Issues-with-Python3-7-and-Fluke-Multimeter

      Basicamente deve ser algo relacionado a encoding, strings e bytes.

      Está usando qual versão do Python?

      Sobre /etc/inittab. Isso não está relacionado com erro de enviar o ‘L’.

      Esse post é de 2015 então de lá pra cá provavelmente já mudou bastante coisa no processo.

      Veja um método mais atual de habilitar a porta serial em uma Raspberry Pi:
      https://www.raspberrypi.org/forums/viewtopic.php?t=213133

      Resumindo a resposta do link acima:
      “Enabling the serial port is easy. Start sudo raspi-config and find serial in the Interfaces menu.
      Answer NO to the question about login shell.
      Answer YES to the question about serial hardware port.
      Reboot.”

    2. Olá,

      Também passei por este problema, resolvi alterando a linha 23, de:
      ser.write(“L”)

      Para:
      ser.write(b’L’)

  11. 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 [email protected]
    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?

  12. 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 MakerHero

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

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

  15. 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

  16. 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.

  17. 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

  18. 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 MakerHero

  19. 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 MakerHero

  20. 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

  21. 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 MakerHero

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

    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 MakerHero

  23. 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 MakerHero

      1. Muito obrigado!

  24. Até que enfim, estava esperando por um post assim 😀

  25. quando vai ter mais sorteios?