Tuesday, December 11, 2012

Interfacing a PlayStation 2 (PS2) Controller with Arduino

I got a free PS2 controller, but with no PS2 to use it with I had to do SOMETHING with it, haha. That, of course, was taking it apart and using it with an Arduino as a control system.

Here is the inside:


Inside the connector:



Pinout Inside Controller 


Pinout of the connector:

You can see on the PCB which wires are for each pin. Then where the wires go on the connector.

Connections to Arduino:

These are using the PSX code below. they can be changed in code.
Arduino, PS2 PCB Label, Full Name, Color
13,,,,,,,,,, CLK,,,,,,,,,,,,,,,,, (Clock),,,,,,, Brown
11,,,,,,,,,, DO,,,,,,,,,,,,,,,,,,, (Command), Orange
10,,,,,,,,,, CS,,,,,,,,,,,,,,,,,,,, (Attention),,, Red
12,,,,,,,,,, DI,,,,,,,,,,,,,,,,,,,,, (Data),,,,,,,,,, Green
GND,,,,, GND,,,,,,,,,,,,,,,, (Ground),,,,,, Black
N/C,,,,,,,,ACK,,,,,,,,,,,, (Acknowledge),, White
3.3V,,,,,,,3.3v,,,,,,,,,,,,,,,,,, (3.3v),,,,,,,,,,, Yellow
7.5V,,,,,,,See Below,,,,,,,, See Below,,, Blue

7.5v triggers the feedback motor inside of the controller. Too use this you will have to use a digital pin to trigger a mosfet/transistor to supply the 7.5v. 

Code:

Get the library from here.

#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.");
  Serial.println("Go to www.billporter.info for updates and to report bugs.");
 }
 
  else if(error == 1)
   Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit 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 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);
   
}

24 comments:

  1. I found that some controllers have a different setup with the wires, for example on some the clock is the blue while the data is brown.

    ReplyDelete
  2. the color doesn't really matter, as long as CLK on the controller goes to the correct pin on the arduino

    ReplyDelete
  3. Can u tell me which arduino board to use :-model and version no.If possible,attach
    photo of the arduino board.Also,are there any accessories required to connect ps2 controller to arduino board.
    Email ID:shaileshsk94@gmail.com

    ReplyDelete
    Replies
    1. Arduino UNO R3. you can get the SMD version or not. same functionality.

      Delete
    2. Thanks a lot.Can u plz tell me the ps2 connections on arduino uno r3..or post the picture showing connections.

      Delete
    3. Thanks a lot.After making connections,in the program as given above ,is it required to config.them in the program or just directly use the program.Please reply ASAP.

      Delete
    4. if you connect it correctly, then yes.

      Delete
  4. I have made all connections perfectly.But,still it gives error=1 as check the wiring.Do pull up resistors are required for data line and also what about acknowledge pin??
    How can it interact without ack signal...

    ReplyDelete
    Replies
    1. YES, you'll need a pull up on DATA pin & ack is left open....
      It worked for us in this way, try if it works with you.

      Delete
    2. can u plz elaborate the connections for dualshock controller with mega2560

      Delete
  5. It works well but if I try to do it with a wireless joypad does not work. Any suggestions?

    ReplyDelete
    Replies
    1. the wireless controller has to be using the same wires and signals because it has to be compatible with the ps2 and so it should also work here. id check your wiring.

      Delete
  6. The problem is not in the wiring, I managed to get it to communicate disabling the writing on uart serial arduino but only if I try to communicate via a serial connection is lost joypad. is a mystery!

    ReplyDelete
  7. this tutorial does use a library...

    ReplyDelete
  8. Just wanted to say thanks, so many other tutorials require a bunch of components, this one is simple, without motors it's just one resistor.

    I would like to note to others though, I originally had a 10K pull up which wasn't working, it started working once I changed it to 1K. I figured it out because I read somewhere it should be between 1K and 5K. Hope that helps someone.

    ReplyDelete
  9. Hi, I tried this code using pc joystick controller, but it shows error like this:

    OUT:IN
    1:FF 42:62 0:10 0:FF 0:FF 0:0 0:72 0:72 0:72 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0
    OUT:IN
    1:FF 42:72 0:10 0:FF 0:FF 0:0 0:72 0:72 0:72 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0
    Controller mode not matched or no controller found
    Expected 0x41 or 0x73, got 72
    No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips
    Unknown Controller type

    I've checked all of the wire and it seems OK, Is there any possibilities to fix this - due to the type of the joystick? thx

    ReplyDelete
  10. hey!! I want to control an RC car with ps2 wireless remote plz help me out with the connections and program plz..
    thank ypu...

    ReplyDelete
  11. IF a ihave a ps2 usb gamepad (ps2 gampad for pc), how can i read data and conecting to arduino?, i know usb pinouts are +5Vcc, Data+, Data-, GND.

    ReplyDelete
  12. Hey man, i need some help here. It's giving me this error
    OUT:IN
    1:FF 42:FF 0:FF 0:FF 0:FF 0:FF 0:FF 0:FF 0:FF 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0
    OUT:IN
    1:FF 42:FF 0:FF 0:FF 0:FF 0:FF 0:FF 0:FF 0:FF 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0 0:0
    Controller mode not matched or no controller found
    Expected 0x41 or 0x73, got FF

    Just in case it matters a lot, it's a PS1 joystick with no dualshock. I made sure the wires are what they're supposed to be tho (data, controller, clock, etc, in the right pin on the arduino)

    any idea how to get this working? hope you're still around

    ReplyDelete
    Replies
    1. I dunno, sounds like a connection issue or something. No signal i think.

      Delete