Gérer le GPIO avec Python
Introduction
Avec le langage Python et la bibliothèque gpiozero, il est possible de gérer de façon simplifiée les GPIO du Raspberry Pi. Les fonctions de bas niveau qui sont utilisées pour piloter les E/S du SoC sont masquées par les fonctions de la bibliothèque qui facilitent le développement en simplifiant l’écriture des scripts.
Pour éviter tout risque de détérioration des entrées/sorties du Raspberry Pi 4, éteignez et débranchez toujours l’alimentation du Raspberry Pi avant de connecter les composants sur le GPIO !
Allumer une LED
La LED est le composant de base pour l’apprentissage de la programmation sur Raspberry Pi. Elle permet de voir rapidement si les lignes de code sont efficaces et si le script fonctionne.
Gérer une LED est l’équivalent du "Hello World" des développeurs. C’est très souvent la première phrase écrite sur l’écran avec un langage que l’utilisateur découvre. Adaptée à l’électronique, cette pratique consiste à allumer, éteindre, faire clignoter une LED pour découvrir les rudiments du langage.
Le principe de fonctionnement de la LED a été vu au chapitre Matériel utilisé - Diode LED.
1. Connecter la LED au GPIO
En suivant le schéma ci-dessus :
Connectez la cathode de la LED (patte courte) à la broche 14 (masse) du connecteur GPIO du Raspberry Pi.
Connectez l’anode de la LED (patte longue) à la broche 16 (GPIO 23) du connecteur GPIO du Raspberry Pi via une résistance de 220 Ω (150 à 330 Ω).
2. Piloter la LED en Python
a. En shell
Dans l’IDE Thonny, cliquez dans l’onglet Shell et entrez les commandes suivantes :
>>>import gpiozero
Cette commande charge entièrement la bibliothèque gpiozero que Python va utiliser pour gérer les accès aux ports GPIO du Raspberry Pi.
Le fait de charger la totalité de la bibliothèque gpiozero oblige à indiquer le nom de cette bibliothèque lors de chaque utilisation. Il existe une autre possibilité qui simplifie l’écriture de scripts, elle est expliquée plus loin.
>>>rouge = gpiozero.LED(23)
On indique à gpiozero qu’il doit...
Exécuter un script Python en shell
L’utilisation de Thonny IDE est pratique pour développer et déboguer les scripts Python. Pour une utilisation réelle des scripts, ceux-ci seront exécutés à partir de la ligne de commande. Ce sera directement en mode texte ou dans un terminal avec l’interface graphique.
1. Exécuter directement le script
a. Le shebang #!
Le shebang est symbolisé par les signes #! (dièse point d’exclamation) placés sur la première ligne d’un fichier script Python. Il indique au système d’exploitation (de type Unix-GNU/Linux) que ce fichier n’est pas un fichier binaire, mais un script (un ensemble de commandes). À la suite du shebang sur cette première ligne, on indique au système quel interpréteur il doit utiliser pour exécuter ce script.
Pour utiliser un script Python en ligne de commande sur un Raspberry Pi 4 utilisant Raspberry Pi OS, ajoutez cette ligne au début du script :
#!/usr/bin/python3
Lors de l’exécution du script, le système utilisera Python 3 pour interpréter ce script.
b. Rendre le script exécutable
Pour qu’un script soit exécutable par le système, il doit posséder des droits d’exécution. La commande ls -al permet de connaître les droits d’un fichier (cf. Utiliser la ligne de commande -...
Utiliser un bouton poussoir
1. Connecter le bouton poussoir au GPIO
Câblez la LED en suivant le schéma ci-dessous pour la suite des manipulations. Connectez le bouton poussoir comme indiqué ci-dessous.
Les contacts du bouton poussoir sont reliés aux pins 18 (GPIO 24) et 20 (masse).
Par rapport au câblage préconisé dans le chapitre Matériel utilisé, il faut noter l’absence de toute résistance dans le circuit du bouton poussoir.
Ceci s’explique par le fait que gpiozero active une résistance de tirage interne au SoC (R1) qui relie le GPIO 24 au +3,3 V.
Quand le bouton poussoir est relâché, la pin 24 est à 1 (3,3 V). Lorsque l’on appuie sur le bouton poussoir, la pin 24 est mise à la masse (0 V). Par rapport au schéma du chapitre précédent, le danger est que si la pin 24 est programmée en sortie, elle pourrait être endommagée en cas d’appui sur le bouton poussoir alors que la sortie est à 1 (3,3 V).
Si les manipulations sont faites par des débutants inexpérimentés, il est rassurant de prévoir une résistance R2 de l’ordre de 1 kΩ (non critique) pour protéger le GPIO 24 en cas d’erreur.
Le câblage prend alors cette forme. Le fonctionnement n’est pas modifié, mais la sécurité de la carte est assurée.
Dans la suite de ce livre, le câblage sera effectué comme recommandé dans la documentation de gpiozero : sans résistance de protection. Il appartient à l’utilisateur de prendre les précautions nécessaires pour protéger les GPIO.
2. Lire la position du bouton poussoir
a. Afficher la position du bouton poussoir
Objectif
Afficher en permanence à l’écran l’état du bouton poussoir.
Dans l’onglet script de Thonny IDE, tapez le script suivant (disponible en téléchargement sur LF10/bouton_01.py) :
1 from gpiozero import Button
2
3 position = Button(24)
4
5 while True:
6 if position.is_pressed:
7 print("Le bouton est appuyé")
8 else:
9 print("Le bouton est relâché")...
Allumer une LED avec le bouton poussoir
1. Méthode "classique"
L’étape suivante consiste à allumer une LED lorsque l’utilisateur appuie sur le bouton poussoir. Avec les instructions vues précédemment, il est simple de réaliser cette fonctionnalité. C’est la façon "classique" de réaliser le script avec gpiozero.
Saisissez ce script dans la zone de script de Thonny (disponible en téléchargement sur LF10/LED_04.py) :
1 from gpiozero import LED, Button
2 from signal import pause
3
4 rouge = LED(23)
5 bouton = Button(24)
6
7 print ("Appuyez sur le bouton pour allumer la LED")
8 bouton.when_pressed = rouge.on
9 bouton.when_released = rouge.off
10
11 pause()
Après importation des bibliothèques nécessaires au projet (lignes 1 et 2), on informe gpiozero qu’une LED est connectée au GPIO 23 et un bouton poussoir au GPIO 24.
Le script informe l’utilisateur de l’action à réaliser (ligne 7).
L’action sur le bouton poussoir provoque l’exécution de rouge.on ou rouge.off selon que le bouton est appuyé ou relâché (lignes 8 et 9).
La ligne 11 pause() maintient le script actif.
Démarrez le script et appuyez/relâchez le bouton poussoir....
Projet 1 : Réaliser un feu tricolore
La bibliothèque gpiozero intègre la gestion d’un feu tricolore, appelée TrafficLights. Le premier projet va consister à réaliser un feu tricolore.
1. Cahier des charges
Le fonctionnement est identique à celui du feu tricolore réel. La séquence d’allumage est :
-
rouge (arrêt des voitures)
-
vert (passage des voitures)
-
orange (arrêt des voitures et annonce du rouge)
-
rouge
-
etc.
2. Câblage du feu tricolore
En suivant le schéma ci-dessus :
Raccordez les trois LED du feu tricolore comme indiqué sur le schéma ci-dessus. La ligne de masse est commune à toutes les cathodes des LED. L’anode de chaque LED est connectée à un GPIO différent qui va contrôler l’allumage de la LED.
3. Script du feu tricolore
Avant de passer à la suite, réfléchissez à la création du script permettant d’animer le feu tricolore, à partir des instructions utilisées précédemment. Écrivez et testez votre script. Le script qui suit : FEU_01.py propose une façon de réaliser un feu tricolore.
a. Feu tricolore - version 1
gpiozero offre un ensemble d’outils pour gérer les ensembles de LED : LEDBoard, LEDBarGraph et TrafficLights. C’est ce dernier qui va permettre de simplifier l’écriture du programme.
Saisissez ce script dans la zone de script de Thonny (disponible en téléchargement sur LF10/FEU_01.py) :
1 from gpiozero import TrafficLights
2 from time import sleep
3 from signal import pause
4
5 feu = TrafficLights(16, 20, 21)
6 # Dans l'ordre GPIO des LED rouge, orange, verte
7 # En anglais red, amber, green
8
9 while True:
10 feu.red.on()
11 sleep(5)
12 feu.red.off()
13 feu.green.on() ...
Variation de luminosité de la LED
gpiozero offre la possibilité de faire varier la luminosité de la LED. Il est possible de la faire clignoter (blink en anglais) ou de faire varier sa luminosité de façon continue.
Connectez la LED comme indiqué ci-dessus pour mettre en œuvre les modifications de luminosité.
1. Clignotement
a. Par défaut
gpiozero propose une gestion simplifiée de la LED.
Saisissez ce script dans la zone de script de Thonny (disponible en téléchargement sur LF10/BlinkLED_01.py) :
1 from gpiozero import LED
2 from signal import pause
3 led = LED(23)
4
5 led.blink()
6
7 pause()
Ligne 1 : importation de la bibliothèque de gestion de la LED.
Ligne 2 : importation de la bibliothèque de gestion de la pause.
Ligne 3 : déclaration de la LED reliée au GPIO 23. Le GPIO 23 est paramétré en sortie.
Ligne 5 : mise en clignotement de la LED avec blink(). Par défaut, le temps d’allumage et le temps d’extinction sont réglés à 1 seconde.
La LED reste allumée 1 seconde puis s’éteint pendant 1 seconde.
b. Modification du clignotement
En passant des paramètres à blink(), il est possible de faire varier les temps d’allumage et extinction de la LED....
Projet 2 : Variation de luminosité
1. Cahier des charges
Faire varier la luminosité d’une LED grâce à deux boutons poussoirs. L’un des boutons fait augmenter la luminosité, l’autre la fait diminuer.
Lorsque la luminosité est égale à 0 % ou à 100 %, elle ne varie plus.
La valeur de la luminosité s’affiche à l’écran.
2. Câblage du variateur de luminosité
Câblez la LED et les deux boutons poussoirs en suivant le schéma ci-dessous :
La LED est connectée au GPIO 23 (pin 16) et les boutons poussoirs aux GPIO 24 et 25 (respectivement pin 18 et 22).
3. Analyse du déroulement du script
Lorsqu’un projet devient plus complexe, il est souvent utile de poser les idées sur le papier avant de se lancer dans l’écriture du script. Cela permet d’imaginer le déroulement du script, de l’optimiser et d’aider à la compréhension des éventuels dysfonctionnements.
L’organigramme de programmation aussi appelé logigramme est une des possibilités graphiques d’analyser un problème. Il comporte un certain nombre de formes standardisées. Plus d’informations sont disponibles sur https://fr.wikipedia.org/wiki/Organigramme_de_programmation.
L’organigramme ci-dessus utilise un jeu réduit et simplifié...
Projet 3 : Jeu de réflexes
Avec le même circuit que celui qui vient d’être utilisé pour la commande de luminosité de la LED, il est possible de créer un jeu de réflexes pour départager deux joueurs.
1. Cahier des charges
Au lancement du programme, la LED s’allume puis s’éteint après un temps aléatoire, compris entre 1 et 5 secondes.
Lorsque la LED s’éteint, les deux joueurs appuient chacun sur leur bouton poussoir. Le script détermine lequel des deux joueurs a appuyé en premier et affiche le vainqueur à l’écran.
2. Câblage du jeu de réflexes
Le câblage comprend une LED et deux boutons poussoirs. Il est identique au montage utilisé pour faire varier la luminosité de la LED.
Cet exemple montre que la même configuration matérielle peut avoir différentes utilisations en fonction du logiciel qui l’anime.
3. Écriture du script
Saisissez ce script dans la zone de script de Thonny (disponible en téléchargement sur LF10/LEDreflexe_01.py) :
# Importer les bibliothèques utilisées par le script
from gpiozero import LED, Button
from time import sleep
# uniform fournit un nombre aléatoire arrondi entre deux valeurs
# les bornes de l'intervalle sont comprises
from random import uniform
from signal...
LED tricolore RVB
Les LED RVB ont été présentées au chapitre Matériel utilisé - LED RVB. Ce sont des LED qui regroupent en un seul boîtier trois LED de couleur rouge, verte et bleue. Leur gestion est identique à celle du feu tricolore. Elles sont simplement intégrées dans le même boîtier.
1. Brochage de la LED RVB
Les LED RVB ont des longueurs de pattes différentes, ce qui permet de les identifier. La patte la plus longue est la patte commune. Pour cet atelier, la LED RVB choisie est un modèle à cathode commune.
2. Câblage de la LED RVB
En suivant le schéma ci-dessus :
Connectez la cathode de la LED (patte la plus longue) à la ligne verticale de Masse. Connectez les trois pattes correspondant aux diodes comme indiqué, sans oublier les résistances de protection.
3. Script Python pour tester la LED RVB
Saisissez ce script dans la zone de script de Thonny (disponible en téléchargement sur LF10/RGBLED_01.py) :
# Importation des bibliothèques
from gpiozero import RGBLED
from time import sleep
# Déclaration des GPIO qui commandent les LED
# Dans l'ordre rouge - vert - bleu
led = RGBLED(16, 20, 21)
# Allumer la LED bleue
led.color = (0,0,1)
#Attendre 0.5 seconde
sleep(0.5)
# Allumer la LED verte
led.color = (0,1,0)
sleep(0.5)
# Allumer la LED rouge
led.color = (1,0,0)
sleep(0.5)
# Allumer les LED bleu + vert...
LED RVB adressable
Comme vu au chapitre Matériel utilisé - LED adressable, chaque WS2812 héberge un circuit qui prélève dans la trame de données les trois premiers octets (24 bits). Les octets restants sont envoyés sur la sortie pour piloter les LED suivantes.
L’alimentation 5 volts du Raspberry Pi 4 est capable d’alimenter une douzaine de LED (anneau de 12 LED ou ruban de LED). Au-delà, il faudra impérativement prévoir d’alimenter les LED à partir d’une alimentation externe 5V suffisamment puissante (environ 60 mA par WS2812 lorsque les trois LED RVB sont allumées).
1. Bibliothèque WS2812
La bibliothèque gpiozero ne gère pas les LED RVB de type WS2812. L’intégration de ce composant dans la bibliothèque a été proposée, mais pas encore implémentée. La bibliothèque est disponible sur pypi et s’installe simplement (https://pypi.org/project/rpi-ws281x/).
Il faut donc utiliser une bibliothèque supplémentaire pour gérer les LED WS2812.
Pour installer la bibliothèque, saisissez la ligne suivante dans un terminal :
L sudo pip3 install rpi_ws281x
2. Connexion des LED RGB
Connectez l’anneau ou le ruban de LED WS2812 (pas plus de 12 LED) suivant le schéma ci-dessus. La connexion ne nécessite que trois fils : le +5 V et la masse pour l’alimentation et le GPIO 18 (pin 12) connecté à l’entrée Din (Data in = Entrée de données) du ruban ou de l’anneau.
Les caractéristiques des LED WS2812 indiquent que la tension sur Din doit être comprise entre 0 et 5 V. L’expérience montre que la tension de 3,3 V présente sur le GPIO 18 suffit pour piloter les LED. Ceci évite l’utilisation d’un convertisseur de tension entre le Raspberry Pi et le ruban de LED.
3. Test des LED WS2812
Récupérez le programme de test des LED WS2812 disponible dans le GitHub du projet :
wget https://raw.githubusercontent.com/jgarff/rpi_ws281x/master/python/
examples/strandtest.py
Le programme est également disponible dans les fichiers téléchargés en complément du livre (LF10/strandtest.py). Pour tester les LED, le script va devoir accéder au matériel. Il faut...
Gestion d’une matrice de LED
La gestion d’une matrice de LED requiert l’installation d’une nouvelle bibliothèque appelée LUMA. Cette bibliothèque gère un ou plusieurs afficheurs 7219, différentes polices de caractères ainsi que les arrangements de matrices. Les matrices peuvent être disposées de manière linéaire (journal lumineux) ou en panneau. Il faudra renseigner la bibliothèque sur l’arrangement choisi pour qu’elle gère l’affichage.
Pour piloter les matrices de LED, le bus SPI doit être activé dans le menu Configuration du Raspberry Pi, onglet Interfaces.
1. Installation de la bibliothèque
La gestion en Python de la matrice avec le circuit 7219 et le bus SPI est facilitée par l’emploi de la bibliothèque LUMA.
Son installation passe par pip3 qui est le système de gestion de paquets utilisé pour installer et gérer des librairies écrites en Python. C’est l’équivalent d’apt-get pour le système. Les librairies se trouvent dans PyPi (Python Package Index).
Placez-vous dans le dossier de l’utilisateur pi.
cd
Ajoutez l’utilisateur pi aux groupes spi et gpio pour qu’il puisse les utiliser :
sudo usermod -a -G spi,gpio pi
Installez des paquets nécessaires à l’utilisation de Luma :
sudo apt-get install build-essential python3-dev python3-pip libfreetype6-dev
libjpeg-dev
Mettez à jour les versions de pip et setuptools depuis pypi, car les versions disponibles dans Raspberry Pi OS sont souvent des versions antérieures.
sudo pip3 install --upgrade --force-reinstall pip setuptools
Il est possible que des WARNING apparaissent pendant l’installation. La plupart disparaîtront avec les mises à jour suivantes. N’en tenez pas compte.
Installez la librairie Luma depuis pypi :
sudo pip3 install --upgrade luma.led_matrix
Importez le répertoire...
Projet 4 : Journal lumineux
1. Cahier des charges
Afficher un texte défilant sur un bloc de trois matrices à LED 8x8 en utilisant la bibliothèque LUMA. Reprenez le programme de démonstration matrix_demo.py fourni avec la bibliothèque LUMA pour en extraire la partie intéressante pour ce projet. Elle se situe au début de la fonction demo.
N’hésitez pas à consulter la documentation de la bibliothèque LUMA pour comprendre le fonctionnement des instructions utilisées. C’est une des façons de s’approprier un langage et de progresser.
2. Câblage du journal lumineux
Le câblage est identique à celui qui a été vu à la section précédente Gestion d’une matrice de LED.
3. Script du journal lumineux
Saisissez ce script dans la zone de script de ThonnySudo (disponible en téléchargement sur LF10/matrice_01.py) :
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Importation des bibliothèques utilisées par le script
import time
# Gestion du circuit 7219
from luma.led_matrix.device import max7219
# Gestion du bus SPI
from luma.core.interface.serial import spi, noop
# Affichage des messages
from luma.core.legacy import show_message
# Polices utilisées par le script
from luma.core.legacy.font import proportional...
Piloter un servomoteur
Le servomoteur accepte une commande PWM. gpiozero offre la possibilité de commander le moteur à trois positions prédéterminées : minimum, maximum et milieu. On peut également définir plus précisément la position du moteur entre -1 (minimum) et +1 (maximum). Dans ce cas, 0 représente la position médiane et toutes les valeurs entre -1 et +1 sont possibles.
Tous les servomoteurs ne sont pas identiques. En fonction du modèle dont vous disposez, il est possible que vous ayez à adapter le programme pour obtenir une rotation de 180°. Certains servomoteurs n’offrent que 90° de rotation au maximum.
1. Câblage
Le servomoteur nécessite une alimentation 5 V. Il sera connecté sur la broche 5 V du connecteur (broche 2).
Le fil de commande est relié à la broche 40 du connecteur (GPIO 21).
2. Script de commande du servomoteur
a. Positions prédéterminées
Saisissez ce script dans la zone de script de Thonny (disponible en téléchargement sur LF10/servo_01.py) :
# Programme test du servomoteur SG90
# Positionne le servomoteur sur 3 positions fixes
# Importation des bibliothèques utilisées par le script
from gpiozero import Servo
from time import sleep
# Connecte le servomoteur au GPIO21
servo = Servo(21)
...
Codeur rotatif incrémental
1. Cahier des charges
L’objectif est d’afficher le sens de rotation du codeur incrémental à l’écran. Par la suite, il sera possible d’utiliser cette information pour piloter le volume de sortie d’un amplificateur, la luminosité ou la couleur d’une LED ou d’un ruban de LED…
2. Branchement au GPIO
Le codeur rotatif est relié au +3,3 V et à la masse et les deux fils S1 et S2 rejoignent les GPIO 24 et 25. La broche non connectée sur le codeur correspond au bouton poussoir qui est actionné en appuyant verticalement sur l’axe du codeur. Il n’est pas utilisé ici.
3. Programme
Saisissez ce script dans la zone de script de Thonny (disponible en téléchargement sur LF10/incremental_01.py) :
#!/usr/bin/python3
# Utilisation d'un codeur rotatif incrémental
# Importer les bibliothèques utilisées par le script
from gpiozero import Button
from signal import pause
from time import sleep
# Déclarer les entrées du codeur comme des boutons
S2 = Button(24)
S1 = Button(25)
def S1_pressed():
print ('S1 appuyé')
sleep(0.15)
def S2_pressed():
print ('S2 appuyé')
sleep(0.15)
...
Projet 5 : Défilement de couleurs
1. Cahier des charges
Une LED RVB émet une lumière de couleur. Les huit couleurs de base (noir, blanc, rouge, vert, bleu, jaune, magenta, cyan) sont affichées successivement grâce à la rotation d’un encodeur rotatif. Le défilement des couleurs dépend du sens de rotation du codeur.
2. Câblage
Le câblage du codeur incrémental rotatif est identique à celui de la section précédente. La LED RVB est connectée comme dans la section Câblage de la LED RVB et le codeur incrémental remplace le bouton poussoir de ce schéma.
3. Script de défilement de couleurs
Saisissez ce script dans la zone de script de Thonny (disponible en téléchargement sur LF10/incremental_03.py) :
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Importation des bibliothèques utilisées par le script
from gpiozero import RGBLED, Button
from colorzero import Color
from time import sleep
from signal import pause
# Cette bibliothèque permet de créer une file d'attente pour ranger les événements
# La file utilisée ici est de type FIFO = First In First Out = Premier entré
Premier Sorti
import queue
# Créer la file d'attente FIFO
eventq = queue.Queue()
...
Carte d’acquisition analogique
Un des reproches souvent faits au Raspberry Pi est l’absence d’entrée analogique. Ce type d’entrée permet de transformer une tension analogique variant continuellement en valeur numérique.
1. Choix de la carte
De nombreuses solutions existent et il faut choisir la carte qui sera la plus appropriée en fonction du projet.
Pour la station météo, il existe une carte à base de convertisseur Analogique/Numérique MCP3008 conçue par Alex Eames pour RasPiO. Elle permet de convertir huit valeurs analogiques et donne accès aux ports GPIO qui sont ramenés sur des pastilles de la carte. La carte est fournie sous forme d’un kit comportant le circuit imprimé et l’ensemble des composants.
La carte RasPiO Analog Zero utilise le bus SPI. Il faut activer ce bus via le menu Configuration du Raspberry Pi - Interfaces.
La carte se connecte sur les ports GPIO du Raspberry Pi 4 (connecteur en haut de la photo ci-dessus). Sous ce connecteur, une rangée de pastilles identifiées par sérigraphie donne accès à chaque port du GPIO. On trouve ensuite U6, le convertisseur analogique/numérique (CAN ou ADC). Les huit entrées analogiques A0 à A7 recevront les tensions à mesurer (0 à 3,3 V maximum). Sur la droite, une série de pastilles offre la possibilité de câbler...
Conclusion
Les programmes et projets de ce chapitre montrent qu’avec peu de moyens et une programmation basique, il est possible de piloter relativement facilement des composants électroniques.
Les programmes Python proposés dans ce chapitre utilisent volontairement des instructions faciles à mettre en œuvre par un débutant. Après le test des programmes et la compréhension des instructions, il est souhaitable de renforcer les connaissances acquises en combinant les possibilités.
Par exemple : faire varier la luminosité d’une LED avec le codeur incrémental, déplacer une LED allumée sur un ruban de LED RGB avec des boutons poussoirs, déplacer une LED allumée sur un anneau de LED avec le codeur incrémental…