mercredi 20 novembre 2019

Raspberry Pi: présenter des mesures sous forme de graphique cartésien

Dans cet article, je vous présente comment j'ai pu présenter en temps réel, sous la forme d'un graphique cartésien, les mesures prises par un capteur branché aux broches GPIO du Rasbperry Pi.  Pour ce faire, j'ai utilisé un programme en langage Python, ainsi que la bibliothèque Matplotlib.



Installation de la bibliothèque Matplotlib

Matplotlib est une bibliothèque spécialement conçue pour représenter des données sous forme de graphique dans un programme en Python. Une façon simple de l'installer dans votre Raspberry Pi est d'écrire la commande suivante dans le terminal:

pip3 install matplotlib

J'ai aussi eu besoin d'installer gi cairo:

sudo apt-get install python3-gi-cairo

Un exemple de script (données calculées)

Voici un script qui fait apparaître un graphique qui se met à jour à toutes les 500 ms. Pour que tout le monde puisse en faire l'essai sans autre matériel qu'un Rasbperry Pi, les données qui s'affichent sur le graphique sont issues d'un calcul plutôt que d'une mesure effectuée par un capteur.

-
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Ce script produit un graphique en temps réel en calculant
la valeur d'une fonction sinusoïdale.
Il s'agira de remplacer le calcul de valeurs_y par la mesure
reçue d'un capteur.
Pour plus d'infos:
https://electroniqueamateur.blogspot.com/2019/11/raspberry-pi-presenter-des-mesures-sous.html
'''
from math import sin # pour le calcul de valeurs_y
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
temps_pause = 500 # nombre de millisecondes entre 2 mesures consécutives
valeurs_x = [] # données en abcisse
valeurs_y = [] # données en ordonnée
def animate(i):
valeurs_x.append(i * temps_pause/1000.0) # temps écoulé en secondes
#---
valeurs_y.append(5.0*sin(i/20.0)*sin(i/50.0)) # à remplacer par la mesure d'un capteur
#---
plt.cla() # on efface le graphique déjà tracé
plt.plot(valeurs_x, valeurs_y) # tracé de la courbe
plt.title('Mon graphique') # titre du graphique
plt.xlabel('temps (s)') # identification de l'abcisse
plt.ylabel('valeur calculee') # identification de l'ordonée
ani = FuncAnimation(plt.gcf(), animate, interval=temps_pause) # mise à jour du grahpique
plt.show() #affichage à l'écran
-

La variable temps_pause contient le nombre de millisecondes entre chaque mise à jour du graphique. Vous pouvez évidemment modifier cette valeur selon vos besoins (si ce temps est trop court pour la vitesse de votre Raspberry Pi, le graphique restera vide).

Les données à mettre en graphique s'accumulent dans les variables valeurs_x et valeurs_y.

Grâce à la fonction FuncAnimation de matplotlib, la routine animate s'exécute automatiquement, à intervalle régulier.

Le programme s'interrompt lorsque vous fermez la fenêtre du graphique.



Un deuxième exemple de script (données mesurées)

Pour afficher dans le graphique les données mesurées par un capteur, il s'agit de remplacer le calcul de la ligne 30 par une procédure qui ajoute à la variable valeurs_y la mesure issue du capteur. Évidemment, la syntaxe exacte dépend du capteur que vous utilisez.

Voici par exemple un script qui met en graphique les valeurs mesurées par un module PCF8591 (il s'agit en fait de la tension contrôlée par le potentiomètre intégré au module).

-
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Ce script produit un graphique en temps réel de
la valeur mesurée par le potentiomètre d'un
module PCF85901.
Plus d'infos:
https://electroniqueamateur.blogspot.com/2019/11/raspberry-pi-presenter-des-mesures-sous.html
'''
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import smbus # nécessaire pour la communication i2c
addresse = 0x48 # adresse i2c du module PCF8691
entree = 0x40 # utiliser 0x40 pour A0, 0x41 pour A1, 0x42 pour A2 et 0x43 pour A3
temps_pause = 500 # nombre de millisecondes entre 2 mesures consécutives
valeurs_x = []
valeurs_y = []
bus = smbus.SMBus(1) # définition du bus i2c (parfois 0 ou 2)
def animate(i):
valeurs_x.append(i * temps_pause/1000.0) # temps écoulé en secondes
#---
bus.write_byte(addresse,entree) # directive: lire l'entrée A0
valeurs_y.append(bus.read_byte(addresse))
#---
plt.cla() # on efface le graphique déjà tracé
plt.plot(valeurs_x, valeurs_y)
plt.title('Etat du potentiometre') # titre du graphique
plt.xlabel('temps (s)') # identification de l'abcisse
plt.ylabel('valeur mesuree') # identification de l'ordonée
ani = FuncAnimation(plt.gcf(), animate, interval=temps_pause)
plt.show()
-

En tournant lentement le potentiomètre, j'ai obtenu ce graphique:


À lire aussi

Vous trouverez sur cette page la liste de tous les articles du blog portant sur le Raspberry Pi, et sur celle-ci les articles portant sur l'utilisation des microcontrôleurs dans un contexte scientifique.

Yves Pelletier   (TwitterFacebook)


Aucun commentaire:

Enregistrer un commentaire