fbpixel
Etiquetas: ,

,

Cuando la Raspberry Pi está conectada a la red WiFi, es posible comunicarse con otros dispositivos de la red utilizando el protocolo UDP. Esto hace posible controlar la Raspberry Pi desde otro dispositivo o gestionar otros microcontroladores utilizando peticiones UDP. Se puede utilizar para enviar comandos y recibir datos de dispositivos Arduino, ESP32 o ESP8266 conectados a la misma red WiFi.

Hardware

  • Raspberry Pi
  • Conexión Wifi o Ethernet

Principio de funcionamiento

El Protocolo de Datagramas de Usuario (UDP) permite transmitir datagramas de forma rápida y sencilla entre dos dispositivos. Cada dispositivo se define mediante una dirección IP y un número de puerto. No es necesaria ninguna comunicación previa para establecer la conexión (en comparación con el handshaking).

La comunicación wifi utiliza generalmente una arquitectura cliente-servidor. En esta arquitectura, hay un servidor y uno o varios clientes. El servidor gestiona las peticiones de los clientes y puede enviarles una respuesta.

Código

Para comunicarnos utilizando el protocolo UDP, simplemente crearemos el servidor udp, que podrá leer y escribir en el puerto localPort. La biblioteca socket se utiliza para abrir una conexión entre dos dispositivos.

El constructor de socket espera dos parámetros, la familia de direcciones (en este caso direcciones de Internet) y el tipo de socket (en este caso UDP).

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

El socket debe estar enlazado a un puerto de la máquina sock.bind((hostname, localPort)). Poniendo un carácter vacío en lugar de hostname (equivalente a 0.0.0.0) permite enlazar el socket a todas las interfaces locales.

#!/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.: La función get_ip_address() implementa un método para obtener la dirección IP de la Raspberry Pi abriendo un socket temporalmente. También puede utilizar la biblioteca os con el comando ifconfig.

Resultados

Para probar el resultado, utilizamos PacketSender, que actúa como cliente. Configuramos la interfaz para enviar un paquete UDP a la dirección 192.168.1.46 en el puerto 8888. En la interfaz podemos ver la respuesta «received OK» del servidor UDP.

raspberrypi-udp-packetsender-result Configuración de un servidor UDP en Raspberry Pi
raspberrypi-udp-server-result Configuración de un servidor UDP en Raspberry Pi

Fuentes