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.

