Em alguns projetos, pode ser interessante estabelecer uma comunicação serial entre o Raspberry Pi e o Arduino. Com isso, aliamos a capacidade de processamento e a interface sem fios do Raspberry Pi com as entradas e saídas e a coleção de módulos do Arduino. O primeiro exemplo que vem em mente é uma aplicação domótica em que o Raspberry Pi oferece a interface de controle e a inteligência e o Arduino funciona como um autômato programável, agindo sobre os componentes no final da cadeia (luzes, radiador, ventilador, sensores, etc.).
Veremos agora como estabelecer uma comunicação serial entre Raspberry Pi e Arduino via entrada USB. Neste tutorial, utilizamos a placa Arduino UNO, mas ele pode ser adaptado a outros tipos de placa com ligação serial (Nano, Mega, Feather, EPS32, ESP8266, etc.).
Pré-requisitos: Comunicação serial com o Arduino, Acesso remoto ao Raspberry Pi com VNC
Material
- Computador
- Arduino UNO
- Raspberry Pi 3B+
- USB A Macho/USB B Macho
Esquema de ligação
Para estabelecer a comunicação serial entre Raspberry Pi e Arduino, basta ligá-los com um cabo USB adequado. No nosso caso, utilizamos um Raspberry Pi 3B+ e um Arduino UNO. Precisamos portanto de um cabo USBA Macho para USB B Macho.
Neste tutorial, vamos focar na ligação USB, mas também é possível criar uma comunicação serial utilizando os pinos Rx/Tx de ambos os componentes.
- Tx GPIO14(RPI) <-> Rx 0(Arduino)
- Rx GPIO15(RPI) <-> Tx 1(Arduino)
- GND (RPI) <-> GND(Arduino)
Configuração do Raspberry Pi
Recordamos que, para utilizar o seu Raspberry Pi sem monitor ou teclado, é preciso configurar a conexão remota VNC.
Para utilizar a interface serial do Raspberry Pi, ela deve ser ativada no menu de configuração. Para isso, introduza o seguinte comando num terminal:
sudo raspi-config
No menu, selecione “5 – Opções de Interface” e depois “P6 Serial” e confirme.
Efetuada a conexão, pode verificar os dispositivos ligados à porta serial digitando o seguinte comando no terminal:
lsusb
O Raspberry Pi devolve uma lista de dispositivos conectados às entradas USB.
pi@raspberrypi:~ $ lsusb
Bus 001 Device 002: ID 2341:0043 Arduino SA Uno R3 (CDC ACM)
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Para encontrar o nome da entrada onde o Arduino está conectado, usamos o comando:
dmesg | grep "tty"
Esse comando devolve as mensagens do sistema relativas à porta serial. O nome da porta deve aparecer entre as últimas mensagens. No nosso caso, o nome é ttyACM0.
pi@raspberrypi:~ $ dmesg | grep "tty"
[ 0.000000] Kernel command line: coherent_pool=1M 8250.nr_uarts=1 bcm2708_fb.fbwidth=1824 bcm2708_fb.fbheight=984 bcm2708_fb.fbswap=1 smsc95xx.macaddr=B8:27:EB:23:CF:07 vc_mem.mem_base=0x1ec00000 vc_mem.mem_size=0x20000000 console=ttyS0,115200 console=tty1 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles
[ 0.000636] console [tty1] enabled
[ 0.951553] 20201000.serial: ttyAMA0 at MMIO 0x20201000 (irq = 81, base_baud = 0) is a PL011 rev2
[ 0.954393] console [ttyS0] disabled
[ 0.954466] 20215040.serial: ttyS0 at MMIO 0x0 (irq = 53, base_baud = 31250000) is a 16550
[ 0.954570] console [ttyS0] enabled
[ 5.378641] systemd[1]: Created slice system-serial\x2dgetty.slice.
[ 1455.402071] cdc_acm 1-1:1.0: ttyACM0: USB ACM device
[ 1581.980257] cdc_acm 1-1:1.0: ttyACM0: USB ACM device
Instalação da IDE do Arduino no Raspberry Pi
A melhor maneira de instalar a IDE do Arduino no Raspberry é utilizando o terminal. Basta introduzir as seguintes linhas de código:
mkdir ~/Applications
cd ~/Applications
wget https://downloads.arduino.cc/arduino-1.8.9-linuxarm.tar.xz
tar xvJf arduino-1.8.9-linuxarm.tar.xz
cd arduino-1.8.9/
./install.sh
rm ../arduino-1.8.9-linuxarm.tar.xz
Isso permitirá programar o Arduino diretamente a partir do Raspberry Pi.
Código
Código Arduino
A biblioteca utilizada para a comunicação serial do lado Arduino é a mesma usada para comunicar com o monitor serial: a Serial.h, que já conhecemos bem. Verifique se a velocidade de comunicação é a mesma para ambos os dispositivos (baudrate=9600), caso contrário a comunicação não funcionará.
String nom = "Arduino"; String msg; void setup() { Serial.begin(9600); } void loop() { readSerialPort(); if (msg != "") { sendData(); } delay(500); } void readSerialPort() { msg = ""; if (Serial.available()) { delay(10); while (Serial.available() > 0) { msg += (char)Serial.read(); } Serial.flush(); } } void sendData() { //write data Serial.print(nom); Serial.print(" received : "); Serial.print(msg); }
Código Python
Neste tutorial, adotamos a linguagem Python no lado do Raspberry Pi. A biblioteca utilizada para gerir a comunicação serial é a serial.
#!/usr/bin/env python # -*- coding: utf-8 -*- # lsusb to check device name #dmesg | grep "tty" to find port name import serial,time if __name__ == '__main__': print('Running. Press CTRL-C to exit.') with serial.Serial("/dev/ttyACM0", 9600, timeout=1) as arduino: time.sleep(0.1) #wait for serial to open if arduino.isOpen(): print("{} connected!".format(arduino.port)) try: while True: cmd=input("Enter command : ") arduino.write(cmd.encode()) #time.sleep(0.1) #wait for arduino to answer while arduino.inWaiting()==0: pass if arduino.inWaiting()>0: answer=arduino.readline() print(answer) arduino.flushInput() #remove data after reading except KeyboardInterrupt: print("KeyboardInterrupt has been caught.")
Resultado
O Raspberry Pi envia o comando “Hello Arduino” ao Arduino, e este responde com o seu nome e o comando recebido.
Exemplo prático
Estabelecida a comunicação entre o Raspberry Pi e o Arduino, o interessante é poder controlar as entradas e saídas do Arduino e obter os valores dos sensores. Neste exemplo, vamos definir diferentes comandos:
- um comando para obter os valores dos sensores
- e outro para ligar e desligar o LED no pino 13.
Código Arduino
O Arduino envia dados ao receber o comando “data” e acende e apaga o LED ligado ao pino 13 de acordo com os comandos “led0” e “led1”.
const int ledPin=13; String nom = "Arduino"; String msg; void setup() { Serial.begin(9600); } void loop() { readSerialPort(); if (msg == "data") { sendData(); }else if(msg=="led0"){ digitalWrite(ledPin,LOW); Serial.print(" Arduino set led to LOW"); }else if(msg=="led1"){ digitalWrite(ledPin,HIGH); Serial.print(" Arduino set led to HIGH"); } delay(500); } void readSerialPort() { msg = ""; if (Serial.available()) { delay(10); while (Serial.available() > 0) { msg += (char)Serial.read(); } Serial.flush(); } } void sendData() { //write data ledState x sensor1 x sensor2 Serial.print(digitalRead(ledPin)); Serial.print("x"); Serial.print(analogRead(A0)); Serial.print("x"); Serial.print(analogRead(A1)); }
Código Python
#!/usr/bin/env python # -*- coding: utf-8 -*- # lsusb to check device name #dmesg | grep "tty" to find port name import serial,time if __name__ == '__main__': print('Running. Press CTRL-C to exit.') with serial.Serial("/dev/ttyACM0", 9600, timeout=1) as arduino: time.sleep(0.1) #wait for serial to open if arduino.isOpen(): print("{} connected!".format(arduino.port)) try: while True: cmd=input("Enter command (data,led0 or led1): ") arduino.write(cmd.encode()) #time.sleep(0.1) #wait for arduino to answer while arduino.inWaiting()==0: pass if arduino.inWaiting()>0: answer=str(arduino.readline()) print("---> {}".format(answer)) if cmd=="data": dataList=answer.split("x") print("led state : {}".format(dataList[0])) print("Analog input A0 : {}".format(dataList[1])) print("Analog input A1: {}".format(dataList[2])) arduino.flushInput() #remove data after reading except KeyboardInterrupt: print("KeyboardInterrupt has been caught.")
Uma vez carregados e lançados os dois códigos, observamos que, ao introduzir o comando “data” no terminal, o Arduino retorna bytes contendo os valores dos sensores. É possível dividir esta resposta numa lista usando a função split() e o carectere “x”, e assim obter os valores dos sensores e o estado do LED. Com este código, podemos controlar o estado do LED no pino 13.
Este código pode ser modificado para controlar e visualizar qualquer entrada ou saída do Arduino no Raspberry Pi.
Aplicação
- Criar uma interface gráfica de usuário (GUI) no Raspberry Pi para controlar um Arduino e obter os valores dos sensores
Fontes
Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie