Interfacing Wireless PS2 Controller with Arduino
Hi, in this tutorial we’ll try to interface a PS2 wireless controller with Arduino UNO board, it is very interesting since all the controller’s buttons would be inputs for the Arduino board and not only that but also wireless, using 2.4GHz Radio Frequency communication protocol, which can be very useful to control robots, vehicles, servos…

I bought this controller with A servo dedicated board for 30 USD, you can get the controller/Receiver much cheaper, but don’t forget that these cheap devices have some problems (you can see it in the video), the sensitivity is not that good comparing it with the original controller, also you may experience some push button problems…
You can learn a lot about this controller visiting this website: billporter.info
Wiring:
Considering from which side you are observing this is the order I followed, the pins #3 and #8 don’t have a connector at all, also we’re not using the pin #9.


Wiring with the usual LCD i2c screen, I used with the code I made.
Libraries:
Here you can download the libraries required for the devices, The LCD i2c library is optional and only used if you are using one:
- Download PS2X Library. Don’t forget that the directory named “PS2X_lib” must be present in the libraries directory
- Download LCD i2c Library
Codes:
You can download the code using LCD here, or check below
Code 1: Example from the library
The first code you’ll find it in the library, it shows different functions you can use such as reading the analog stick values, detect if a button is pressed, released or being held…., also it detects which type of controller you are using or showing you an error if there is one.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
#include <PS2X_lib.h> //for v1.6 PS2X ps2x; // create PS2 Controller Class //right now, the library does NOT support hot pluggable controllers, meaning //you must always either restart your Arduino after you conect the controller, //or call config_gamepad(pins) again after connecting the controller. int error = 0; byte type = 0; byte vibrate = 0; void setup(){ Serial.begin(57600); //CHANGES for v1.6 HERE!!! **************PAY ATTENTION************* error = ps2x.config_gamepad(13,11,10,12, true, true); //setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error if(error == 0){ Serial.println("Found Controller, configured successful"); Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;"); Serial.println("holding L1 or R1 will print out the analog stick values."); } else if(error == 1) Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit http://www.billporter.info for troubleshooting tips"); else if(error == 2) Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit http://www.billporter.info for troubleshooting tips"); else if(error == 3) Serial.println("Controller refusing to enter Pressures mode, may not support it. "); //Serial.print(ps2x.Analog(1), HEX); 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(){ /* You must Read Gamepad to get new values Read GamePad and set vibration values ps2x.read_gamepad(small motor on/off, larger motor strenght from 0-255) if you don't enable the rumble, use ps2x.read_gamepad(); with no values you should call this at least once a second */ if(error == 1) //skip loop if no controller found return; if(type == 2){ //Guitar Hero Controller ps2x.read_gamepad(); //read controller if(ps2x.ButtonPressed(GREEN_FRET)) Serial.println("Green Fret Pressed"); if(ps2x.ButtonPressed(RED_FRET)) Serial.println("Red Fret Pressed"); if(ps2x.ButtonPressed(YELLOW_FRET)) Serial.println("Yellow Fret Pressed"); if(ps2x.ButtonPressed(BLUE_FRET)) Serial.println("Blue Fret Pressed"); if(ps2x.ButtonPressed(ORANGE_FRET)) Serial.println("Orange Fret Pressed"); if(ps2x.ButtonPressed(STAR_POWER)) Serial.println("Star Power Command"); if(ps2x.Button(UP_STRUM)) //will be TRUE as long as button is pressed Serial.println("Up Strum"); if(ps2x.Button(DOWN_STRUM)) Serial.println("DOWN Strum"); if(ps2x.Button(PSB_START)) //will be TRUE as long as button is pressed Serial.println("Start is being held"); if(ps2x.Button(PSB_SELECT)) Serial.println("Select is being held"); if(ps2x.Button(ORANGE_FRET)) // print stick value IF TRUE { Serial.print("Wammy Bar Position:"); Serial.println(ps2x.Analog(WHAMMY_BAR), DEC); } } else { //DualShock Controller ps2x.read_gamepad(false, vibrate); //read controller and set large motor to spin at 'vibrate' speed if(ps2x.Button(PSB_START)) //will be TRUE as long as button is pressed Serial.println("Start is being held"); if(ps2x.Button(PSB_SELECT)) Serial.println("Select is being held"); if(ps2x.Button(PSB_PAD_UP)) { //will be TRUE as long as button is pressed Serial.print("Up held this hard: "); Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC); } if(ps2x.Button(PSB_PAD_RIGHT)){ Serial.print("Right held this hard: "); Serial.println(ps2x.Analog(PSAB_PAD_RIGHT), DEC); } if(ps2x.Button(PSB_PAD_LEFT)){ Serial.print("LEFT held this hard: "); Serial.println(ps2x.Analog(PSAB_PAD_LEFT), DEC); } if(ps2x.Button(PSB_PAD_DOWN)){ Serial.print("DOWN held this hard: "); Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC); } vibrate = ps2x.Analog(PSAB_BLUE); //this will set the large motor vibrate speed based on //how hard you press the blue (X) button if (ps2x.NewButtonState()) //will be TRUE if any button changes state (on to off, or off to on) { if(ps2x.Button(PSB_L3)) Serial.println("L3 pressed"); if(ps2x.Button(PSB_R3)) Serial.println("R3 pressed"); if(ps2x.Button(PSB_L2)) Serial.println("L2 pressed"); if(ps2x.Button(PSB_R2)) Serial.println("R2 pressed"); if(ps2x.Button(PSB_GREEN)) Serial.println("Triangle pressed"); } if(ps2x.ButtonPressed(PSB_RED)) //will be TRUE if button was JUST pressed Serial.println("Circle just pressed"); if(ps2x.ButtonReleased(PSB_PINK)) //will be TRUE if button was JUST released Serial.println("Square just released"); if(ps2x.NewButtonState(PSB_BLUE)) //will be TRUE if button was JUST pressed OR released Serial.println("X just changed"); if(ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1)) // print stick values if either is TRUE { Serial.print("Stick Values:"); Serial.print(ps2x.Analog(PSS_LY), DEC); //Left stick, Y axis. Other options: LX, RY, RX Serial.print(","); Serial.print(ps2x.Analog(PSS_LX), DEC); Serial.print(","); Serial.print(ps2x.Analog(PSS_RY), DEC); Serial.print(","); Serial.println(ps2x.Analog(PSS_RX), DEC); } } delay(50); } |
Code 2: Test with LCD i2c screen
The second code just takes few functions and shows the value or the buttons that are being pressed on the screen, here I only associated printing on lcd screen for every function, but for you, you can control servos, dc motors, LEDs… overall it’s just an example for the tutorial.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
/*This code is to use with PS2 wireless controller and LCD i2c, *it shows the buttons pressed or the analog sticks and pads values *Refer to SurtrTech.com for more details */ #include <PS2X_lib.h> #include <Wire.h> //Libraries needed #include <LCD.h> #include <LiquidCrystal_I2C.h> #define I2C_ADDR 0x27 //I2C adress, you should use the code to scan the adress first (0x27) here #define BACKLIGHT_PIN 3 // Declaring LCD Pins #define En_pin 2 #define Rw_pin 1 #define Rs_pin 0 #define D4_pin 4 #define D5_pin 5 #define D6_pin 6 #define D7_pin 7 PS2X ps2x; // create PS2 Controller Class LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin); int error = 0; int i=0,j=0; byte type = 0; byte vibrate = 0; void setup(){ Serial.begin(9600); error = ps2x.config_gamepad(13,11,10,12, true, true); //setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error type = ps2x.readType(); lcd.begin (16,2); lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); lcd.setBacklight(HIGH); //Lighting backlight lcd.home (); lcd.print(" PS2X Test"); lcd.setCursor(0,1); lcd.print(" SurtrTech"); delay(3000); lcd.clear(); } void loop(){ ps2x.read_gamepad(false, vibrate); if(ps2x.Button(PSB_START)){ lcd.clear(); lcd.print("Start Pressed"); } if(ps2x.Button(PSB_SELECT)){ lcd.clear(); lcd.print("Select Pressed"); } if(ps2x.Button(PSB_L2)) j=1; if(ps2x.Button(PSB_R2)) j=0; if (j==1){ if(ps2x.Button(PSB_PAD_UP)) { lcd.clear(); lcd.setCursor(0,0); lcd.print("Up: "); lcd.setCursor(0,1); lcd.print(ps2x.Analog(PSAB_PAD_UP)); } if(ps2x.Button(PSB_PAD_RIGHT)){ lcd.clear(); lcd.setCursor(0,0); lcd.print("Right: "); lcd.setCursor(0,1); lcd.print(ps2x.Analog(PSB_PAD_RIGHT)); } if(ps2x.Button(PSB_PAD_LEFT)){ lcd.clear(); lcd.setCursor(0,0); lcd.print("Left: "); lcd.setCursor(0,1); lcd.print(ps2x.Analog(PSB_PAD_LEFT)); } if(ps2x.Button(PSB_PAD_DOWN)){ lcd.clear(); lcd.setCursor(0,0); lcd.print("Down: "); lcd.setCursor(0,1); lcd.print(ps2x.Analog(PSB_PAD_DOWN)); } } vibrate = ps2x.Analog(PSAB_BLUE); if(ps2x.ButtonPressed(PSB_RED)){ lcd.clear(); lcd.print(" Circle"); } if(ps2x.ButtonPressed(PSB_PINK)){ lcd.clear(); lcd.print(" Square"); } if(ps2x.ButtonPressed(PSB_BLUE)){ lcd.clear(); lcd.print(" X"); } if(ps2x.ButtonPressed(PSB_GREEN)){ lcd.clear(); lcd.print(" Triangle"); } if(ps2x.Button(PSB_L1)) i = 1; if(ps2x.Button(PSB_R1)) i = 0; if(i==1){ lcd.clear(); lcd.setCursor(0,0); lcd.print("LY "); lcd.setCursor(3,0); lcd.print(ps2x.Analog(PSS_LY), DEC); lcd.setCursor(0,1); lcd.print("LX "); lcd.setCursor(3,1); lcd.print(ps2x.Analog(PSS_LX), DEC); lcd.setCursor(8,0); lcd.print("RY "); lcd.setCursor(11,0); lcd.print(ps2x.Analog(PSS_RY), DEC); lcd.setCursor(8,1); lcd.print("RX "); lcd.setCursor(11,1); lcd.println(ps2x.Analog(PSS_RX), DEC); } delay(50); } |
Categories
Yassine View All
Automation and Electrical Engineer, Electronics amateur trying to share my little projects.
How can I deactivate the vibration of the control, to perform a test without the possibility of damaging the PC input?
good contribution!!
Remove the line vibrate = ps2x.Analog(PSAB_BLUE) or comment it
brother, I want to do a counter using some axis of the stick to control servos later,
the problem is that I want to use the value (controlps.Analog (PSS_LY), DEC); and use conditional “if” to increase or decrease said counter.
when doing this, the “++ or –” operation does not respond, but the function does recognize the real-time position of the stick,
can you support me to determine the fault ?.
—————————————————————–
#include //
PS2X controlps; // create PS2 Controller Class
int contadorservo;//—–>counter variable
void setup() {
controlps.config_gamepad(13,11,10,12, false, false); // GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error
Serial.begin(9600);
}
void loop() {
byte vibrate = 0;
int lectura=(controlps.Analog(PSS_LY), DEC);
controlps.read_gamepad(false, vibrate);
if(lectura==0) {contadorservo=contadorservo++;} //condicional only for fast test
if(lectura==128){contadorservo=contadorservo;}
if(lectura==255){contadorservo=contadorservo–;}
Serial.print(contadorservo); //—–> print the data
Serial.print(” “);
Serial.println(controlps.Analog(PSS_LY), DEC);
}
—————————————
Best regards and grace for the support
Hi I’ll take a look to this, do you want to control a servo using the stick? because I have done a project where I control dual axis camera tilt with a ps2x stick.
Try this writing
if(lectura==0)
contadorservo++;
if(lectura==255)
contadorservo–-;
Try not to copy/paste this directly it may result in some errors like “stray ‘\342’ in program” and it won’t compile.
brother could you make a post with the code with the project that you tell me, I would like to have a reference with a functional project, the example of arduino has several functions running and on the internet I only find projects using buttons and no stick
thank you for your support my email is marckoe93@hotmail.com
Regards
You can check this project: https://surtrtech.com/2019/01/17/arduino-rc-laser-tank-self-propelled-laser-turret/
And here I have just a thumbstick (not the wireless joystick) with 2 servos using 2 different manners to control: https://surtrtech.com/2018/01/30/control-dual-axis-fpv-camera-cradle-with-joystick-module/
code svp
Le premier code que j’ai utilisé, vous pouvez le trouver dans l’exemple de la librairie le deuxième le lien il est juste au dessus:
Lien pour la librairie:
https://drive.google.com/file/d/1EzUuQ_v6zROcF1u4iduVKpWwXhX70keh/view
Lien pour le code qui utilise LCD:
https://drive.google.com/file/d/1-LTx07NfKrq3qYaB3ZD8_X8d596UpLZs/view
Controller found but not accepting commands
DualShock Controller Found
how to fix that?
its connected but when i click any button there is no command