Réception et envoi simultanément

(de données par un programme Python)

 

 

Les programmes Python de communication avec l’Arduino étudiés jusqu’à présent, permettaient soit de recevoir, soit d’envoyer des données. Mais pour qu’il soit complet, le programme Python doit pouvoir gérer les deux actions simultanément.

Le problème se pose quand on demande à l’utilisateur de saisir au clavier une donnée et que l’Arduino continu d’envoyer des informations. Le programme Python étant bloqué sur la saisie de l’utilisateur, les données envoyées par le microcontrôleur ne peuvent pas être lues.

Pour effectuer, l’envoi et la réception des données simultanément, il suffit de créer deux boucles, l’une pour la gestion de la réception, et l’autre pour la gestion de l’envoi.

C’est de la programmation parallèle, c’est-à-dire que plusieurs instructions de code s’exécuteront en même temps, ou presque en même temps.

Pour cela, nous allons utiliser le module threading” qui permet d’exécuter un code indépendamment du code principal, ce code est appelé un thread”

Avant de l’utiliser dans un programme Python, il faut bien-sûr, l’importer :

import threading

et créer une classe qui hérite de threading.Thread :

class MyThread(threading.Thread):

    def __init__(self, target):

        threading.Thread.__init__(self)

        self.target = target

        self.StopThread = False

   
    def run(self):

        while not self.StopThread:

            self.target()

    def stop(self):

        self.StopThread = True

Ensuite, il faut créer un objet thread :

Thread = MyThread(target)

 et définir la fonction ”target” qui est appelée au lancement du thread et contient le code qui doit s’exécuter en parallèle du reste du programme.

Le thread est lancé à l’aide de l’instruction : Thread.start()

La méthode ”run()” du thread est alors appelé qui elle-même appelle la fonction ”target” qui s’exécute en boucle tant que le thread n’est pas arrêté à la fin du programme par : Thread.stop()


Exemple :

Reprenons le programme (Parseint.ino) à téléverser dans la mémoire de l’Arduino qui permet de régler la luminosité de la DEL rouge du circuit support des exemples.

Ce programme demande à l’utilisateur de saisir la valeur souhaitée de la luminosité (nombre entier entre 1 et 255), puis renvoie la valeur choisie.

Dans le programme Python (WriteThread.py) associé au programme Arduino, nous allons créer un thread” pour la réception des données envoyés par l’Arduino et une boucle while True” pour la saisie des valeurs de luminosité qui aura lieu après chaque réception suivant le déroulement suivant :

– Première réception : L’Arduino demande de saisir la luminosité (chaine de caractères reçue et affichée dans la console Python par le ”thread”)

– Saisie de la luminosité par l’utilisateur (chaine de caractères envoyée par la ”boucle while True”)

– Deuxième réception : L’Arduino renvoie la valeur choisie (nouvelle chaine de caractères reçue et affichée dans la console Python par le ”thread”)

– Nouvelle saisie de la luminosité par l’utilisateur (chaine de caractères envoyée par la ”boucle while True”)

– etc, …

 

Résultats dans la console Python :


Déroulement du programme
 :

Importation des librairies et définition de fonctions (idem programmes précédents avec en plus) :

. Importation de la bibliothèque threading” pour la création des threads,

. Création de la classe MyThread”,

. Définition de la fonction ImportDonneeSerial()” qui sera la fonction appelée en boucle par le thread et qui permet de recevoir les données envoyées par l’Arduino.

Déclaration des constantes et variables :

. donnees = ” (variable pour stocker les données qui transitent par le port série),

. DonneeRecue = 0 (compteur des données reçues, incrémentation de la variable dans la fonction gérant la réception des données).

Connexion à l’Arduino (idem programmes précédents) :

Si l’ouverture du port série a réussi, on crée un objet ”thread” dont l’argument est la fonction à appeler, et on le lance :

SerialThread = MyThread(ImportDonneeSerial)

SerialThread.start()

– Boucle principale du programme (boucle ”while True”) :

–> Attente de la saisie de la valeur la luminosité si la demande par l’Arduino a été envoyé et reçue (if DonneeRecue==1) et envoie de la donnée à l’Arduino:

SerialPort.write(str(saisie).encode(‘utf-8’))

–> Réinitialisation du compteur des donnée reçues (DonneeRecue=0) si un envoi a été fait.

– Fin du programme en appuyant sur Ctrl-C :

–> Arrêt du thread en cours : SerialThread.stop()