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.
No Arduino Uno a comunicação será feita por meio dos pinos 0 (RX) e 1 (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.
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:
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.
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:
Gostou? Deixe seu comentário logo abaixo.
Excelente! Muito legal! Parabéns pelos post’s!👏👏👏👏
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 ?
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
Olá, agradeço o tutorial, muito bom 🙂
Uma dúvida surgiu: é possível alimentar o arduino via GPIO da Raspberry?
Agradeço desde já
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
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?
Lorentz,
Se ambos estiverem configurados de forma corretinha, funciona sim.
Abraços, e cuide-se com o COVID-19!
Diogo – Equipe MakerHero
É possível fazer essa comunicação com o modulo RF ? Tel algum tutorial ?
Olá, Yuri,
É possível sim, com o módulo nRF24L01: https://www.makerhero.com/produto/nrf24l01-wireless-transceiver-24ghz/
Abraços!
Diogo – Equipe MakerHero
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?
Olá Luis,
Você está usando o Raspbian como sistema operacional?
Abraço!
Rosana – Equipe MakerHero
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.
O Arquivo ttyAMA0, agora está presente. Mas não consigo configurar para essa saída.
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:
Depois é só continuar o tutorial 😀
Abraço!
Rosana – Equipe MakerHero
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.
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
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 ?
Olá,
Acredito que o procedimento deva ser o mesmo.
Abraço,
Rosana – Equipe MakerHero
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)?
Olá Cristovão,
Recomendo usar uma fonte para cada placa para garantir o bom funcionamento de cada uma.
Abraço!
Rosana – Equipe MakerHero
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.
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.”
Olá,
Também passei por este problema, resolvi alterando a linha 23, de:
ser.write(“L”)
Para:
ser.write(b’L’)
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?
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
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
Ao conectar o arduino com a placa raspberry ele também passará a ter o bluetooh e wifi?
Olá Adilson, é possível fazer comunicação entre um Raspberry pi3 e um LCD 3.2 Arduíno?
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
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
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.
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
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?
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
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/
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
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
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.
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
Excelente post.
Uma pergunta. É possível realizar esta comunicação utilizando o NRF24L01?
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
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.
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
Muito obrigado!
Até que enfim, estava esperando por um post assim 😀
quando vai ter mais sorteios?