Wireless PS2 Controller

Overview

The wireless PS2 controller has 12 buttons, and two analog sticks with full 360 degree motion. This mode of interfacing is robust and easy to use. The hardware setup takes about three minutes, and the only thing stopping you from doing seemingly impossible tasks with your robot is just a few lines away from the example code below. Button-mapping is simple, so setting up a simple control scheme for your robot with four wheels, a crane, and a grabbing mechanism is manageable.

Parts

-Arduino microcontroller and carrier board

-LiPo battery

-wireless PS2 Controller

-Controller Cable

-Jumper wires

Preparing the breadboard

Note: This wiring scheme MUST correlate to the code (example displayed below). Here, the DIGITAL pins 2, 3, 4, and 5 are being used, and are therefore the active inputs. If you don't account for this, you will encounter NO functionality.

Your Li-Po battery must be fully charged to use this controller!!!

PS2 Libraries

1. Bill Porter: Library (comes with GuitarHero Controller support) (tested):

To Install This Library:

-Unzip and place 'PS2X_lib' folder into your 'C:\Users\{user name}\Documents\Arduino\libraries'

folder or '{Arduino IDE path}\hardware\libraries" or {Arduino IDE path}\libraries" directory.

-Restart the Arduino IDE, and open up the example sketch. All uses of the library are in the example

sketch.

2. Analog PS2 Controller (not tested by 2.007 staff yet).

Program the Microcontroller

Open up the example sketch, which is located inside the 'PS2X_Example' folder. All uses of the library are in the example sketch.

Note: The library does NOT support hot pluggable controllers, meaning you must ALWAYS restart your Arduino after you connect the controller.

If you are using the PS2X_lib.h library by Bill Porter, you need to change some code to reflect your wiring. The PS2 controller is a digital controller, which means you need to plug the cables onto the digital pins (here, they are 2, 4, 3, 5. They correspond to the cable labels: clock, command, attention, data) on your Arduino board.

ps2x_error = ps2x.config_gamepad(2,4,3,5, false, false);
// config_gamepad(clock, command, attention, data, Pressures?, Rumble?)
//or set it up via global defines: always safer!
#define DAT 2
#define CMD 3
#define ATT 4
#define CLK 5
ps2x_error = ps2x.config_gamepad(CLK, CMD, ATT, DAT, false, false);
//Check your cable colors!!! Otherwise you will get zilch data.
// cable colors: (blue, yellow, orange, brown)    // old controllers
// cable colors: (blue, yellow, white, brown)     // new config

// cable colors: (purple, yellow, orange, blue) // new config

IMPORTANT: Newer cables have a different configuration. Check your cable and pay special attention to the colors.

Old Configuration

blue - clock

yellow - attention

orange - command

brown- data

New configuration

purple - clock

yellow - attention

orange - command

blue - data

Note: This sketch does not use the full functionality of the PS2X library. Refer to the example code for all button functions!

// include additional headers
#include <Servo.h>
#include <PS2X_lib.h>  //for v1.6
// create PS2 Controller Class
PS2X ps2x;
int ps2x_error = 0;
byte ps2x_type = 0;
byte ps2x_vibrate = 0;
// create servo class
Servo servoL;        // initialize left servo
Servo servoR;        // init right servo
#define SERVOR 8
#define SERVOL 9

//set up pins for playstation controller

#define DAT 2 #define CMD 3 #define ATT 4 #define CLK 5

const int neutral = 1512;
const int forward = 2000;
const int backward = 1000;
//--- Function: Setup ()
void setup()
{
  Serial.begin(57600);
 
  // setup servos
  pinMode (SERVOL, OUTPUT);
  pinMode (SERVOR, OUTPUT);
  servoL.attach(SERVOL);   
  servoR.attach(SERVOR);
  servoL.writeMicroseconds(neutral);     // set servo to mid-point
  servoR.writeMicroseconds(neutral);    // set servo to mid-point
  // check for controller

ps2x_error = ps2x.config_gamepad(CLK, CMD, ATT, DAT, false, false);

  if(ps2x_error == 0)
    Serial.println("Found Controller, configured successful");
  else if(ps2x_error == 1)
    Serial.println("No controller found, check wiring.");
  else if(ps2x_error == 2)
    Serial.println("Controller found but not accepting commands.");
  else if(ps2x_error == 3)
    Serial.println("Controller refusing to enter Pressures mode, may not support it. ");
  // get which type
  ps2x_type = ps2x.readType();
  switch(ps2x_type)
  {
  case 0: Serial.println("Unknown Controller type");  break;
  case 1: Serial.println("DualShock Controller Found");  break;
  }
}
//--- Function: loop ()
void loop()
{
   
  if((ps2x_error == 1) || (ps2x_error == 2) || (ps2x_error == 3))
    {
    //skip loop if no controller found
    return;
     }
  else if(ps2x_error == 0)
  {
    if(ps2x_type == 1)
    {
      ps2x.read_gamepad(false, ps2x_vibrate);         
      //read controller and set large motor to spin at 'vibrate' speed
      if(ps2x.Button(PSB_PAD_UP))
      {    
        Serial.println("Up ");
        servoL.writeMicroseconds(backward);
        servoR.writeMicroseconds(forward);
      }
      else if(ps2x.Button(PSB_PAD_RIGHT))
      {
        Serial.println("Right");
        servoL.writeMicroseconds(neutral);
        servoR.writeMicroseconds(forward);
      }
      else if(ps2x.Button(PSB_PAD_LEFT))
      {
        Serial.println("LEFT");
        servoL.writeMicroseconds(backward);
        servoR.writeMicroseconds(neutral);
      }
      else if(ps2x.Button(PSB_PAD_DOWN))
      {
        Serial.println("DOWN ");
        servoL.writeMicroseconds(forward);
        servoR.writeMicroseconds(backward);
      }
      else
      {
        servoL.writeMicroseconds(neutral);
        servoR.writeMicroseconds(neutral);
      }
    } // end error
  }// end DualShock Controller
  delay(50);
}  // end loop

Additional buttons:

ps2x.Button(PSB_START)
ps2x.Button(PSB_SELECT)
ps2x.Button(PSB_PAD_UP)
ps2x.Button(PSB_PAD_RIGHT)
ps2x.Button(PSB_PAD_LEFT)
ps2x.Button(PSB_PAD_DOWN)
ps2x.Button(PSB_L1)
ps2x.Button(PSB_R1)
ps2x.Button(PSB_L2)
ps2x.Button(PSB_R2)
ps2x.Button(PSB_L3)
ps2x.Button(PSB_R3)
ps2x.Button(PSB_RED)
ps2x.Button(PSB_GREEN)
ps2x.Button(PSB_PINK)
ps2x.Button(PSB_BLUE)

Implementation Examples/Information:

Value based on how hard you press the blue (X) button:

byte value = ps2x.Analog(PSAB_BLUE);

Drive with stick values (in loop()):

// include additional headers
#include <Servo.h>
#include <PS2X_lib.h>  //for v1.6
// create PS2 Controller Class
PS2X ps2x;
int ps2x_error = 0;
byte ps2x_type = 0;
byte ps2x_vibrate = 0;
// create servo class
Servo servoL;        // initialize left servo
Servo servoR;        // init right servo
#define SERVOR 8
#define SERVOL 9
const int servoneutral = 1500;

//set up pins for playstation controller

#define DAT 2

#define CMD 3

#define ATT 4

#define CLK 5

//--- Function: Setup ()
void setup()
{
  Serial.begin(57600);
  // setup servos
  pinMode (SERVOL, OUTPUT);
  pinMode (SERVOR, OUTPUT);
  servoL.attach(SERVOL);  
  servoR.attach(SERVOR);
  servoL.writeMicroseconds(servoneutral);     // set servo to mid-point
  servoR.writeMicroseconds(servoneutral);    // set servo to mid-point
  // check for controller 
ps2x_error = ps2x.config_gamepad(CLK, CMD, ATT, DAT, false, false);
  if(ps2x_error == 0)
    Serial.println("Found Controller, configured successful");
  else if(ps2x_error == 1)
    Serial.println("No controller found, check wiring.");
  else if(ps2x_error == 2)
    Serial.println("Controller found but not accepting commands.");
  else if(ps2x_error == 3)
    Serial.println("Controller refusing to enter Pressures mode, may not support it. ");
  // get which type
  ps2x_type = ps2x.readType();
  switch(ps2x_type)
  {
  case 0:
    Serial.println("Unknown Controller type"); 
    break;
  case 1:
    Serial.println("DualShock Controller Found"); 
    break;
  }
}
//--- Function: loop ()
void loop()
{
  if((ps2x_error == 1) || (ps2x_error == 2) || (ps2x_error == 3))
  {
    return; //skip loop if no controller found
  }
  else if(ps2x_error == 0)
  {
    if(ps2x_type == 1)
    {
      ps2x.read_gamepad(false, ps2x_vibrate); //read controller
      Serial.print("Stick Values: ");
      Serial.println(ps2x.Analog(PSS_LY), DEC);
      //Left stick, Y axis. Other options: LX, RY, RX 
      int leftstick = (ps2x.Analog(PSS_LY));
      leftstick = leftstick-128;
      int rightPWM = 1500 + (leftstick)*4;
      int rightstick = (ps2x.Analog(PSS_RY));
      rightstick = rightstick-128;
      int leftPWM = 1500 + (rightstick)*4;      
      servoL.writeMicroseconds(leftPWM);
      servoR.writeMicroseconds(rightPWM);
    } // end type
  }// end error
  delay(50);
}  // end loop

Vibration:

byte vibrate = 0;
ps2x.read_gamepad(true, vibrate);         
//read controller and set large motor to spin at 'vibrate' speed
vibrate = ps2x.Analog(PSAB_BLUE);       
//this will set the large motor vibrate speed based on how hard you press the blue (X) button