Étiquettes : ,

Lorsque le Raspberry Pi est connecté au réseau Wifi, il est possible de communiquer avec les autres appareils du réseau à l’aide du protocole UDP. Ceci permet de piloter le Raspberry Pi depuis un autre appareil ou de gérer d’autres microcontrôleur à l’aide de requêtes UDP. Il peut servir à envoyer des commandes et recevoir des données des Arduino, ESP32 ou ESP8266 connectés sur le même réseau Wifi.

Matériel

  • Raspberry Pi
  • Connexion Wifi ou Ethernet

Principe de fonctionnement

Le protocole UDP, User Datagram Protocol, permet la transmission de datagramme de manière très simple et rapide entre deux appareils. Chaque appareil se défini par une adresse IP et un numéro de port. L’établissement de la connexion ne nécessite aucune communication préalable (en comparaison du handshaking).

La communication Wifi utilise généralement une architecture client-serveur. Dans cette architecture, il y a un serveur et un ou plusieurs clients. le serveur gère les requêtes clients et leurs envoie éventuellement une réponse.

Code

Pour communiquer à l’aide du protocole UDP, nous allons simplement créer le serveur udp qui pourra lire et écrire sur le port localPort. La librairie socket permet d »ouvrir une connexion entre deux appareils.

Le constructeur socket attend deux paramètres, la famille d’adresse (ici adresses internet) et le type de socket (ici UDP)

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

Le socket doit être lié un port de la machine sock.bind((hostname, localPort)). le fait de mettre un caractère vide à la place d’hostname (équivalent à 0.0.0.0) permet de lié le socket à toutes les 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 fonction get_ip_address() implémente une méthode pour obtenir l’adresse IP du Raspberry Pi en ouvrant un socket temporairement. Il est tout à fait possible d’utiliser la librairie os avec la commande ifconfig.

Résultat

Pour tester le résultat, nous utilisons le logiciel PacketSender qui joue le rôle de client. Nous configurons l’interface afin d’envoyer un paquet UDP sur l’adresse 192.168.1.46 sur le port 8888. Nous pouvons voir sur l’interface la réponse du serveur UDP « received OK ».

raspberrypi-udp-packetsender-result Mise en place d'un serveur UDP sur Raspberry Pi
raspberrypi-udp-server-result Mise en place d'un serveur UDP sur Raspberry Pi

Sources