fbpixel
Etiquetas: , , ,
0
(0)

Neste tutorial, veremos como fazer com que um Raspberry Pi e um ESP32 se comuniquem usando o protocolo UDP. Quando os dispositivos estão ligados à mesma rede WiFi, podem comunicar de forma muito simples através da troca de pacotes de dados utilizando o protocolo UDP. Como tanto o Raspberry Pi quanto o ESP32 têm conetividade WiFi integrada, é bastante simples configurar um protocolo UDP entre os dois.

Neste exemplo, o Raspberry Pi actuará como servidor e o ESP32 como cliente.

N.B.: Este tutorial pode ser facilmente transposto para um ESP8266 (código de cliente bónus no final do artigo).

Hardware

  • Computador
  • Raspberry Pi
  • NodeMCU ESP32 x1 ou superior (ou ESP8266)
  • Cabo USB A macho

Código do servidor Raspberry Pi

Para comunicar utilizando o protocolo UDP, vamos simplesmente criar o servidor udp, que será capaz de ler e escrever na porta localPort. A biblioteca socket é utilizada para abrir uma ligação entre dois dispositivos.

O construtor do socket espera dois parâmetros, a família de endereços (neste caso, endereços Internet) e o tipo de socket (neste caso, UDP).

sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) ## Internet,UDP

O socket deve ser ligado a uma porta na máquina sock.bind((hostname, localPort)) Colocar um carácter vazio no lugar do hostname (equivalente a 0.0.0.0) permite que o socket seja ligado a todas as interfaces locais.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

#Libraries
import socket	#https://wiki.python.org/moin/UdpCommunication

#Parameters
localPort=8888
bufferSize=1024

#Objects
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)  ## Internet,UDP

# function init 
def init():
	sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
	sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #enable broadcasting mode
	sock.bind(('', localPort))
	print("UDP server : {}:{}".format(get_ip_address(),localPort))

# function main 
def main():
	while True:
		data, addr = sock.recvfrom(1024) # get data
		print("received message: {} from {}\n".format(data,addr))
    
		sock.sendto("RPi received OK",addr)  # write data
  

# function get_ip_address 
def get_ip_address():
	"""get host ip address"""
	ip_address = '';
	s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
	s.connect(("8.8.8.8",80))
	ip_address = s.getsockname()[0]
	s.close()
	return ip_address




if __name__ == '__main__':
	init()
	main()

N.B.: A função get_ip_address() implementa um método para obter o endereço IP do Raspberry Pi abrindo um socket temporariamente. Também é possível usar a biblioteca os com o comando ifconfig.

Anote o endereço IP e a porta do Raspberry Pi para que possa copiá-los para o código do cliente:

  • Endereço IP: 192.168.1.46
  • Número do porto: 8888

Código do cliente UDP do ESP32

No código do cliente, vamos ligar-nos ao servidor utilizando o endereço IP e a porta anteriormente indicados (neste caso, 192.168.1.46:8888).

Nota: Não se esqueça de alterar os valores ssid e password para que o ESP32 se ligue à mesma rede que o Raspberry Pi.

#include <WiFi.h>
#include <WiFiUdp.h>
WiFiUDP udp;

char packetBuffer[255];
unsigned int localPort = 9999;
char *serverip = "192.168.1.46";
unsigned int serverport = 8888;

const char *ssid = "******";
const char *password = "********";

void setup() {
  Serial.begin(115200);
  // Connect to Wifi network.
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500); Serial.print(F("."));
  }
  udp.begin(localPort);
  Serial.printf("UDP Client : %s:%i \n", WiFi.localIP().toString().c_str(), localPort);
}

void loop() {
  int packetSize = udp.parsePacket();
  if (packetSize) {
    Serial.print(" Received packet from : "); Serial.println(udp.remoteIP());
    int len = udp.read(packetBuffer, 255);
    Serial.printf("Data : %s\n", packetBuffer);
    Serial.println();
  }
  delay(500);
  Serial.print("[Client Connected] "); Serial.println(WiFi.localIP());
  udp.beginPacket(serverip, serverport);
  char buf[30];
  unsigned long testID = millis();
  sprintf(buf, "ESP32 send millis: %lu", testID);
  udp.printf(buf);
  udp.endPacket();
}

Resultados

Quando as duas placas se ligam ao WiFi, podemos ver que há uma troca de informações entre as duas placas. É então possível controlar um dispositivo ligado ao cliente a partir do servidor ou vice-versa.

N.B.: Os endereços IP são geralmente atribuídos automaticamente. Como os endereços são definidos de forma “rígida” no código, é preferível configurar os seus dispositivos de modo a que tenham um endereço IP estático e não dinâmico. Deste modo, não é necessário modificar o código de cada vez que o aparelho é ligado.

Bónus: Comunicação UDP entre o Raspberry Pi e dois clientes ESP32

Uma vez estabelecida a comunicação, é possível adicionar vários clientes. Neste exemplo, adicionamos um cliente ESP8266

Código de cliente UDP ESP8266

É fácil transformar o código do ESP32 para o adaptar ao ESP8266, modificando o nome da biblioteca Wifi. Também alteramos o valor da porta 9696

Nota: Quando adicionar um cliente, certifique-se de que este tem um emparelhamento de endereços de

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
WiFiUDP udp;

char packetBuffer[255];
unsigned int localPort = 9696;
char *serverip = "192.168.1.46";
unsigned int serverport = 8888;

const char *ssid = "******";
const char *password = "******";


void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500); Serial.print(F("."));
  }
  udp.begin(localPort);
  Serial.printf("UDP Client : %s:%i \n", WiFi.localIP().toString().c_str(), localPort);
}


void loop() {
  int packetSize = udp.parsePacket();
  if (packetSize) {
    Serial.print(" Received packet from : "); Serial.println(udp.remoteIP());
    int len = udp.read(packetBuffer, 255);
    Serial.printf("Data : %s\n", packetBuffer);
    Serial.println();
  }
  delay(500);
  Serial.print("[Client Connected] "); Serial.println(WiFi.localIP());
  udp.beginPacket(serverip, serverport);
  char buf[30];
  unsigned long testID = millis();
  sprintf(buf, "ESP8266 send millis: %lu", testID);
  udp.printf(buf);
  udp.endPacket();
}

Resultadoss

Podemos ver que os endereços e os valores trocados pelo ESP32 e pelo ESP8266 são diferentes.

Aplicações

  • Crear una red de ordenadores y/o microcontroladores para gestionar diferentes dispositivos o sensores.

Fontes

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

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

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?