0% ont trouvé ce document utile (0 vote)
63 vues1 page

Python - PySerial - Premier Script - LEnsE

Transféré par

aminali158
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
63 vues1 page

Python - PySerial - Premier Script - LEnsE

Transféré par

aminali158
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Accueil Sites Année Thèmes Réalisations La MInE ENG

MInE / Mosaïque d’INformations pour l’Expérimentation by LEnsE

Python / PySerial / Premier script

Type | Tutoriels |
Thèmes | Electronique Embarquée | Traitement de Données |
Mots-Clefs | Interface | Microcontroleurs | Nucleo | Python |

Back to Python Sommaire [montrer]

Pour pouvoir tester les exemples de ces tutoriels, vous devez installer la
bibliothèque PySerial. Sa documentation complète est disponible en ligne :
[Link]

PySerial est une bibliothèque Python permettant d’ouvrir et de transférer des données par
l’intermédiaire des liaisons séries d’un ordinateur. Elle est compatible avec les systèmes d’exploitation
Windows, OSX et Linux.
 Dépôt GitHub  [Link]

Premiers essais en console


Afin de pouvoir utiliser cette bibliothèque, il faut que vous l’importiez dans votre environnement de News du LEnsE
travail Python. Cette bibliothèque s’appelle serial. Nous aurons également besoin par la suite d’un outil
intégré à cette bibliothèque : list_ports. Pour importer ces deux éléments, vous pouvez saisir les lignes Forum IngénIOGS – 30 avril 2024
suivantes dans votre console Python :

1. import serial
2. import [Link].list_ports

Liste des ports séries d’une machine


Les ordinateurs peuvent posséder, de base, plusieurs interfaces séries à disposition de l’utilisateur.
Certains périphériques (comme les cartes Nucléo par exemple) sont susceptibles de proposer RayON épisode 3 est disponible !
également une interface de ce type afin de transférer des données. Il est donc indispensable de
connaître la liste des ports de communication série disponibles sur votre machine.

Pour cela, vous pouvez saisir dans la console Python la commande suivante :

1. serial_port = [Link].list_ports.comports()

L’objet serial_port est alors une liste contenant tous les objets de type port de communication série de
Forums des TPs 3A·M2 – Octobre-décembre 2023
votre machine. Si vous affichez directement cette liste, vous vous apercevrez qu’il n’est pas encore
possible d’accéder à l’information des ports de communication. Il va falloir afficher indépendamment
chacun des éléments de la liste par la commande suivante (par exemple) :

1. for port in serial_port:


2. print(f"{port}")

Son exécution vous donnera un affichage de ce type :

1. COM6 - Lien série sur Bluetooth standard (COM6)


2. COM4 - Lien série sur Bluetooth standard (COM4) Nouveaux Projets DEPhI en 2AP

Chaque port de communication série possède un nom. Sous Windows, ce nom est un ensemble des
lettres COM suivies d’un numéro, qui est unique. Il est possible d’accèder autrement à ces informations
en utilisant des attributs de la classe [Link].list_ports.ListPortInfo.

L’exécution des lignes suivantes :

1. for port in serial_port:


2. print(f"{[Link]} // {[Link]} // D={[Link]}")

donnera l’affichage suivant :

1. COM6 // COM6 // D=Lien série sur Bluetooth standard (COM6)


2. COM4 // COM4 // D=Lien série sur Bluetooth standard (COM4)

Connexion à un port série


Une fois que vous connaissez le port de communication auquel est connecté votre périphérique, il est
alors possible d’ouvrir une connexion avec celui-ci. Pour cela, il suffit d’exécuter la commande
suivante, en spécifiant comme premier argument de la fonction Serial le nom du port que vous
souhaitez utiliser (l’attribut device de la classe [Link].list_ports.ListPortInfo)

1. ser = [Link]("COM6", baudrate=115200)

Cette fonction d’ouverture d’un port de communication possède plusieurs paramètres :

port – obligatoire pour spécifier la nom du port auquel se connecter


baudrate (int) – la vitesse de transfert des données
timeout (float) – pour spécifier une valeur de timeout en seconde

D’autres paramètres sont également disponibles pour spécifier le nombre de bits par transmission,
l’ajout d’une détection de parité… Vous pouvez vous référer à la documentation de la bibliothèque
PySerial : [Link]

Il est important dans une liaison utilisant le protocole série (ou RS232) de spécifier la vitesse de
transmission à laquelle les deux noeuds du réseau doivent transmettre (et recevoir) les informations
binaires transmises. Ce protocole est asynchrone, le signal d’horloge, temporisant l’échantillonnage des
données, n’est alors pas transmis entre l’émetteur et le récepteur. Par défaut, cette vitesse est de 9600
bauds.

Déconnexion d’un port série


Il est indispensable de libérer le port série une fois que vous avez fini de l’utiliser. La commande pour le
faire est la suivante :

1. [Link]()

Informations relatives à la connexion RS232


Une fois connecté, il est possible de récupérer des informations sur la liaison établie.

La commande suivante donne, par exemple, l’affichage suivant. On retrouve le nom du port, la vitesse
de transfert, la parité…

1. print(ser)

1. Serial<id=0x2406d398c10, open=True>(port='COM6', baudrate=115200, bytesize=8,


parity='N', stopbits=1, timeout=None, xonxoff=False, rtscts=False, dsrdtr=False)

Il est également possible d’accéder indépendamment à chacun de ces éléments en faisant appel à
l’attribut correspondant de l’objet ser. Pour obtenir la vitesse de transmission, par exemple, on peut
écrire :

1. print([Link])

Transmission d’informations
La liaison série est une liaison asynchrone (sans transmission du signal d’horloge) et duplex
(transmission dans les deux directions). L’envoi se fait souvent octet par octet par l’application
émettrice (couches liaison et réseau du modèle OSI). La couche protocolaire RS232 émet cependant
l’information bit par bit (couche physique du modèle OSI).

Pour plus d’informations sur les différents types de communication, vous pouvez consulter le tutoriel suivant :
Faire communiquer deux systèmes ensemble (Nucleo).

Pour plus d’informations sur le fonctionnement du protocole RS232, vous pouvez consulter le tutoriel suivant :
Configurer une communication RS232 (Nucleo).

Envoi d’un “message”


L’envoi d’un message se fait caractère par caractère – norme ASCII – ou octet par octet dans le cadre de
données numériques.

Ce protocole de bas niveau ne permet que de transmettre un octet de manière “sécurisée”. Pour
pouvoir transmettre un ensemble de données de manière “propre”, il va falloir ajouter une couche
protocolaire permettant d’identifier les différents paquets transmis (voir Tutoriel XXX ).

Envoi d’un caractère


Pour envoyer un octet par l’intermédiaire de la liaison série établie précédemment, on peut utiliser le
code suivant :

1. [Link](b'a')

Dans cet exemple, le caractère ‘a’ est transmis sur la liaison. Cette fonction renvoie alors le nombre
d’octets transmis sur la liaison série.

On précise ici qu’il s’agit d’une conversion vers un octet (ou byte en anglais) par la syntaxe b’…’.

Envoi d’une chaine de caractères


De la même façon, on peut transmettre une chaine de caractères (ou String) :

1. [Link](b'bonjour')

Envoi d’octets
Il est également possible de transmettre une succession d’octets, stockés au préalable dans une liste,
ayant des valeurs particulières, de la façon suivante :

1. dataL = [1, 2, 3, 4, 5]
2. dataBytes = bytes(dataL)
3. [Link](dataBytes)

Dans cette exemple, 5 octets sont envoyés valant 1, 2, 3, 4 et 5.

Envoi de valeurs décimales


Il existe au moins deux méthodes pour transmettre une valeur décimale par l’intermédiaire d’une
liaison de ce type :

envoyer une chaîne de caractères alphanumériques correspondant à la valeur décimale (pour


transmettre 152, on transmettra successivement les caractères ‘1’, ‘5’ et ‘2’)
envoyer une valeur décimale “directement” sur le nombre d’octets nécessaires (par exemple, 152
peut être transmis sur un seul octet – car inférieur à la valeur maximale sur un octet – mais 489
devra être transmis sur au moins 2 octets).

Le choix de la méthode de transmission doit être spécifiée et identique des deux côtés de la chaîne de
transmission, afin de pouvoir décoder correctement les éléments tranmsis.

Méthode par caractères


A partir d’un entier, il est possible de créer une chaine de caractères par la méthode suivante (en
spécifiant l’encodage initial de la chaine de caractères) :

1. int_a = 152
2. str_a = str(int_a)
3. byt_a = bytes(str_a, 'utf-8')

Il est alors possible de transmettre la chaîne de caractères par la même fonction que précédemment :

1. [Link](byt_a)

Méthode par décomposition en octets


Afin de pouvoir transmettre des entiers octet par octet, il existe une méthode en python pour pouvoir
décomposer ces entiers en une série d’octets (dont le nombre est à préciser). Dans l’exemple suivant,
on souhaite décomposer le nombre 489 en 4 octets, dont le premier sera le poids fort (méthode big –
contrairement à la méthode little). La méthode write de la classe Serial enverra systématiquement 4
octets dans cet exemple.

1. int_val = 489
2. byt_val = int_val.to_bytes(4, 'big')
3. print(byt_val)
4. [Link](byt_val)

Réception d’un “message”


Il est également possible de lire des données provenant du système connecté sur cette liaison par
l’intermédiaire de 4 méthodes différents de la classe Serial :

read – qui lit un nombre d’octets passé en paramètre


read_until – qui lit des caractères jusqu’à un caractère particulier (paramètre expected)
readline – qui permet de lire une ligne de caractères (terminée par un caractère de fin de ligne)
readlines – qui permet de lire un nombre donné de lignes de caractères et les fournits dans des
listes

L’exemple suivant permet de récupérer 5 caractères sous forme d’une liste.

1. read_bytes = [Link](5)

Attention ! Si le nombre spécifié de données n’est pas atteinte, la fonction est alors bloquante…

Nous verrons dans un prochain tutoriel qu’il est parfois plus facile de traiter octet par octet afin de
pouvoir décider des actions à mener en fonction de leur valeur.

Nombre d’octets reçus


Il existe également des méthodes et attributs permettant de savoir si une donnée a été reçue par
l’ordinateur.

L’attribut in_waiting de la classe Serial fournit le nombre d’octets reçu par l’ordinateur. Cet attribut vaut
0 si aucun octet n’a été reçu.

1. print(ser.in_waiting)

Il est alors possible, lorsqu’on sait qu’on doit recevoir des données de la part du système connecté sur la
liaison d’attendre en testant la valeur de cet attribut. Si 4 octets sont attendus, on peut alors exécuter
le code suivant :

1. while(ser.in_waiting != 4):
2. print("Wait !")
3. read_bytes = [Link](4)

Exemple complet avec une carte Nucléo


Il est possible de paramétrer une liaison série (RS232) sur les cartes STMicroelectronics Nucleo (voir les
tutoriels Configurer une liaison Série et Echanger des données entre deux systèmes communiquants –
Nucleo ) et de la configurer pour qu’elle renvoie les caractères reçus (mode echo).

Echo mode sur Nucleo


Le programme de test du côté Nucléo est le suivant :

1. #include "mbed.h"
2.
3. BufferedSerial usb_pc(USBTX, USBRX);
4.
5. void usb_pc_ISR(void){
6. char rec_data_pc;
7. int rec_length = 0;
8. if(usb_pc.readable()){
9. rec_length = usb_pc.read(&rec_data_pc, 1);
10. usb_pc.write(&rec_data_pc, 1);
11. rec_data_pc = 'c';
12. usb_pc.write(&rec_data_pc, 1);
13. }
14. }
15.
16. int main()
17. {
18. usb_pc.set_baud(115200);
19. usb_pc.sigio(callback(usb_pc_ISR));
20. while (true){}
21. }

Dans cet exemple, la réception des données séries sur la carte Nucléo se fait par interruption (sigio sur
la liaison BufferedSerial). A chaque fois qu’un octet est reçu (fonction usb_pc_ISR), il est alors renvoyé
sur la même liaison et le caractère ‘c’ est ajouté.

Transmission d’information depuis Python


1. import serial
2. import [Link].list_ports
3.
4. serial_com = 6
5. serial_com_name = 'COM'+str(serial_com)
6.
7. # Open the setup serial port
8. ser = [Link](serial_com_name, baudrate=115200)
9. # Sending a char to Nucleo Board
10. [Link](b'a')
11.
12. # Waiting for data sending by Nucleo board
13. while(ser.in_waiting == 0):
14. print("Wait !")
15.
16. rec_data_nucleo = [Link](2)
17. print(f'Rec = {rec_data_nucleo}')
18.
19. [Link]()

Copyright © 2024 LEnsE. All rights reserved. Theme Spacious by ThemeGrill. Powered by: WordPress.

Vous aimerez peut-être aussi