Gérer le GPIO avec Python
Introduction
Ça y est, c’est le grand saut ! Après avoir pris le temps de beaucoup d’explications et de se doter des outils nécessaires à la programmation, c’est le moment de se lancer, enfin !
Comme dans tout apprentissage, nous commencerons par des choses simples pour complexifier au fur et à mesure. À l’instar de l’affichage d’un « Hello world !! » dans une fenêtre réalisé avec un nouveau langage, l’allumage d’une LED avec un Raspberry Pi en Pyhton est LA première étape incontournable. Et il faudra aborder tous les concepts de ce chapitre afin d’être armé pour comprendre le chapitre suivant et ses outils d’analyse d’images.
Précisons qu’à la lecture de ces lignes, il paraît toujours très facile de reproduire les manipulations décrites. Mais bien souvent, dans la réalité, cela ne se passe pas comme on l’imagine. Et il est pratiquement sûr qu’à un moment ou à un autre, vous passerez à côté de quelque chose qui produira une erreur ou un fonctionnement non souhaité. C’est normal et inhérent à l’apprentissage.
Alors, n’hésitez pas à persévérer un peu, revérifiez la syntaxe, lisez les messages d’erreur...
Allumer une LED
La LED est le composant de base pour l’apprentissage de la programmation sur Raspberry Pi. Par son éclairage ou son extinction, elle matérialise la présence ou l’absence de tension électrique. Connectée à une sortie GPIO et dotée d’une résistance de limitation adéquate, elle rend compte d’effets produits par le programme sur la sortie.
1. Connecter la LED au GPIO
Une sortie GPIO pouvant prendre deux états (l’état haut à 3,3 volts et l’état bas à 0 volt), il existe deux manières de brancher une LED sur une sortie GPIO. L’une avec la masse comme référence, l’autre avec le +3,3 volts.

Dans le premier cas, il faut mettre la sortie à l’état haut afin d’amener le potentiel 3,3 volts pour illuminer la LED. Dans le second, c’est l’inverse : l’état bas doit être mis sur la sortie afin d’amener le potentiel 0 volt.
Le positionnement de la résistance d’un côté ou de l’autre de la LED n’a pas d’importance. Il faudra cependant bien veiller à l’orientation de la LED pour respecter sa polarité afin de la voir s’illuminer.
Pour la suite, le choix se porte sur une LED rouge, ainsi que sa résistance de 150 Ω connectée à la sortie GPIO 23. Le schéma de connexion vers la masse est, à ce stade, privilégié afin de faciliter la compréhension de l’ensemble : état haut, ce qui veut dire présence d’une tension de 3,3 volts, d’où courant dans la LED et donc illumination.
Voici le schéma électronique :

Et voici un exemple de positionnement des composants et des liaisons entre la platine d’essai et le Raspberry Pi 5 :

Vous verrez souvent apparaître le nom de Fritzing sur les schémas de câblage. Et pour cause, tous les schémas électroniques de cet ouvrage ont été réalisés avec ce logiciel open source de prototypage électronique. Il permet la conception et la réalisation de circuits imprimés à partir de schémas et de prototypes sur platine d’essai. En outre, il dispose d’une bibliothèque...
Réaliser un feu tricolore
1. Cahier des charges
Fort du pilotage d’une LED, passons maintenant à un niveau supérieur en réalisant un feu de circulation tricolore. Le feu tricolore fait intervenir trois LED avec le fonctionnement suivant :
-
Le feu est rouge pendant 10 secondes.
-
Le feu est vert pendant 5 secondes.
-
Le feu passe à l’orange pendant 2 secondes.
-
Le feu passe au rouge pendant 10 secondes.
Dans un second temps, cette séquence sera répétée de manière infinie.
2. Câblage du feu tricolore
Au niveau du schéma, pas de difficulté majeure. Il suffit de rajouter deux LED, l’une orange et l’autre verte, avec leur résistance de limitation sur deux sorties GPIO supplémentaires. Le choix se porte sur les GPIO 24 et 25, relativement proches du GPIO 23.

Côté câblage, on utilisera cette fois-ci la ligne de masse de la platine d’essai afin de limiter la liaison à une seule broche GND du Raspberry Pi.

3. La création du script Python
Nous avons déjà expérimenté les méthodes pour piloter les LED, désormais nous voulons les enchaîner et les exécuter de manière infinie. Cela passe par la création d’un fichier script Python.
D’une manière générale, l’adoption d’une organisation faisant intervenir un répertoire par projet est une bonne pratique. Il faudra placer tous les projets étudiés dans cet ouvrage dans un répertoire CodePython que vous aurez créé dans votre répertoire ~/Documents.
À l’aide du gestionnaire de fichiers, ou bien en ligne de commande, créez le répertoire CodePython dans ~/Documents. Créez ensuite un sous-répertoire FeuTricolore.
Ouvrez Visual Studio Code.
À partir du menu Fichier, choisissez l’option Ouvrir le dossier….

Parcourez l’arborescence pour sélectionner votre répertoire FeuTricolore nouvellement créé.

Cliquez sur le bouton Ouvrir.
Lors de l’ouverture d’un nouveau dossier dans Visual Studio Code, l’avertissement de sécurité suivant peut s’afficher :

Il s’agit tout simplement de décider si votre...
Utiliser un bouton-poussoir
Le bouton-poussoir ou l’interrupteur sont des actionneurs externes à la carte Raspberry Pi qui permettent d’interagir avec un programme. L’appui ou la bascule modifie l’état de potentiel électrique d’une broche GPIO configurée en mode entrée et indique au programme qu’une action a été effectuée.
1. Connecter le bouton-poussoir au GPIO
Comme pour la LED, il existe deux façons de connecter un bouton-poussoir à une entrée GPIO. Si leurs finalités sont équivalentes, le choix de l’un ou l’autre des schémas (vus au chapitre Le matériel utilisé, section Le bouton-poussoir et l’interrupteur) est généralement guidé par des contraintes de câblage, par exemple. En général, la masse est facilement accessible en tout point d’un circuit et est généralement commune à tous les niveaux de tension d’alimentation. C’est d’ailleurs le cas pour le Raspberry Pi 5 avec ses deux alimentations 5 volts et 3,3 volts et sa masse commune. Le premier schéma est bien souvent privilégié pour ces raisons. Mais pas seulement ! La résistance de tirage est très souvent remplacée par celle disponible en interne au SoC qui est activable par logiciel. Un composant de moins, et surtout une connexion vers le +3,3 volts en moins à réaliser !
Voici donc le schéma que nous allons retenir pour le bouton-poussoir.

Il s’en trouve extrêmement simplifié, le bouton-poussoir étant câblé entre la masse et la broche GPIO 7.
Voici un exemple de positionnement sur la platine d’essai.

Le bouton-poussoir utilisé ici dispose de quatre pattes, ce qui lui confère une meilleure stabilité mécanique une fois soudé. Comme le montre la vue schématique, les pattes sont reliées entre elles par paires, et l’appui établit le contact entre les deux paires, ce qui est exactement le même fonctionnement qu’avec un bouton-poussoir à deux pattes.
2. Récupérer l’information du bouton-poussoir
La bibliothèque gpiozero met à disposition la classe Button permettant de récupérer l’information...
Variation de luminosité d’une LED
Pour mettre à profit les acquis sur le bouton-poussoir et la LED, nous allons maintenant mettre en pratique ces deux composants en créant un variateur de luminosité.
1. Cahier des charges
Le principe de fonctionnement se rapproche des variateurs de luminosité dont on peut disposer chez soi et qui fait intervenir un bouton-poussoir mural classique pour commander la luminosité de l’éclairage intérieur. La manipulation du bouton-poussoir provoque les effets suivants :
-
Lors d’un appui bref sur le poussoir :
-
Si la lumière est éteinte, elle s’allume.
-
Si la lumière est allumée, elle s’éteint. Jusque là, c’est le fonctionnement normal d’un poussoir d’éclairage.
-
Lors d’un appui long, la luminosité est augmentée progressivement jusqu’au relâchement du bouton.
-
Lors d’un second appui long, la luminosité est diminuée progressivement jusqu’au relâchement du bouton.
2. La variation de luminosité via PWM
L’une des méthodes très utilisées pour faire varier la luminosité est le pilotage par PWM ou modulation de largeur d’impulsion. La LED est mise en clignotement à une fréquence très élevée, et le rapport cyclique entre l’état haut et l’état bas est modulé. À cette fréquence, notre œil fait la moyenne, et nous percevons la valeur moyenne de l’éclairage émis.
3. Câblage du variateur de luminosité
Rien de nouveau côté composants et mise en œuvre. Il s’agit uniquement de l’association des deux composants étudiés dans les paragraphes précédents : une LED sur une sortie GPIO et un bouton-poussoir sur une entrée GPIO.

La ligne de masse de la platine d’essai sera utilisée pour limiter les connexions de masse avec la carte Raspberry Pi.

4. Création du script
Pour améliorer la compréhension globale, nous allons procéder en deux étapes fonctionnelles. La première consistera à réaliser les fonctions d’allumage et d’extinction progressives de la LED en restant appuyé sur le bouton-poussoir, sans s’occuper...
Piloter des LED adressables
1. Cahier des charges
Nous allons utiliser ici un anneau de 24 LED RGB. Mais libre à vous d’utiliser un morceau de ruban, une barre toute faite, ou des LED adressables individuellement interconnectées par vos soins. Préférez des LED adressables alimentées en 5 volts de manière à utiliser l’alimentation du Raspberry Pi. Attention au nombre de LED et à la consommation totale déjà évoquée au chapitre Le matériel utilisé, section Les rubans et anneaux de LED adressables, Utilisation. Des LED RGB sont utilisées, mais nous verrons comment adapter simplement aux LED RGBW.
L’objectif de ce script est d’illuminer progressivement les LED du ruban avec une couleur, en commençant de gauche à droite, puis d’éteindre chaque LED de gauche à droite. La couleur pourra être modifiée, ainsi que le nombre de LED, le type de LED (avec ou sans LED blanche) et la vitesse de défilement.
Dans un deuxième temps, deux évolutions seront au programme. Il faudra les prendre en compte dès la conception initiale :
-
L’ajout d’un effet de traînée : à l’extinction, trois, quatre ou cinq LED seront éteintes de manière progressive. Il faudra pouvoir facilement adapter cette longueur de traînée, car elle devra être choisie en fonction de la longueur de notre ruban.
-
Il est prévu de pouvoir piloter l’animation avec deux boutons-poussoirs, l’un pour avancer dans l’animation, l’autre pour reculer.
Mais chaque chose en son temps, concentrons-nous sur la réalisation du remplissage et du vidage du ruban, ainsi que sa mise au point.
2. Le choix de la bibliothèque Python
Jusqu’aux générations 4 de Raspberry Pi, il était possible de piloter une sortie GPIO afin de produire le signal série nécessaire à la première entrée Din d’une chaîne de LED adressables. Ceci était réalisé grâce à la fameuse bibliothèque nommée rpi_ws281x (https://github.com/rpi-ws281x/rpi-ws281x-python). Mais la nouvelle architecture matérielle des cartes Raspberry Pi 5 a un peu changé la donne et cette bibliothèque...
Utiliser des encodeurs rotatifs
1. Cahier des charges
Dans ce paragraphe nous allons mettre en œuvre les deux types d’encodeurs décrits au chapitre Le matériel utilisé : l’encodeur absolu et l’encodeur incrémental.
Ils sont tous deux assimilables à des boutons-poussoirs assemblés en parallèle. La récupération des informations se fera donc via des entrées GPIO.
Pour illustrer ce paragraphe, nous allons simplement réaliser un script capable d’afficher dans la console une valeur numérique représentative de la position de l’axe de l’encodeur, et qui variera en fonction des mouvements.
2. L’encodeur absolu
a. Le câblage de l’encodeur absolu
Avec l’encodeur absolu BOURNS, une simple lecture des états des huit sorties est nécessaire pour connaître la position de son axe. Les huit broches GPIO sont choisies pour leur proximité les unes avec les autres de manière à condenser les connexions vers l’encodeur d’un côté uniquement du connecteur GPIO.

Le câblage est donc assez basique, mais nécessite un peu de rigueur en regard du nombre de fils à connecter.

Notez l’extrême similarité de ce schéma avec celui recommandé par le fabricant.

b. Le script Python
Comme d’habitude, initialisez un nouveau répertoire de travail.
Créez un répertoire Encodeurs dans le répertoire CodePython.
Ouvrez ce répertoire Encodeurs depuis Visual Studio Code.
Créez un nouveau script Python EncodeurACE-128.py.
Créez une classe ayant pour nom EncodeurACE128 :
class EncodeurACE128():
Le constructeur de la classe recevra huit numéros de GPIO, qui correspondent aux huit entrées GPIO connectées aux huit sorties de l’encodeur.
Ajoutez le constructeur de la classe :
def__init__(self,noGpio1,noGpio2,noGpio3,noGpio4,noGpio5,noGpio6,noGpio7,noGpio8):
self.SurChangementValeur=None
self._vEncodeur=None
self._gpios=[
gpiozero.DigitalInputDevice(noGpio1, pull_up=True, bounce_time=0.0001),
gpiozero.DigitalInputDevice(noGpio2...Piloter un servomoteur
Le pilotage d’un servomoteur se réalise de la même manière que pour la variation de luminosité d’une LED. C’est un signal PWM qui permet de définir la position angulaire de l’axe du servomoteur.
1. Câblage du servomoteur
Le servomoteur dispose de trois fils. Le rouge est dédié au + de l’alimentation, généralement en 5 volts. Le noir ou le marron est relié à la masse, et le dernier qui peut être orange, blanc ou d’une autre couleur, est le signal de commande. Ce dernier est généré par le GPIO 18.

Les prises à trois points des servomoteurs ne sont généralement pas adaptées au brochage du GPIO du Raspberry Pi. Il faut adjoindre des câbles Dupont mâle/femelle pour connecter ses broches au Raspberry Pi. Le câblage est assez intuitif : alimentation 5 volts, masse et commande connectées au GPIO 18.

2. Exploration des commandes
La librairie gpiozero dispose de deux classes nommées Servo et AngularServo.AngularServo hérite directement de la classe Servo. Elle dispose donc des mêmes fonctionnalités avec en plus Les deux sont quasi identiques. AngularServo permet simplement un pilotage sous forme angulaire exprimé en degrés, ainsi qu’un calibrage à réaliser en fonction des observations des positions extrêmes. Elle permet aussi de limiter la rotation angulaire, ce qui, pour certains projets, peut être intéressant si la mécanique commandée ne supporte pas toute la plage angulaire.
Néanmoins, dans un but pédagogique, nous allons porter notre attention sur la classe Servo plus basique et brute. Rien ne vous empêche par la suite, une fois le fonctionnement du servomoteur compris et maîtrisé, d’utiliser la classe AngularServo.
Ouvrez une fenêtre REPL.
Importez la bibliothèque gpiozero :
import gpiozero
Instanciez un objet s comme suit :
s=gpiozero.Servo(18)
Le servomoteur se met en marche ; vous remarquerez qu’il oscille un peu.
Testez les commandes ci-dessous :
s.min()
.mid()
s.max()
Ces commandes permettent respectivement la rotation vers la position minimale (sens anti-horaire), la position médiane et la position maximale...
Exploiter la carte Sense Hat
1. Cahier des charges
Pour donner un aperçu des possibilités offertes par la carte Sense HAT, réalisons ici quelques animations lumineuses basées sur des icônes de météo : soleil, soleil nuageux, pluie, orage, brouillard, neige et vent. Le passage d’une animation à une autre s’effectue par simple pression à gauche ou à droite sur le joystick. Une pression vers le haut fait défiler un texte avec les valeurs de température, d’humidité et de pression mesurées par la carte, tandis qu’une pression vers le bas quitte le programme.
2. Le choix de la bibliothèque
Ce qui est très intéressant avec la carte Sense HAT, c’est que vous pouvez totalement expérimenter votre code Python sans disposer d’une carte physique. Il existe en effet un simulateur logiciel offrant un affichage la matrice de LED, des curseurs pour modifier manuellement des valeurs des capteurs internes, et des boutons pour simuler les appuis sur le joystick.
Ce simulateur est installé par défaut sur Raspberry Pi OS Full et est disponible via le menu Framboise, Programmation, puis Sense HAT Emulator. Si vous ne disposez pas de l’icône dans le menu Framboise, c’est que l’émulateur n’est pas installé. Vous pouvez remédier à ce manque en exécutant la commande ci-dessous depuis un terminal :
sudo apt-get install sense-emu-tools python3-sense-emu
Le paquet sense-emu-tools contient l’émulateur, et le paquet python3-sense-emu la bibliothèque Python pour utiliser l’émulateur dans vos scripts.
Ce système est très souple. En effet, pour utiliser le simulateur ou la carte physique, il suffit d’agir sur la bibliothèque : avec sense_emu c’est le simulateur qui sera utilisé, avec sense_hat ce sera la carte physique. Ces deux bibliothèques disposent toutes deux d’une classe SenseHat avec exactement les mêmes propriétés et méthodes. Vous n’aurez donc qu’à modifier l’instruction import en début de script pour basculer entre les deux bibliothèques.
3. Exploration des commandes
Commençons par explorer un peu ce qu’il est possible de faire avec cette carte. La documentation complète...
Exécuter un script Python en dehors de Visual Studio Code
Jusqu’à présent, nous étions aidés par l’environnement graphique de Visual Studio Code pour la création, l’exécution et le débogage des scripts Python. Une fois ceux-ci mis au point, ils devront s’exécuter comme un programme indépendant de Visual Studio Code.
Python, nous l’avons déjà abordé, est un langage interprété à la base. Nos scripts sont donc de simples fichiers texte qui sont lus au fur et à mesure par un interpréteur. Celui-ci est préinstallé dans Raspberry Pi OS et se situe dans le répertoire /bin sous le nom python. D’ailleurs, l’onglet TERMINAL de Visual Studio Code montre clairement l’appel à cet interpréteur lors des phases d’exécution des scripts.

Pour exécuter le script en dehors de Visual Studio Code, il suffira donc de lancer cet interpréteur avec comme premier paramètre le chemin complet et le nom du fichier de script .py à exécuter.
Dans un terminal, lancez la commande suivante :
/bin/python ~/Documents/CodePython/FeuTricolore/FeuTricolore.py
Attention néanmoins à l’environnement virtuel que peut nécessiter votre script. Dans ce cas de figure, il faudra activer l’environnement virtuel avant...
Conclusion
Ces petits projets constituent une base de ce qu’il est possible de réaliser avec un Raspberry Pi. Il existe bien sûr d’autres composants à mettre en œuvre comme des récepteurs GPS, des capteurs divers et variés, etc. Mais les principes de programmation en Python restent les mêmes : paralléliser les tâches longues afin qu’elles ne se bloquent pas entre elles et séparer d’un côté la complexité technique et la logique de programmation de l’autre (aussi appelée le « métier »). Programmer de manière durable c’est aussi ne pas avoir à ré-écrire entièrement un programme parce qu’il n’est plus compréhensible ou maintenable.