Au club scout de Saint-Herblain où j’anime des ateliers robotique un samedi sur deux, le projet « robot qui roule et évite un mur » est devenu le rite de passage. Deux heures, quarante euros de composants, une poignée de jeunes entre 12 et 16 ans, et à la fin de l’après-midi chaque groupe repart avec un robot qui avance sur le bitume de la cour jusqu’à détecter un mur à vingt centimètres, faire marche arrière, pivoter, repartir. C’est ce projet exact qu’on te propose de reproduire ici, détaillé assez pour que tu le fasses seul, chez toi, à ton rythme.
Ce que tu vas construire
Un robot à deux roues motrices, contrôlé par un Raspberry Pi, avec un capteur ultrason HC-SR04 fixé à l’avant. Le code Python pilote les moteurs via un driver L298N et lit la distance au mur en continu. Dès que la distance passe sous le seuil de vingt centimètres, le robot recule pendant une demi-seconde, tourne sur lui-même pendant un quart de seconde, puis repart droit devant. Quarante lignes de code, six fils à brancher (en plus de l’alimentation), et un résultat visible en deux heures.
Ce n’est pas un robot intelligent. C’est un robot qui réagit. La nuance est importante : il ne cartographie pas la pièce, il ne mémorise pas les obstacles, il ne planifie pas de trajectoire. Il se contente de répondre « je vois un mur, je tourne ». C’est précisément pour ça qu’il fonctionne comme premier projet : le code est lisible, le comportement est prévisible, et les erreurs se diagnostiquent en dix secondes.
Liste complète du matériel
Voici ce que j’achète pour chaque groupe de trois scouts. Tout est disponible chez Gotronic ou sur AliExpress avec un délai de deux à trois semaines. Les prix indiqués sont ceux de début 2026.
| Composant | Référence type | Prix indicatif | Remarque |
|---|---|---|---|
| Châssis 2 roues avec moteurs DC | Kit « Smart Car 2WD » | 8-12 € | Inclut 2 moteurs DC 3-6V, roues, roulette arrière, visserie |
| Module driver moteur L298N | L298N dual H-bridge | 3-5 € | Pilote les 2 moteurs simultanément |
| Capteur ultrason HC-SR04 | HC-SR04 | 1,50-3 € | Mesure distance 2 cm à 400 cm |
| Raspberry Pi 4 ou 5 (4 Go) | RPi 4B / RPi 5 | 45-60 € | Pi 4 occasion 35 € est très bien |
| Carte microSD 32 Go | SanDisk Extreme A1 | 8-12 € | Flashée avec Raspberry Pi OS Lite |
| Batterie porteurs | Support 4xAA (recommandé) ou LiPo 7,4V | 3-8 € | 4xAA = 6V, idéal pour moteurs 3-6V. La LiPo 7,4V en entrée du L298N donne 3,5 à 5V aux bornes du moteur après la chute de 2 à 4V dans le pont en H (Vce_sat des deux Darlington en série). Pour des moteurs 3-6V de kit, c’est suffisant mais sans marge. Les 4xAA à 6V en entrée donnent ~4V aux moteurs, résultat comparable. Préfère les piles AA si tu n’as pas d’expérience LiPo, tu évites le risque batterie. |
| Powerbank USB (alim Pi) | 5V 2A minimum, 5000mAh | 10-15 € | Alimente le Pi séparément des moteurs |
| Breadboard mini + fils dupont | MB-102 demi + 20 jumpers M-F | 3-5 € | Ou prototypage soudé si tu préfères le définitif |
| Résistances 330 Ω et 470 Ω (×1 chaque) | 1/4W métal | 0,10 € | Pour le pont diviseur du HC-SR04 |
Total : 80 à 120 euros avec Pi neuf, 35 à 60 euros si tu as déjà un Pi qui traîne. Le poste le plus cher est le Pi lui-même (45-60€ neuf). Les autres composants (kit châssis, L298N, HC-SR04, alimentation, breadboard, résistances) font ensemble entre 30 et 50€ selon fournisseur et qualité.
Ce qu’on n’achète pas (et pourquoi)
Pas de HAT moteur tout-en-un type Adafruit Motor HAT ou PiMotor. Ces cartes sont pratiques mais elles cachent le fonctionnement du pont en H, ce qui va à l’encontre du but pédagogique du projet. Le L298N à 4 euros fait le même travail, et tu comprends chaque fil que tu branches. C’est mon biais, je l’assume : mieux vaut trois fils de plus et savoir pourquoi le moteur tourne.
Principe du câblage
Le câblage se décompose en deux circuits indépendants qui partagent une seule chose : la masse (GND). Les confondre est la source de 80 % des problèmes en atelier.
Circuit 1 : alimentation + moteurs
La batterie (4xAA = 6V, ou LiPo 7,4V) alimente le L298N par ses bornes VIN et GND. Le L298N distribue ensuite le courant aux deux moteurs via ses sorties OUT1/OUT2 (moteur gauche) et OUT3/OUT4 (moteur droit). Ce circuit ne passe jamais par le Pi. Les moteurs DC tirent entre 200 mA et 1 A au démarrage, ce qui grillerait les GPIO du Pi (max 16 mA par broche) en quelques secondes.
Circuit 2 : contrôle (Pi → L298N + capteur)
Le Raspberry Pi envoie des signaux logiques (3,3V, quelques milliampères) au L298N pour lui dire quoi faire : avancer, reculer, tourner, accélérer. Le Pi lit aussi le capteur ultrason HC-SR04 pour mesurer la distance au mur. L’alimentation du Pi vient d’une source séparée (powerbank USB ou alim secteur), pas de la batterie des moteurs.
Tableau de câblage GPIO
| Composant | Broche composant | GPIO Pi | Remarque |
|---|---|---|---|
| L298N | IN1 | GPIO 17 | Direction moteur gauche |
| L298N | IN2 | GPIO 27 | Direction moteur gauche |
| L298N | IN3 | GPIO 22 | Direction moteur droit |
| L298N | IN4 | GPIO 23 | Direction moteur droit |
| L298N | ENA | GPIO 12 (PWM hardware) | Vitesse moteur gauche. GPIO 12 est une broche PWM matérielle (canal PWM0), plus stable que le PWM logiciel pour le contrôle moteur. |
| L298N | ENB | GPIO 13 (PWM hardware) | Vitesse moteur droit. GPIO 13 = canal PWM1. |
| HC-SR04 | TRIG | GPIO 24 | Déclencheur ultrason (3,3V OK) |
| HC-SR04 | ECHO | GPIO 25 via pont | Signal retour divisé de 5V → 3,3V |
| HC-SR04 | VCC | Pin 2 (5V Pi) | Alim capteur |
| Tous | GND | Pin 6 (GND Pi) | Masse commune obligatoire |
Le pont diviseur sur ECHO (obligatoire)
Le HC-SR04 fonctionne en 5V. Sa broche ECHO renvoie un signal à 5V. Le GPIO du Pi supporte au maximum 3,3V en entrée. Brancher ECHO directement sur le GPIO, c’est risquer d’endommager le SoC du Pi. La solution tient en deux résistances : un pont diviseur avec R1 = 330 Ω en série et R2 = 470 Ω vers la masse. Le calcul : 5V × 470 / (330 + 470) = 2,94V, valeur safe pour le GPIO.
Si tu utilises la bibliothèque gpiozero (ce qu’on fait dans ce tuto), elle gère le timing du signal ECHO automatiquement. Mais le pont diviseur matériel reste indispensable.
Installer le système
Flashe Raspberry Pi OS Lite (64-bit, sans bureau graphique) sur la carte microSD avec Raspberry Pi Imager. Active SSH et configure le Wi-Fi dans les paramètres avancés d’Imager, parce qu’on ne branchera jamais d’écran sur ce Pi. Le tutoriel d’installation détaillé de Claire couvre ça étape par étape si c’est la première fois.
Une fois le Pi démarré et connecté en SSH, installe les dépendances :
sudo apt update && sudo apt upgrade -y
sudo apt install python3-gpiozero python3-lgpio -y
gpiozero est la bibliothèque de contrôle GPIO qu’on va utiliser. Elle est préinstallée sur Raspberry Pi OS Desktop, mais pas sur Lite. lgpio est le backend matériel pour Pi 5 (et fonctionne aussi sur Pi 4).
Le code Python complet
Voilà le script en entier. Je l’explique section par section juste après.
#!/usr/bin/env python3
"""
robot_evite.py — Robot 2 roues évite-obstacles
Auteur : Rémi Favreau (rasrobot.com)
Matériel : Raspberry Pi + L298N + HC-SR04
# TODO: refacto cette fonction tourner_droite, elle est moche
# (version rapide pour atelier du 12 mars, jamais nettoyée)
"""
from gpiozero import Motor, DistanceSensor
from time import sleep
from signal import pause
import sys
# --- Configuration des GPIO ---
moteur_gauche = Motor(forward=17, backward=27, enable=12)
moteur_droit = Motor(forward=22, backward=23, enable=13)
capteur = DistanceSensor(echo=25, trigger=24, max_distance=2)
# --- Paramètres réglables ---
SEUIL_CM = 20 # distance déclenchement en cm
VITESSE = 0.7 # 0.0 à 1.0 (70 % par défaut)
DUREE_RECUL = 0.5 # secondes de marche arrière
DUREE_ROTATION = 0.4 # secondes de rotation sur place
def avancer():
moteur_gauche.forward(VITESSE)
moteur_droit.forward(VITESSE)
def reculer():
moteur_gauche.backward(VITESSE)
moteur_droit.backward(VITESSE)
def tourner_droite():
moteur_gauche.forward(VITESSE)
moteur_droit.backward(VITESSE)
def stop():
moteur_gauche.stop()
moteur_droit.stop()
# --- Boucle principale ---
print("Robot démarré. Ctrl+C pour arrêter.")
try:
while True:
distance_m = capteur.distance # en mètres
distance_cm = distance_m * 100
if distance_cm < SEUIL_CM:
print(f" Obstacle à {distance_cm:.0f} cm — recul + rotation")
stop()
sleep(0.1)
reculer()
sleep(DUREE_RECUL)
stop()
sleep(0.1)
tourner_droite()
sleep(DUREE_ROTATION)
stop()
sleep(0.1)
else:
avancer()
sleep(0.05) # 20 mesures par seconde
except KeyboardInterrupt:
print() # saut de ligne
print("Arrêt propre.")
stop()
sys.exit(0)
Ce que fait chaque partie
Les imports : gpiozero fait le travail dur (gestion des signaux GPIO, calcul de distance ultrason, PWM des moteurs). On n'utilise rien d'autre que la bibliothèque standard Python et gpiozero.
La configuration GPIO : Motor(forward=17, backward=27, enable=12) crée un objet moteur qui sait avancer (IN1 haut, IN2 bas) et reculer (l'inverse). Le paramètre enable active le contrôle de vitesse par PWM sur ENA/ENB du L298N. Si tu ne veux pas de contrôle de vitesse (moteurs toujours à fond), retire enable et laisse le jumper du L298N en place.
Le capteur : DistanceSensor(echo=25, trigger=24, max_distance=2) mesure la distance en mètres via le HC-SR04. Le max_distance=2 fixe la portée max à 2 mètres, ce qui est largement suffisant en intérieur et réduit le risque d'échos parasites.
La boucle : vingt fois par seconde (toutes les 50 ms), le script lit la distance. Si elle passe sous 20 cm, il stoppe, recule un demi-seconde, tourne un quart de seconde, puis repart. Le petit sleep(0.1) entre chaque changement de direction protège le L298N d'un changement de sens trop brutal (les bobines des moteurs n'aiment pas les inversions instantanées).
Le cleanup Ctrl+C : sans le bloc try/except KeyboardInterrupt, le script crasherait sans appeler stop() et les moteurs resteraient sous tension. Mauvais pour les batteries et potentiellement dangereux si le robot est sur une table.
Lancer le robot
Pose le robot sur le sol (pas sur une table, au cas où il fonce en avant au premier test), et depuis ta session SSH :
python3 robot_evite.py
Si tout est bien câblé, le robot démarre immédiatement. Tu devrais voir dans le terminal les messages de distance chaque fois qu'il détecte un obstacle.
Les trois pannes classiques du premier essai
Le robot ne bouge pas du tout. Vérifie d'abord que la batterie moteurs est chargée et connectée au L298N (LED rouge du L298N allumée). Puis vérifie que le jumper 5V du L298N est en place (ou qu'une alim logique est connectée). Enfin, vérifie que les fils IN1-IN4 vont bien aux bons GPIO.
Un moteur tourne à l'envers. C'est la panne la plus fréquente et la plus facile à corriger. Inverse physiquement les deux fils du moteur concerné sur les bornes OUT du L298N, ou permute forward et backward dans le code pour ce moteur.
Le capteur donne toujours la même distance (0 ou max). Trois causes dans l'ordre de fréquence : le pont diviseur est mal câblé, TRIG et ECHO sont inversés (je me souviens d'un gamin au club qui a passé deux heures sur ce bug avant qu'on comprenne), ou le capteur est défectueux (ça arrive sur les lots à 1 euro AliExpress). Teste le capteur seul avec un script minimal :
from gpiozero import DistanceSensor
from time import sleep
capteur = DistanceSensor(echo=25, trigger=24)
while True:
print(f"Distance : {capteur.distance * 100:.1f} cm")
sleep(0.5)
Passe la main devant le capteur : la distance affichée doit varier en temps réel. Si elle reste fixe, le problème est matériel. Si elle varie, le problème est dans le câblage moteur ou le reste du code principal.
Ajustements après le premier test
Les réglages qui changent le comportement du robot :
SEUIL_CM = 20: trop bas et le robot frôle les murs avant de réagir. Trop haut et il tourne trop souvent. En intérieur, 15 à 25 cm marchent bien.VITESSE = 0.7: 70 % est un bon compromis. À 100 % le robot est vif mais les virages sont brusques. À 40 % il est mou mais plus précis dans les espaces étroits.DUREE_RECUL = 0.5: raccourcir si le robot recule trop loin. Allonger si la roulette arrière accroche et empêche le pivotement.DUREE_ROTATION = 0.4: raccourcir pour des virages serrés (45°), allonger pour des demi-tours complets (180° prend environ 0.8 à 1 seconde selon la surface et le poids).sleep(0.05)en fin de boucle : si le robot réagit trop lentement aux murs, descends à 0.03. Si le CPU chauffe, monte à 0.1.
Sécurité et bonnes pratiques
Quelques trucs que j'ai appris à la dure en atelier.
- Ne jamais laisser le robot sur une table sans surveillance. Il suffit d'un capteur mal orienté pour qu'il fonce dans le vide. Tester au sol, toujours.
- Batteries LiPo : ne pas décharger sous 3,3 V par cellule (7,4V LiPo = ne pas descendre sous 6,6V total). En dessous, la cellule se dégrade irréversiblement. Si tu débutes, les piles AA sont plus pardonnantes.
- Couper l'alimentation moteurs en premier quand tu veux modifier le câblage. Le Pi peut rester allumé, mais les moteurs sous tension + des fils qui bougent = court-circuit possible sur le L298N.
- Pas vraiment une règle mais un réflexe : j'ai toujours un multimètre branché en parallèle sur la batterie moteurs pendant les tests. Quand la tension passe sous 6V sur un pack 4xAA (ou sous 6,6V sur une LiPo 2S), je coupe. Les batteries en bas de décharge ont un comportement bizarre qu'on prend parfois pour un bug logiciel.
Questions fréquentes
Peut-on faire ce robot avec un Arduino à la place du Raspberry Pi ?
Oui, et c'est même souvent plus simple pour ce projet précis. L'Arduino est temps réel, consomme 10 fois moins, et n'a pas besoin d'OS à booter. Les seuls gains du Raspberry Pi ici sont l'option future d'ajouter une caméra ou du Wi-Fi. Pour un robot évite-obstacles basique sans extensions, un Arduino Nano fait l'affaire pour 10 € au lieu de 60 €.
Quelle autonomie de batterie peut-on attendre ?
Avec 4xAA NiMH de 2 500 mAh en alimentation moteurs et un powerbank 5 000 mAh pour le Pi : compter 2 à 3 heures en roulage continu pour le Pi 4, 1h30 à 2h pour le Pi 5 (qui consomme plus). Les AA s'épuisent généralement avant le powerbank. Avec une LiPo 7,4V 2 200 mAh côté moteurs, l'autonomie double mais la complexité aussi.
Le Raspberry Pi Zero 2W fonctionne-t-il pour ce projet ?
Oui, avec des réserves. Le Zero 2W est moins puissant mais suffit largement pour le code Python du tuto (consommation CPU négligeable). Deux limitations : il faut souder des pin-headers GPIO (le Zero 2W est livré sans), et il a moins de ports USB pour brancher une manette ou une caméra. Pour un robot minimaliste embarqué où le Pi doit être discret, le Zero 2W est un excellent choix.
Quelle différence entre L298N et TB6612FNG ou DRV8833 ?
Le L298N est le driver historique (années 1990, transistors bipolaires). Sa chute de tension de 2 à 4V gaspille de l'énergie en chaleur et réduit la tension disponible pour les moteurs. Le TB6612FNG (Toshiba) et le DRV8833 (Texas Instruments) sont basés sur MOSFET : chute ~0,3V, rendement 90 % contre 70 % pour le L298N. Ils coûtent 2 à 3 € (comparables) mais il faut les souder soi-même (pas de bornier à vis). Pour apprendre : L298N. Pour la version finale d'un projet qui doit durer : DRV8833 ou TB6612FNG.
Comment ajouter un deuxième capteur ultrason latéral ?
Quatre broches GPIO libres suffisent : un TRIG et un ECHO (via pont diviseur 330/470 Ω) par capteur. Côté code, on ajoute un deuxième objet DistanceSensor(echo=X, trigger=Y) et on lit les deux dans la boucle principale. Logique simple : si l'obstacle de face est proche, on tourne vers le côté le plus dégagé. Ça corrige le défaut du tuto actuel (le robot tourne toujours à droite).
Puis-je alimenter les moteurs depuis le même powerbank que le Pi ?
Techniquement oui via la sortie 5V du L298N, mais je le déconseille. Les pics de courant au démarrage des moteurs font chuter la tension du powerbank, ce qui peut faire rebooter le Pi. Mieux : powerbank dédié au Pi, pack de piles AA ou LiPo dédié aux moteurs. C'est le coût de 3-5 € de support AA pour éviter la moitié des problèmes de fiabilité que je vois en atelier.
Aller plus loin
Le robot qui évite un mur, c'est la version zéro. Une fois que ça roule, voilà quatre directions dans lesquelles j'ai vu les jeunes du club continuer naturellement.
- Deux capteurs latéraux : ajouter un HC-SR04 à gauche et un à droite pour que le robot choisisse le meilleur côté au lieu de toujours tourner à droite. Coût : 3 euros, 4 lignes de code en plus.
- Pilotage Wi-Fi : un serveur Flask sur le Pi expose des routes
/avancer,/reculer,/gauche,/droite,/stop. On pilote depuis le navigateur du téléphone. L'atelier « télécommande Wi-Fi » prend environ trois heures. - Suivi de ligne : remplacer le capteur ultrason par trois capteurs IR TCRT5000 en barre sous le châssis, et faire suivre une ligne noire au sol. C'est le projet suivant que les jeunes du club préfèrent.
- Caméra et vision : coller une Pi Camera v3 et utiliser OpenCV pour détecter un objet coloré précis (une balle rouge, par exemple). Nettement plus complexe, mais le résultat impressionne les parents lors des démonstrations.
Le guide complet « construire son premier robot DIY » détaille ces extensions et les concepts théoriques qui vont avec (PID, odométrie, cinématique). Si tu veux d'abord comprendre les bases des capteurs avant de modifier le projet, l'article sur les 5 capteurs indispensables en robotique est un bon point de départ.
Si ton robot roule et que tu veux partager le résultat ou poser une question de câblage, passe par la page contact. Les photos de robots qui marchent, même (surtout) imparfaits, sont exactement ce qu'on aime voir ici.