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 ».