Par Rémi Favreau — 29 avril 2026
Le débat entre les deux bibliothèques GPIO Python est l’un des plus récurrents sur les forums Pi francophones, et il est souvent mal posé. On compare un outil haut niveau (gpiozero) à un outil bas niveau (RPi.GPIO) comme s’il fallait choisir un camp. Ils ne font pas la même chose, et la bonne réponse dépend de ce que tu veux comprendre et de ce que tu veux produire.
TL;DR : sur Pi 5 en 2026, pars sur gpiozero. C’est la bibliothèque recommandée par la documentation officielle de Raspberry Pi, elle fonctionne sur tous les modèles, et elle gère le cleanup automatiquement. RPi.GPIO reste utile pour comprendre ce qui se passe au niveau registre, ou pour faire tourner du code legacy via le shim rpi-lgpio. Le tableau ci-dessous résume.
| Critère | RPi.GPIO | gpiozero |
|---|---|---|
| Première release publique | 26 janvier 2012 (Ben Croston) | octobre 2015 beta, v1.0 nov. 2015 (Ben Nuttall, Dave Jones) |
| Dernière release stable | 0.7.1, 6 février 2022 | 2.0.1, 15 février 2024 |
| Pi 5 natif | Non (incompatible RP1) | Oui (backend lgpio) |
| Niveau d’abstraction | Bas (broches, registres) | Haut (composants) |
| Recommandation 2026 | Cas legacy uniquement | Choix par défaut |
RPi.GPIO : l’outil historique
RPi.GPIO a été pendant des années la seule bibliothèque sérieuse pour manipuler les GPIO du Pi en Python. Elle fonctionne au niveau registre : tu configures une broche en entrée ou sortie (GPIO.setup), tu lis ou écris son état (GPIO.input, GPIO.output), tu gères le PWM manuellement (GPIO.PWM). C’est direct, explicite, et ça ne cache rien.
Ben Croston a commencé à écrire la bibliothèque fin 2011, avant même la sortie commerciale du Raspberry Pi, dans le cadre de son travail à Fuzzy Duck Brewery à Poulton-le-Fylde, où il est head brewer. La bibliothèque servait à automatiser la régulation de température dans les cuves via un capteur DS18B20 (précis à 0,5 °C entre -10 °C et 85 °C). La première publication PyPI date du 26 janvier 2012.
Le problème : la dernière release stable est la 0.7.1 du 6 février 2022, soit plus de quatre ans sans développement actif. Et surtout, RPi.GPIO n’est pas compatible nativement avec le Pi 5. Le Pi 5 a déplacé toute la gestion des I/O dans un chip externe développé par Raspberry Pi, le RP1, qui gère aussi les deux ports USB 3.0, les deux ports USB 2.0, le contrôleur Gigabit Ethernet et les deux interfaces MIPI 4-lanes pour caméra et display (documentation RP1 officielle). Ce chip n’expose pas les GPIO via les mêmes registres mappés en mémoire que les Pi précédents, donc tout code qui tape directement sur /dev/mem casse.
Un shim de compatibilité, rpi-lgpio, écrit par Dave Jones (le co-auteur de gpiozero et auteur de picamera), reproduit l’API de RPi.GPIO en s’appuyant sur lgpio. Ça dépanne pour migrer du code existant, mais pour un nouveau projet en 2026 il vaut mieux partir directement sur gpiozero ou lgpio.
gpiozero : le moderne
Annoncée en beta mi-octobre 2015 par Ben Nuttall (alors community manager à la Raspberry Pi Foundation) avec une grosse contribution architecturale de Dave Jones, gpiozero propose une abstraction par composant : LED, Button, Motor, DistanceSensor, Servo. Au lieu de manipuler des numéros de broche et des niveaux logiques, tu manipules des objets qui représentent des composants physiques. La v1.0 est sortie en novembre 2015 et le projet est aujourd’hui recommandé par défaut dans la documentation officielle de Raspberry Pi.
La dernière release stable est la 2.0.1 publiée le 15 février 2024 sur PyPI. Le rythme de release a ralenti depuis (deux ans entre la 2.0 et la 2.0.1, contre des cadences trimestrielles entre 2015 et 2018), mais la bibliothèque est toujours maintenue et installée par défaut dans Raspberry Pi OS Bookworm.
# RPi.GPIO : allumer une LED import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) GPIO.setup(17, GPIO.OUT) GPIO.output(17, GPIO.HIGH) # ... GPIO.cleanup() à la fin # gpiozero : allumer une LED from gpiozero import LED led = LED(17) led.on()
La différence de verbosité est flagrante. L’intérêt de gpiozero va au-delà de la concision : elle gère le cleanup automatiquement (pas de GPIO.cleanup() oublié qui laisse des broches dans un état indéfini), elle supporte plusieurs backends matériels (lgpio par défaut sur Pi 5, RPi.GPIO en fallback legacy sur Pi antérieurs), et elle inclut des patterns courants comme le contrôle de luminosité LED ou le pilotage de moteur en une ligne. À noter : sur Pi 5, le PWM hardware passe par lgpio. L’autre backend historique pour le PWM hardware, pigpio (joan2937), est explicitement hardcodé pour refuser de tourner sur Pi 5 (issue #589 confirmée par l’auteur).
Comparaison sur trois cas concrets

Cas 1 : bouton qui allume une LED
# RPi.GPIO (11 lignes) import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) GPIO.setup(17, GPIO.OUT) GPIO.setup(2, GPIO.IN, pull_up_down=GPIO.PUD_UP) try: while True: if GPIO.input(2) == GPIO.LOW: GPIO.output(17, GPIO.HIGH) else: GPIO.output(17, GPIO.LOW) except KeyboardInterrupt: GPIO.cleanup() # gpiozero (3 lignes) from gpiozero import LED, Button led = LED(17) led.source = Button(2).values
La version gpiozero utilise le pattern « source/values » qui connecte directement la sortie du bouton à l’entrée de la LED. Attention : ce pattern crée un thread de fond, donc il faut garder le programme vivant après l’assignation avec signal.pause() (sinon le script se termine et la LED s’éteint immédiatement). C’est élégant, mais ça cache beaucoup de mécanique. Pour comprendre ce qui se passe physiquement (pull-up, état haut/bas, boucle de scrutation), la version RPi.GPIO reste meilleure pédagogiquement.
Cas 2 : moteur DC avec contrôle de vitesse

# gpiozero (2 lignes utiles) from gpiozero import Motor m = Motor(forward=17, backward=27, enable=12) m.forward(0.7) # 70% de vitesse # RPi.GPIO (8 lignes utiles) import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) GPIO.setup(17, GPIO.OUT) GPIO.setup(27, GPIO.OUT) GPIO.setup(12, GPIO.OUT) pwm = GPIO.PWM(12, 1000) pwm.start(70) GPIO.output(17, GPIO.HIGH) GPIO.output(27, GPIO.LOW)
La version RPi.GPIO rend visible le pont en H (IN1 haut + IN2 bas = avancer) et le PWM séparé sur ENA à 1000 Hz. Le tutoriel L298N montre les deux versions en parallèle pour que tu comprennes ce que gpiozero fait sous le capot. Sur le robot 2 roues du site, la pile de migration a été : code RPi.GPIO de 2022, passage à gpiozero+lgpio sur Pi 5 en mars 2024, suppression du GPIO.cleanup() oublié qui faisait planter les redémarrages à chaud.
Cas 3 : capteur ultrason HC-SR04

# gpiozero (2 lignes) from gpiozero import DistanceSensor d = DistanceSensor(echo=25, trigger=24) print(f"{d.distance * 100:.1f} cm") # RPi.GPIO (15+ lignes, gestion timing manuelle) import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM) GPIO.setup(24, GPIO.OUT) GPIO.setup(25, GPIO.IN) GPIO.output(24, False) time.sleep(0.5) GPIO.output(24, True) time.sleep(0.00001) GPIO.output(24, False) while GPIO.input(25) == 0: pulse_start = time.time() while GPIO.input(25) == 1: pulse_end = time.time() distance = (pulse_end - pulse_start) * 17150 print(f"{distance:.1f} cm")
La constante 17150 vient du calcul classique : vitesse du son à 20 °C ≈ 343 m/s, soit 34300 cm/s, divisé par 2 pour l’aller-retour, ce qui donne 17150 cm/s à multiplier par la durée de pulse en secondes. Ici, la version RPi.GPIO est non seulement plus longue mais aussi fragile : les boucles while bloquantes risquent de se coincer si le capteur ne répond pas. gpiozero gère les timeouts et les erreurs de mesure en interne, et tu as accès à d.max_distance pour borner la mesure (par défaut 1 m, max théorique HC-SR04 = 4 m).
Performance : est-ce que ça compte ?
Pour la robotique DIY, non. Les deux bibliothèques sont en Python, qui n’est de toute façon pas un langage temps réel à cause du GIL et du scheduling de Linux qui peuvent introduire du jitter de plusieurs millisecondes. Le surcoût d’abstraction de gpiozero est négligeable face aux temps de mesure des capteurs : un cycle ultrason HC-SR04 prend déjà 30 à 60 ms, un cycle PWM moteur tourne à 1 kHz typique sur le L298N, donc même si l’appel GPIO ajoute une dizaine de microsecondes selon le backend, ça reste invisible.
Si tu as besoin de temps réel vrai (boucle à 10 kHz, mesure à la microseconde), ni l’une ni l’autre ne convient : il faut descendre en C, voire passer sur un microcontrôleur. Le RP2040 ou RP2350 du Pico, avec son bloc PIO programmable et ses 4 state machines, est précisément conçu pour ce genre de contraintes timing strictes.
Bref, je recommanderais quoi ?
Commence avec gpiozero. C’est la bibliothèque recommandée par la documentation officielle, elle fonctionne sur tous les Pi (y compris le Pi 5 via lgpio), elle est bien documentée, et elle te permet de construire des projets fonctionnels rapidement. Quand tu voudras comprendre ce qui se passe au niveau des registres, lis le code source de gpiozero (c’est du Python lisible) ou fais un exercice ponctuel en RPi.GPIO. Mais ne te force pas à apprendre RPi.GPIO « parce que c’est plus formateur » si ça te bloque pendant des heures sur un problème de cleanup oublié.
Exception : si tu travailles sur un projet qui utilise une dépendance legacy en RPi.GPIO (certaines bibliothèques de HAT ne supportent que cette API), installe le shim rpi-lgpio sur Pi 5. Tu gardes ton code RPi.GPIO existant, et il s’exécute via lgpio en dessous. C’est aussi la voie la plus rapide pour migrer un robot construit en 2020 vers un Pi 5 sans tout réécrire.
Le guide complet robotique DIY et l’article sur les 5 capteurs indispensables utilisent gpiozero par défaut, avec les équivalents RPi.GPIO en note quand c’est utile.
Questions fréquentes
gpiozero fonctionne-t-il sur Pi Zero et Pi Zero 2 W ?
Oui, gpiozero fonctionne sur tous les modèles de Raspberry Pi, du Pi 1 au Pi 5 en passant par les Pi Zero et Pi Zero 2 W. Le backend change automatiquement selon le modèle détecté : lgpio sur Pi 5 et CM5, RPi.GPIO en fallback sur les modèles antérieurs.
Comment installer rpi-lgpio sur Pi 5 ?
Dans un environnement virtuel Python : pip install rpi-lgpio. Important : il faut désinstaller RPi.GPIO d’abord avec sudo apt remove python3-rpi.gpio ou pip uninstall RPi.GPIO, sinon les imports rentrent en conflit (les deux paquets définissent un module RPi.GPIO). Le code existant qui fait import RPi.GPIO as GPIO continue de fonctionner sans modification.
Peut-on mélanger gpiozero et RPi.GPIO dans le même script ?
Techniquement oui sur Pi antérieurs au 5 (gpiozero peut utiliser RPi.GPIO comme backend), mais c’est déconseillé : tu risques des conflits sur la gestion des broches et le cleanup. Choisis une seule bibliothèque par projet.
gpiozero gère-t-il les interruptions matérielles ?
Oui, via les callbacks when_pressed, when_released, when_motion, etc. En interne, ça repose sur les capacités de détection d’edge du backend (lgpio sur Pi 5), donc c’est aussi efficace qu’en RPi.GPIO direct. Le RP1 inclut un debouncing matériel sur les GPIO, exposé via lgpio.
pigpio fonctionne-t-il sur Pi 5 ?
Non. pigpio est explicitement hardcodé pour refuser de s’initialiser sur Pi 5 (issue #589 du repo joan2937/pigpio, confirmée par l’auteur en septembre 2023). Pour le PWM hardware sur Pi 5, utilise lgpio directement ou gpiozero avec le pin factory lgpio.