,
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”.