SE5 ECEAI/eceai 2024/2025/ling

De wiki-se.plil.fr
Aller à la navigation Aller à la recherche

L’objectif de ce module est de comprendre ce qu'est le Edge Computing. Durant ces TP, il va falloir créer un réseau d'objets connectés qui pourront distribuer le calcul à différents endroits du réseau afin d’être en mesure de pouvoir optimiser le système en termes de performances et sobriété énergétique.

Le matériel qui m'a été fourni est :

- Un Raspberry Pi 4

- Un NUCLEO-F401RE

- Un X-NUCLEO-53L5A1 (capteur de type Time Of Flight)

J'ai donc décidé de réaliser le réseau d'objets connectés suivant :

Réseau d'objets connectés


Création d'un serveur cloud

Dans un premier temps, j'ai créé une VM appelée SE5-ling sur le serveur Capbreton en utilisant l'hyperviseur Xen. Pour se faire, j'ai utilisé la commande suivante

xen-create-image --hostname SE5-ling --force --dist bookworm --size 10G --memory 1G --dir /usr/local/xen --dhcp --bridge bridgeStudents

J'ai configuré cette VM afin qu'elle puisse me servir de serveur cloud qui pourra communiquer avec les autres objets du réseau.

Pour la suite, je vais utiliser mon ordinateur personnel en tant que Serveur cloud car je m'y suis pris trop tard et les VM de Capbreton ne sont plus disponible. Pour le sous-réseau, étant donné que le point d'accès original a été retiré, j'ai décidé d'utiliser celui de mon téléphone portable .

Communication entre la Raspberry Pi et le serveur cloud

Configuration de la Raspberry Pi

J'ai choisi de communiquer avec le serveur cloud en utilisant le protocole MQTT (Message Queuing Telemetry Transport).

Il s'agit d'un protocole très utilisé en IoT (Internet of Things) car il est léger, efficace et fiable pour les communications entre appareils connectés et est également adapté pour de nombreux appareils connectés.

Pour pouvoir communiquer en MQTT, j'ai installé le service Mosquitto sur la Raspberry Pi et ainsi que sur le serveur cloud qui sont tous les deux sur le même sous-réseau.

Pour interagir avec la Raspberry Pi, je me suis connecté en série, puis j'ai utilisé Minicom pour exécuter "ip a" et obtenir son adresse IP afin d'établir une connexion SSH ensuite.

ssh pifou@192.168.53.212

Test de publication de messages MQTT sur le serveur cloud

Mosquitto est configuré par défaut pour être utilisé sur le port 1883 (sans SSL). Le service Mosquitto étant le broker MQTT a la même adresse IP que le serveur cloud donc : 192.168.53.172

Du côté de la Raspberry Pi (client MQTT), je vais souscrire à un topic appelé mqtt_rpi_cloud/test et publier un message "test MQTT depuis RPI4". Le broker va recevoir et relayer ce message à un client qui écoute sur le topic où on a publié :

mosquitto_pub -h 192.168.53.172 -p 1883 -t mqtt_rpi_cloud/test -m "test MQTT depuis RPI4"

Du côté du serveur cloud, je vais créer un client qui reçoit les messages du broker MQTT en étant souscrit au topic mqtt_rpi_cloud/test

mosquitto_sub -h 192.168.53.172 -p 1883 -t mqtt_rpi_cloud/test 

Ci-dessous, on voit bien que la communication entre la Raspberry Pi et le serveur cloud fonctionne :

Le message publié est bien arrivé au client souscrit au topic


Finalement, étant donné la quantité de données de capteur à transférer, j'ai décidé d'utiliser deux programmes python à la place de mosquitto. Un qui tournera dans la Raspberry Pi qui sera le publisher pour envoyer les données du capteur et une deuxième qui sera le subscriber qui recevra les données tout en les enregistrant.

Côté publisher (Raspberry) on lit les données qui arrivent sur le port série ttyACM0 et on les publie sur le topic "mqtt_rpi_cloud" :

import serial
import paho.mqtt.client as mqtt

# Configuration du port série
ser = serial.Serial('/dev/ttyACM0', 115200) # Préciser le port sur lequel les données arrivent

# Configuration du client MQTT
mqtt_client = mqtt.Client()
mqtt_client.connect('192.168.53.172', 1883, 60) # Préciser l'adress du broker MQTT'

try:
    while True:
        if ser.in_waiting > 0:
            # Lecture des données du port série
            serial_data = ser.readline().rstrip()
            #print(f"Données reçues : {serial_data}")

            # Publication des données sur le topic MQTT
            mqtt_client.publish('mqtt_rpi_cloud', serial_data)

except KeyboardInterrupt:
    print("Arrêt du programme.")
finally:
    ser.close()
    mqtt_client.disconnect()

Côté subscriber (serveur cloud), on récupère les données en étant souscrit au topic "mqtt_rpi_cloud" et on les stocke dans un fichier data.txt :

import paho.mqtt.client as mqtt

# Configuration du broker MQTT
broker = '192.168.53.172'
port = 1883  # Port par défaut pour MQTT
topic = 'mqtt_rpi_cloud'  # Remplacez par le topic auquel vous souhaitez vous abonner
output_file = 'data.txt'  # Nom du fichier de sortie

# Callback lors de la connexion au broker
def on_connect(client, userdata, flags, rc,properties=None):
    if rc == 0:
        print("Connecté au broker MQTT")
        client.subscribe(topic)
    else:
        print(f"Échec de la connexion, code de retour {rc}")

# Callback lors de la réception d'un message
def on_message(client, userdata, msg):
    # Enregistrement des données brutes dans le fichier
    with open(output_file, 'ab') as f:  # Mode 'ab' pour écrire en binaire
        f.write(msg.payload)
    print(f"Message reçu sur le topic {msg.topic} et enregistré dans {output_file}")

# Initialisation du client MQTT avec la version 2 de l'API des callbacks
client = mqtt.Client(callback_api_version=mqtt.CallbackAPIVersion.VERSION2)
client.on_connect = on_connect
client.on_message = on_message

# Connexion au broker MQTT
client.connect(broker, port, 60)

# Boucle principale pour écouter les messages
client.loop_forever()

Dans le fichier data.txt, on retrouve les données brutes du capteur :

Données stockées par le serveur


Entraînement du modèle d’apprentissage

Réception des données du capteur

Avant de commencer à entraîner le modèle, j'ai cherché à faire fonctionner le capteur en envoyant les données du capteur sur la liaison série. Pour cela, sur Nanoedge AI Studio, j'ai cliqué sur data logger et sélectionné les paramètres d’acquisitions au maximum avec : Data rate à 15Hz, Frame resolution à 64 et Frame à 32.

Cela a généré un programme que l'on peut téléverser en utilisant l'utilitaire STM32CubeProgrammer conçu spécialement pour les microcontroleurs STM32 comme le nucleo. Après avoir sélectionné la carte NUCLEO-F401RE, j'ai pu téléverser mon programme de data logger.

Téléversement réussi sur STM32cubeProgrammer


Si on se connecte au port série de la carte, on peut voir les données acquises par le capteur :

Donnée qui arrivent sur le port série :

Pour la suite, je compte entraîner un modèle pour reconnaître les directions des mains : mouvement vers le haut, le bas, la gauche et la droite.