Arduino Robottank Gestuurd met PS2 Draadloze Joystick
Onderdelen en benodigdheden
| Arduino UNO | 1 |
| SparkFun Dual H-Bridge motor driver L298N | 1 |
| DIY robotieke tank kit (chassis, motoren, ketten, schroeven) | 1 |
| Sony PS2 draadloze controller | 1 |
| 18650 3.7V accu's (3 stuks in serie) | 3 |
| 3S 18650 accu-houder | 1 |
| 18650 accu-lader | 1 |
| Jumper wires (male-female, male-male) | 1 set |
| Type-B USB-kabel | 1 |
| Soldeerbout & soldeerdraad | 1 |
| EVA schuimplaat (isolatie) | 1 |
| Dubbelzijdig tape | 1 |
| Schaar | 1 |
Apps en online diensten
- Arduino IDE
Over dit project
In deze tutorial bouw je een robotische tank die je bestuurt met een draadloze PlayStation 2 (PS2) joystick. Een Arduino Uno fungeert als hoofdcontroller: het ontvangt commando's van de ontvanger en regelt de motordreven. Hetzelfde principe werkt op andere boards (NodeMCU, FireBeetle, etc.) en voor andere robotmodellen.




Stap 1: Hulpmiddelen en materialen
Zie bovenstaande tabel. De tank-kit bevat alle benodigde schroeven, moeren en gereedschap (inbussleutels, schroevendraaier) – ideaal voor beginners. Let op: het chassis is aluminium, dus plaats een laagje EVA-schuim tussen printplaten en frame om kortsluiting te voorkomen.



Stap 2: De robot monteren
Volg de handleiding van de kit (vaak in het Chinees). Er zijn voldoende reserveonderdelen. De montage is straight-forward: motoren, tandwielen, ketten, batterijhouder achterop. Zorg dat de printplaten op het schuim bevestigd worden met dubbelzijdig tape.
Stap 3: Schakeling bedraden

Drie 18650 accu's in serie leveren 11,1 V voor de 12 V DC-motoren. De L298N H-bridge versterkt de 5 V Arduino-signalen naar de motorspanning en stelt draairichting in.

Pinout Arduino Uno:
- D3 → H-Bridge ENA
- D5 → IN1, D4 → IN2 (motor A)
- D8 → IN3, D7 → IN4 (motor B)
- D6 → ENB
- 5V → H-Bridge 5V, GND → H-Bridge GND
- D10 → PS2 ontvanger pin 6 (attention)
- D11 → PS2 pin 2 (command)
- D12 → PS2 pin 1 (data)
- D13 → PS2 pin 7 (clock)
- 3.3V → PS2 pin 5, GND → PS2 pin 4
H-Bridge naar motoren:
- OUT1/OUT2 → rechter motor (±)
- OUT3/OUT4 → linker motor (±)
- 12V → batterij +, GND → batterij -


Stap 4: Arduino IDE instellen
- Download en installeer de nieuwste Arduino IDE van arduino.cc.
- Installeer de PS2X library van Bill Porter: GitHub. Download, unzip, kopieer naar
librariesmap.

Stap 5: PS2X bibliotheek uitgelegd

De PS2-controller heeft 20 digitale knoppen en 2 analoge sticks. De PS2X-bibliotheek biedt een PS2X klasse met methodes:
config_gamepad(clock, command, attention, data, pressures?, rumble?)– initialisatie, retourneert foutcode.read_gamepad(vibrate, rumble)– moet elke loop aangeroepen worden.Button(knop)– leest digitale knop (true/false). Knopnamen:PSB_PAD_UP,PSB_PAD_DOWN,PSB_PAD_LEFT,PSB_PAD_RIGHT,PSB_GREEN(driehoek),PSB_RED(cirkel),PSB_BLUE(kruis),PSB_PINK(vierkant),PSB_L1,PSB_R1,PSB_L2,PSB_R2,PSB_L3,PSB_R3,PSB_SELECT,PSB_START.Analog(stick_as)– leest analoge waarde (0-255). Assen:PSS_LX,PSS_LY,PSS_RX,PSS_RY.
Stap 6: Sketch #1 – D-pad knoppen (basale besturing)

Elke D-pad knop stuurt een basisbeweging: vooruit, achteruit, links draaien, rechts draaien. Motoren draaien op vaste snelheid (PWM 1023).

Stap 7: Sketch #2 – Analog stick + L2/R2 triggers (race-stijl)

Linker stick X-as stuurt (links/rechts), R2 = gas vooruit, L2 = achteruit. Snelheid wordt gemoduleerd met stick-afwijking.

Stap 8: Sketch #3 – Twee analoge sticks (differentiële sturing)

Linker stick Y-as = linker ketten, rechter stick Y-as = rechter ketten. Voelt als een echte tank. Doodzone ±50 om trillen te voorkomen.

Stap 9: Sketch #4 – Enkel linker analoge stick (geavanceerd mix)

Één stick regelt zowel snelheid als richting via differentiële mix (arcade-stijl). Code gebaseerd op ImpulseAdventure.

Stap 10: Afsluitende overwegingen
Veel plezier met bouwen! Ondersteun mijn toekomstige projecten met een kleine Bitcoin-donatie: 1FiWFYSjRaL7sLdr5wr6h86QkMA6pQxkXJ.

Code
Sketch #1 – D-pad
// PS2 Tank by Igor Fonseca @2019
#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");
type = ps2x.readType();
if(type==1) Serial.println("DualShock Controller Found");
else if(type==2) Serial.println("GuitarHero Controller Found");
else Serial.println("Unknown Controller type");
}
void loop() {
if(error==1) return;
ps2x.read_gamepad(false, vibrate);
if(ps2x.Button(PSB_PAD_UP)) { // vooruit
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)) { // rechts
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)) { // links
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)) { // achteruit
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 – Analog stick + triggers
// PS2 Tank by Igor Fonseca @2019
#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
int motor_right_speed = 0, motor_left_speed = 0;
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");
type = ps2x.readType();
if(type==1) Serial.println("DualShock Controller Found");
else if(type==2) Serial.println("GuitarHero Controller Found");
else Serial.println("Unknown Controller type");
}
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, motor_left_speed = 1023;
if (nJoyL < 0) motor_right_speed += nJoyL;
if (nJoyL > 0) motor_left_speed -= nJoyL;
if(ps2x.Button(PSB_R2)) { // vooruit
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)) { // achteruit
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 – Twee analoge sticks
// PS2 Tank by Igor Fonseca @2019
#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");
type = ps2x.readType();
if(type==1) Serial.println("DualShock Controller Found");
else if(type==2) Serial.println("GuitarHero Controller Found");
else Serial.println("Unknown Controller type");
}
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);
// Motor A (rechts)
if(nJoyR>50) { digitalWrite(MOTORA_1,HIGH); digitalWrite(MOTORA_2,LOW); analogWrite(ENA,1023); }
else if(nJoyR<-50) { digitalWrite(MOTORA_1,LOW); digitalWrite(MOTORA_2,HIGH); analogWrite(ENA,1023); }
else analogWrite(ENA,0);
// Motor B (links)
if(nJoyL>50) { digitalWrite(MOTORB_1,HIGH); digitalWrite(MOTORB_2,LOW); analogWrite(ENB,1023); }
else if(nJoyL<-50) { digitalWrite(MOTORB_1,LOW); digitalWrite(MOTORB_2,HIGH); analogWrite(ENB,1023); }
else analogWrite(ENB,0);
delay(50);
}
Sketch #4 – Enkel linker stick (arcade mix)
// PS2 Tank by Igor Fonseca @2019
#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
int motor_right_speed = 0, motor_left_speed = 0;
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");
type = ps2x.readType();
if(type==1) Serial.println("DualShock Controller Found");
else if(type==2) Serial.println("GuitarHero Controller Found");
else Serial.println("Unknown Controller type");
}
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);
float nMotPremixL, nMotPremixR;
if (nJoyY >= 0) {
nMotPremixL = (nJoyX>=0)? 1023.0 : (1023.0 + nJoyX);
nMotPremixR = (nJoyX>=0)? (1023.0 - nJoyX) : 1023.0;
} else {
nMotPremixL = (nJoyX>=0)? (1023.0 - nJoyX) : 1023.0;
nMotPremixR = (nJoyX>=0)? 1023.0 : (1023.0 + nJoyX);
}
nMotPremixL = nMotPremixL * nJoyY/1023.0;
nMotPremixR = nMotPremixR * nJoyY/1023.0;
int nPivSpeed = nJoyX;
float fPivScale = (abs(nJoyY)>1023.0)? 0.0 : (1.0 - abs(nJoyY)/1023.0);
int nMotMixL = (1.0-fPivScale)*nMotPremixL + fPivScale*( nPivSpeed);
int nMotMixR = (1.0-fPivScale)*nMotPremixR + fPivScale*(-nPivSpeed);
motor_left_speed = nMotMixL; motor_right_speed = nMotMixR;
if (motor_right_speed > 50) { digitalWrite(MOTORB_1,HIGH); digitalWrite(MOTORB_2,LOW); }
else if (motor_right_speed < -50) { digitalWrite(MOTORB_1,LOW); digitalWrite(MOTORB_2,HIGH); }
else { digitalWrite(MOTORB_1,LOW); digitalWrite(MOTORB_2,LOW); }
if (motor_left_speed > 50) { digitalWrite(MOTORA_1,LOW); digitalWrite(MOTORA_2,HIGH); }
else if (motor_left_speed < -50) { digitalWrite(MOTORA_1,HIGH); digitalWrite(MOTORA_2,LOW); }
else { digitalWrite(MOTORA_1,LOW); digitalWrite(MOTORA_2,LOW); }
analogWrite(ENA, abs(motor_left_speed));
analogWrite(ENB, abs(motor_right_speed));
delay(50);
}
Schema's


Productieproces
- Bouw een Internet-gecontroleerde Video-streamende Robot met Arduino & Raspberry Pi
- Unopad: Naadloze Arduino MIDI-controller voor Ableton Live
- Servo-gestuurde obstakelvermijdende robot: Bouw met Arduino & HC-SR04
- Bestuur Je Roomba Create 2 Met Arduino En Android: Stapsgewijze Handleiding
- Arduino-gebaseerde 6-DoF Robotarm Gestoeerd met Wii Nunchuk
- Twee Stappenmotors Sturen met Arduino Nano & Joystick – Simpele Tutorial
- Bouw een Aangepaste Arduino Joystick Stuurwiel voor Gaming
- Arduino FM Radio met RDA5807M – RDS, Presets & OLED Display
- Arduino robotarm besturen via speciale Android-app
- Arduino Nano eetrobot bouwen: stap-voor-stap handleiding
- Bouw een 4-Wiel Arduino Robot Bestuurd via Dabble App