Robot chenillé Arduino piloté par manette PS2 sans fil
Composants et fournitures
| Arduino UNO | × | 1 |
| Double pont en H L298 (SparkFun) | × | 1 |
| Kit robot chenillé DIY | × | 1 |
| Manette sans fil Sony PS2 | × | 1 |
Applications et services en ligne
- Arduino IDE
À propos du projet
Dans ce tutoriel, je vous montre comment utiliser une manette PlayStation 2 (PS2) sans fil pour piloter un robot chenillé. Une carte Arduino Uno est utilisée comme contrôleur principal. Elle reçoit les commandes de la manette et règle la vitesse des moteurs. D'autres cartes de développement (NodeMCU, Firebeetle, etc.) peuvent également être utilisées, et les principes présentés s'appliquent à d'autres modèles de robots.
J'ai précédemment conçu un robot chenillé contrôlé via Blynk. Il se connecte au Wi-Fi et reçoit les commandes du serveur Blynk. Un smartphone avec l'application Blynk servait de télécommande, avec différentes méthodes de contrôle : boutons poussoirs, barres coulissantes et même l'accéléromètre du téléphone. Plus de détails ici : projet Blynk
J'ai aussi expérimenté le contrôle vocal, utile pour piloter un robot sans les mains ou le rendre accessible aux personnes à mobilité réduite. Un fauteuil roulant robotisé à commande vocale est envisageable. J'ai utilisé un kit robotique DIY avec Adafruit.io, IFTTT et Arduino IDE. Instructions complètes : projet commande vocale
Vous pouvez utiliser différents kits ou concevoir vos propres robots avec des matériaux simples, sans imprimante 3D ni découpe laser. Exemple : robot FPV Wi-Fi

Étape 1 : Outils et matériaux

Outils utilisés :
- Fer à souder et fil - Les moteurs DC ont déjà des fils soudés, mais ils peuvent casser.
- Feuille de mousse EVA (ou autre matériau non conducteur) - Le châssis est en aluminium, la mousse évite les courts-circuits.
- Ruban double face - Pour fixer la mousse et le module L298.
- Ciseaux - Pour découper la mousse.
Pièces matérielles :
- Carte de développement Arduino Uno - Contrôleur principal, facile à programmer.
- Module double pont en H L298N - Amplifie les signaux 3,3V/5V vers 12V pour les moteurs.
- Kit châssis robot chenillé DIY - Inclut moteurs DC, engrenages, chenilles, boulons, écrous et outils de montage.
- Télécommande sans fil PS2 - Envoie des commandes sans fil vers un récepteur interfacé en série.
- 3 accus 18650 3,7V - Alimentation 11,1V (3 × 3,7V) pour moteurs 12V.
- Support 3S pour accus 18650 - Maintient 3 accus en série, se fixe à l'arrière du char.
- Chargeur pour accus 18650
- Fils de connexion (jumpers) - 6 mâle-femelle pour signaux, 2 mâle-mâle pour 5V et GND.
- Câble USB type-B - Pour téléverser le code.
Étape 2 : Assemblage du robot
La première partie consistait à assembler la structure du robot. J'ai précédemment conçu mes propres structures avec des matériaux accessibles (sans outils complexes). Voir : projet structure DIY
J'ai ensuite testé un kit robotique acheté en ligne : lien vers le kit. C'est une bonne option ! Je l'ai utilisé dans deux autres tutoriels. L'assemblage semblait complexe au vu du nombre de pièces, mais le kit m'a surpris : bonne qualité, pièces de rechange incluses (pratique quand on perd des vis !). Tous les outils nécessaires sont fournis (clés Allen, tournevis), idéal pour débutants.
Point négatif : documentation insuffisante. Le manuel (fichier tableur en chinois) n'est pas convivial, peu de tutoriels en ligne. J'ai donc documenté l'assemblage en vidéo. Attention : le châssis en aluminium peut causer des courts-circuits si les broches des circuits touchent la structure.

Étape 3 : Câblage du circuit

Un pack de 3 accus 18650 (11,1V) est installé à l'arrière. Le L298N reçoit les signaux 5V de l'Arduino et fournit la tension nécessaire aux moteurs, permettant la rotation dans les deux sens.

Connexions Arduino Uno :
- Pin 3 (numérique) → L298N ENA
- Pin 5 → L298N IN1
- Pin 4 → L298N IN2
- Pin 8 → L298N IN3
- Pin 7 → L298N IN4
- Pin 6 → L298N ENB
- 5V → L298N 5V
- GND → L298N GND
- Pin 10 → Récepteur PS2 pin 6
- Pin 11 → Récepteur PS2 pin 2
- Pin 12 → Récepteur PS2 pin 1
- Pin 13 → Récepteur PS2 pin 7
- 3,3V → Récepteur PS2 pin 5
- GND → Récepteur PS2 pin 4
Connexions L298N :
- ENA → Arduino pin 3
- IN1 → Arduino pin 5
- IN2 → Arduino pin 4
- IN3 → Arduino pin 8
- IN4 → Arduino pin 7
- ENB → Arduino pin 6
- 5V → Arduino 5V
- GND → Arduino GND
- GND → Fil négatif pack batterie
- 12V → Fil positif pack batterie
- OUT1 → Moteur droit fil négatif
- OUT2 → Moteur droit fil positif
- OUT3 → Moteur gauche fil positif
- OUT4 → Moteur gauche fil négatif
Récepteur PS2 :
- Pin 1 (data) → Arduino pin 12
- Pin 2 (command) → Arduino pin 11
- Pin 4 (ground) → Arduino GND
- Pin 5 (power) → Arduino 3,3V
- Pin 6 (attention) → Arduino pin 10
- Pin 7 (clock) → Arduino pin 13
Étape 4 : Configuration Arduino IDE
- Télécharger et installer Arduino IDE (dernière version) depuis arduino.cc
- Ajouter la bibliothèque PS2X : télécharger depuis GitHub, décompresser et copier dans le dossier libraries d'Arduino IDE.
Étape 5 : Bibliothèque PS2X expliquée
La manette PS2 sans fil offre 20 boutons numériques et 2 joysticks analogiques. J'utilise la bibliothèque PS2X de Bill Porter (GitHub).
Elle définit une classe PS2X avec méthodes pour lire entrées analogiques et numériques :
PS2X ps2x; // Création de l'objet
error = ps2x.config_gamepad(clock, command, attention, data, pressure?, rumble?); // Configuration des pins
Lecture boutons numériques : ps2x.Button(bouton)
- Directionnels : PSB_PAD_UP, PSB_PAD_DOWN, PSB_PAD_LEFT, PSB_PAD_RIGHT
- Action : PSB_GREEN/TRIANGLE, PSB_RED/CIRCLE, PSB_BLUE/CROSS, PSB_PINK/SQUARE
- Gâchettes : PSB_L1, PSB_R1, PSB_L2, PSB_R2
- Joysticks (bouton poussoir) : PSB_L3, PSB_R3
- Menu : PSB_SELECT, PSB_START
Lecture joysticks analogiques (0-255) : ps2x.Analog(axe)
- PSS_LY = axe Y joystick gauche
- PSS_LX = axe X joystick gauche
- PSS_RY = axe Y joystick droit
- PSS_RX = axe X joystick droit
Étape 6 : Sketch #1 - Boutons directionnels (D-pad)
Émulation des contrôles de jeux rétro (SEGA, SNES). Boutons = mouvements de base : avancer, reculer, tourner gauche/droite. Sortie binaire = moteurs à vitesse fixe.
- PSB_PAD_UP = avancer
- PSB_PAD_DOWN = reculer
- PSB_PAD_LEFT = tourner gauche
- PSB_PAD_RIGHT = tourner droite

Code expliqué
Configuration des pins du pont en H, initialisation série, configuration ps2x avec gestion d'erreurs. Dans loop() : lecture des boutons D-pad et commande des moteurs via pins numériques et PWM (ENA/ENB).
Étape 7 : Sketch #2 - Joystick analogique gauche + boutons L2/R2
Configuration style jeux de course (Mario Kart) : joystick gauche pour direction, R2 accélération, L2 marche arrière/frein.

Lecture position X joystick gauche (0-255 → -1023 à 1023), ajouté/soustracté à la vitesse de chaque moteur pour créer différentiel de vitesse. R2 = avance, L2 = inverse direction, aucun bouton = moteurs arrêtés.
Étape 8 : Sketch #3 - Deux joysticks analogiques (commande différentielle)
Mon mode préféré : chaque joystick contrôle une chenille. Joystick gauche = chenille gauche, droit = chenille droite. Lecture axes Y des deux joysticks, zone morte ±50 pour désactiver les moteurs au centre.

Étape 9 : Sketch #4 - Joystick gauche seul
Contrôle optimal en ressources (boutons libres pour autres actions), mais plus difficile à maîtriser. Vitesse de chaque chenille selon axes X et Y. Code dérivé de : tutoriel direction différentielle

Étape 10 : Considérations finales
J'ai mis beaucoup d'efforts pour rendre ce projet clair et éducatif. Si vous l'aimez, likez et partagez ! Vos soutiens sont précieux.
Autres tutoriels robotiques :
Codes sources
Sketch #1 - Boutons D-pad
// PS2 Tank par Igor Fonseca @2019
// Contrôle robot chenillé avec manette PS2, boutons D-pad
#include <PS2X_lib.h>
#define ENA 3
#define MOTORA_1 4
#define MOTORA_2 5
#define MOTORB_1 8
#define MOTORB_2 7
#define ENB 6
PS2X ps2x;
int error = 0;
byte type = 0;
byte vibrate = 0;
void setup() {
pinMode(ENA, OUTPUT); pinMode(MOTORA_1, OUTPUT); pinMode(MOTORA_2, OUTPUT);
pinMode(ENB, OUTPUT); pinMode(MOTORB_1, OUTPUT); pinMode(MOTORB_2, OUTPUT);
digitalWrite(ENA, 0); digitalWrite(ENB, 0);
Serial.begin(57600);
error = ps2x.config_gamepad(13, 11, 10, 12, true, true);
if (error == 0) Serial.println("Found Controller, configured successful");
else if (error == 1) Serial.println("No controller found, check wiring or reset the Arduino");
else if (error == 2) Serial.println("Controller found but not accepting commands");
else if (error == 3) Serial.println("Controller refusing to enter Pressures mode, may not support it.");
type = ps2x.readType();
switch (type) {
case 0: Serial.println("Unknown Controller type"); break;
case 1: Serial.println("DualShock Controller Found"); break;
case 2: Serial.println("GuitarHero Controller Found"); break;
}
}
void loop() {
if (error == 1) return;
ps2x.read_gamepad(false, vibrate);
if (ps2x.Button(PSB_PAD_UP)) {
digitalWrite(MOTORA_1, LOW); digitalWrite(MOTORA_2, HIGH);
digitalWrite(MOTORB_1, HIGH); digitalWrite(MOTORB_2, LOW);
analogWrite(ENB, 1023); analogWrite(ENA, 1023);
Serial.println("Move forward");
}
if (ps2x.Button(PSB_PAD_RIGHT)) {
digitalWrite(MOTORA_1, HIGH); digitalWrite(MOTORA_2, LOW);
digitalWrite(MOTORB_1, HIGH); digitalWrite(MOTORB_2, LOW);
analogWrite(ENB, 1023); analogWrite(ENA, 1023);
Serial.println("Turn right");
}
if (ps2x.Button(PSB_PAD_LEFT)) {
digitalWrite(MOTORA_1, LOW); digitalWrite(MOTORA_2, HIGH);
digitalWrite(MOTORB_1, LOW); digitalWrite(MOTORB_2, HIGH);
analogWrite(ENB, 1023); analogWrite(ENA, 1023);
Serial.println("Turn left");
}
if (ps2x.Button(PSB_PAD_DOWN)) {
digitalWrite(MOTORA_1, HIGH); digitalWrite(MOTORA_2, LOW);
digitalWrite(MOTORB_1, LOW); digitalWrite(MOTORB_2, HIGH);
analogWrite(ENB, 1023); analogWrite(ENA, 1023);
Serial.println("Move back");
}
if (!ps2x.Button(PSB_PAD_DOWN) && !ps2x.Button(PSB_PAD_UP) && !ps2x.Button(PSB_PAD_RIGHT) && !ps2x.Button(PSB_PAD_LEFT)) {
analogWrite(ENB, 0); analogWrite(ENA, 0);
}
delay(50);
}
Sketch #2 - Joystick analogique + L2/R2
// ... même configuration ...
int motor_right_speed = 0;
int motor_left_speed = 0;
// ... setup identique ...
void loop() {
if (error == 1) return;
ps2x.read_gamepad(false, vibrate);
int nJoyL = ps2x.Analog(PSS_LX);
nJoyL = map(nJoyL, 0, 255, 1023, -1023);
int motor_right_speed = 1023;
int motor_left_speed = 1023;
if (nJoyL < 0) motor_right_speed += nJoyL;
if (nJoyL > 0) motor_left_speed -= nJoyL;
if (ps2x.Button(PSB_R2)) {
digitalWrite(MOTORA_1, LOW); digitalWrite(MOTORA_2, HIGH);
digitalWrite(MOTORB_1, HIGH); digitalWrite(MOTORB_2, LOW);
analogWrite(ENA, motor_right_speed); analogWrite(ENB, motor_left_speed);
}
if (ps2x.Button(PSB_L2)) {
digitalWrite(MOTORA_1, HIGH); digitalWrite(MOTORA_2, LOW);
digitalWrite(MOTORB_1, LOW); digitalWrite(MOTORB_2, HIGH);
analogWrite(ENA, motor_right_speed); analogWrite(ENB, motor_left_speed);
}
if (!ps2x.Button(PSB_L2) && !ps2x.Button(PSB_R2)) {
analogWrite(ENA, 0); analogWrite(ENB, 0);
}
delay(50);
}
Sketch #3 - Double joystick (commande différentielle)
// ... même configuration ...
void loop() {
if (error == 1) return;
ps2x.read_gamepad(false, vibrate);
int nJoyL = ps2x.Analog(PSS_LY);
int nJoyR = ps2x.Analog(PSS_RY);
nJoyL = map(nJoyL, 0, 255, 1023, -1023);
nJoyR = map(nJoyR, 0, 255, -1023, 1023);
if (nJoyR > 50) { digitalWrite(MOTORA_1, HIGH); digitalWrite(MOTORA_2, LOW); analogWrite(ENA, 1023); }
if (nJoyR < -50) { digitalWrite(MOTORA_1, LOW); digitalWrite(MOTORA_2, HIGH); analogWrite(ENA, 1023); }
if (abs(nJoyR) < 50) analogWrite(ENA, 0);
if (nJoyL > 50) { digitalWrite(MOTORB_1, HIGH); digitalWrite(MOTORB_2, LOW); analogWrite(ENB, 1023); }
if (nJoyL < -50) { digitalWrite(MOTORB_1, LOW); digitalWrite(MOTORB_2, HIGH); analogWrite(ENB, 1023); }
if (abs(nJoyL) < 50) analogWrite(ENB, 0);
delay(50);
}
Sketch #4 - Joystick gauche seul (mélange drive/pivot)
// ... même configuration ...
void loop() {
if (error == 1) return;
ps2x.read_gamepad(false, vibrate);
int nJoyX = ps2x.Analog(PSS_LX);
int nJoyY = ps2x.Analog(PSS_LY);
nJoyX = map(nJoyX, 0, 255, -1023, 1023);
nJoyY = map(nJoyY, 0, 255, 1023, -1023);
// Algorithme de mélange drive/pivot pour direction différentielle
// ... calculs nMotMixL, nMotMixR ...
analogWrite(ENA, abs(motor_left_speed));
analogWrite(ENB, abs(motor_right_speed));
delay(50);
}
Schémas


Processus de fabrication
- Construire un robot piloté par Internet avec streaming vidéo Arduino & Raspberry Pi
- Unopad : contrôleur MIDI Arduino fluide pour Ableton Live
- Robot Évitement d'Obstacles Piloté par Servomoteur : Construction avec Arduino et HC-SR04
- Contrôlez votre Roomba Create 2 avec Arduino et Android – Guide pas à pas
- Bras robotique 6 DoF piloté par Nunchuk Wii – Kit Arduino Mega
- Contrôler 2 moteurs pas-à-pas avec Arduino Nano et joystick – Tutoriel Visuino
- Volant Joystick Arduino Personnalisé pour Jeux Vidéo
- Créer un Robot de Combat Télécommandé avec une Manette PS2
- Contrôlez votre bras robot Arduino via une application Android dédiée