%pylab inline
import serial # nécessite l'installation du module pyserial
from time import time
Exécuter la première cellule et la dernière (fonctions support).
La fonction lectureSerie
permet de récupérer dans un tableau numpy de flottants et dans un fichier texte des données transmises sur le port série.
Les données sont lues ligne par ligne sur le port série. Chaque ligne doit comporter des entiers ou flottants, transmis sous forme de chaînes de caractères, séparées uniquement par un caractère espace.
2 opérations à réaliser :
initPortSerie
pour configurer la connection. Cette fonction ne peut être exécutée plusieur fois.lectureSerie
pour lire les données et, de façon optionnelle, créer un fichier texte.Un fichier texte contenant les données est créé uniquement si un nom de fichier est transmis. Les données peuvent facilement être récupérées avec np.loadtxt
.
Il est possible de définir la durée de communication (15s par défaut). Par défaut, les 5 premières lignes sont affichées. La définition est :
def lectureSerie(ser, duree=15, affiche=5, fichier=None):
Ci-dessous un exemple d'utilisation à adapter.
# INITIALISATION du port série (à n'éxécuter qu'une seule fois)
ser = initPortSerie("COM5",115200)
# lecture des données sur le port série pendant 10s et créaction d'un fichier data.txt
data=lectureSerie(ser, 10, fichier="data.txt") # données récupérées dans la variable data
data = np.loadtxt("data.txt")
t = np.linspace(0, (len(data)-1) * 0.1, len(data))
vG, vD, vitG, vitD = data[:,0], data[:,1], data[:,2], data[:,3]
plt.plot(t,vG, label="vG")
plt.plot(t,vG, label="vD")
plt.plot(t,vitG, label="vitG")
plt.plot(t,vitD, label="vitD")
plt.grid()
plt.legend()
plt.figure(figsize=(10,3))
plt.subplot(121)
plt.plot(t,vG, label="vG")
plt.plot(t,vG, label="vD")
plt.plot(t,vitG, label="vitG")
plt.plot(t,vitD, label="vitD")
plt.grid()
plt.legend()
plt.xlim(0, 1)
plt.ylim(0,1000)
plt.subplot(122)
plt.plot(t,vG, label="vG")
plt.plot(t,vG, label="vD")
plt.plot(t,vitG, label="vitG")
plt.plot(t,vitD, label="vitD")
plt.grid()
plt.legend()
plt.xlim(3.25, 4.5)
plt.ylim(0,1000)
Les fonctions ci-dessous permettent de récupérer les informations envoyées par le microcontroleur sur le port série avec la fonction Serial.print et Serial.println.
La lecture est réalisée ligne par ligne et se termine à la lecture d'une ligne comprenant l'unique mot : fin. La lecture s'arrête aussi au bout d'un temps de prédéfini (15s par défaut).
Par défaut, le débit doit être le plus important possible : 115200 bauds
Le nom du port est affiché en bas à gauche des fenêtre de l'environnement Arduino.
La fonction la plus importante est lectureSerie.
def initPortSerie(port,baud=9600):
"""Initialise le port série port et retourne un objet de type serial.Serial"""
ser=serial.Serial();
ser.port = port
ser.baudrate = baud # doit être identique au débit du programme arduino
print("Configurer le port série de l'Arduino avec : Serial.begin(",baud,");\n")
return ser
def ouverturePortSerie(ser):
"""Ouvre en lecture le port ser, objet de type serial.Serial."""
ser.open() # Ouverture du port série
print("port série ouvert :",ser.port)
ser.flushInput() ; ser.flushOutput() # Vider les buffers d'entree et de sortie
def fermeturePortSerie(ser):
"""Ferme le port ser, objet de type serial.Serial."""
ser.close() # Fermeture du port série
ser.close()
print("port série fermé :",ser.port)
def traitement(ligne,nbligne=-1):
"""Traitement par défaut des lignes lues sur le port série.
Cette fonction affiche chaque ligne lue ainsi que son numéro."""
print(nbligne,"-->",ligne)
def lecture(ser,f=traitement,duree=15):
"""Lit, ligne par ligne, les données sur le port ser (objet de type serial.Serial).
La lecture s'arrete lorsqu'une ligne est constituée de l'unique mot 'fin',
ou au bout d'un temps de 15 s par défaut (duree).
Chaque ligne lue avec son numéro est transmise à la fonction f.
Par défaut la fonction f est la fonction de nom 'traitement' réalisant l'affichage
de la ligne."""
ouverturePortSerie(ser) # ouverture
fin=False
tdebut=time()
nbligne=0
while (not fin) and (time()-tdebut)<duree:
# lecture des lignes
lignes=[]
while ser.inWaiting(): # on remplit le buffer avec les données en attente sur le port série
try :
lignes.append(ser.readline().decode("utf8").strip())
if lignes[-1]=="fin": fin=True
except :
print("il y a une donnee incorrecte")
fin=True
# traitement des lignes lues
for l in lignes:
if l!="fin":
try:
f(l,nbligne)
except:
fermeturePortSerie(ser)
raise
nbligne=nbligne+1
fermeturePortSerie(ser)
def lectureSerie(ser, duree=15, affiche=5, fichier=None):
"""Lit sur le port série, pendant la durée indiquée, les données et les converties
en tableau de flottant.
Les données doivent être séparées par le caractère espace.
Séparateur décimal : . (le point).
Affiche les affiche premières lignes lues.
Les donnes peuves être enregistrée dans un fichier texte avec l'espace comme séparateur."""
data=[]
if fichier is not None:
fic = open(fichier,'w')
def recup(l,n):
if n==0 and affiche>0: print(str(affiche)+" premières lignes récupérées :")
if n<affiche: print(l)
A=l.split(" ")
try:
data.append(np.array([float(val) for val in A]))
except ValueError:
if fichier is not None: fic.close()
raise ValueError("La ligne "+l+" ne peut être convertie en liste de flottants.")
if fichier is not None:
fic.write(l + "\n")
lecture(ser, recup, duree)
if fichier is not None: fic.close()
return np.array(data)