Site icon AranaCorp

Comunicação serial entre Raspberry Pi e Arduino

5
(1)

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

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.

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:

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

Fontes

Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie

How useful was this post?

Click on a star to rate it!

Average rating 5 / 5. Vote count: 1

No votes so far! Be the first to rate this post.

Exit mobile version