,
Quando o Raspberry Pi está ligado à rede WiFi, é possível comunicar com outros dispositivos na rede utilizando o protocolo UDP. Isto torna possível controlar o Raspberry Pi a partir de outro dispositivo ou gerir outros microcontroladores utilizando pedidos UDP. Pode ser utilizado para enviar comandos e receber dados de dispositivos Arduino, ESP32 ou ESP8266 ligados à mesma rede WiFi.
Hardware
- Raspberry Pi
- Ligação Wifi ou Ethernet
Princípio de funcionamento
O Protocolo de Datagrama do Utilizador (UDP) permite a transmissão rápida e fácil de datagramas entre dois dispositivos. Cada dispositivo é definido por um endereço IP e um número de porta. Não é necessária qualquer comunicação prévia para estabelecer a ligação (em comparação com o “handshaking”).
A comunicação Wifi utiliza geralmente uma arquitetura cliente-servidor. Nesta arquitetura, existe um servidor e um ou mais clientes. O servidor gere os pedidos dos clientes e pode enviar-lhes uma resposta.
Código
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 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
# 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(bufferSize) # get data
print("received message: {} form {}".format(data,addr))
sock.sendto("received OK",addr) # write data
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.
Resultados
Para testar o resultado, usamos o PacketSender, que atua como um cliente. Configuramos a interface para enviar um pacote UDP para o endereço 192.168.1.46 na porta 8888. Na interface, podemos ver a resposta do servidor UDP, “received OK”.

