Searching for info regarding the PS2X Library

Hi there!

Recently I received a lynxmotion ps2 controller kit (birthday present) and I would like to interface it with my arduino mega and use it to control my tracked robot. I download the PS2X library, but problem is , I can't for the life of me find any detailed information on how to use it. Does anyone know of a good source to find information on its functions and how to use them or would anyone be kind enough to explain what they know? I am specifically interested in how to read button states and the position of the analog joysticks.

Thanks!

Walter

Did you try the example that came with the library? If you downloaded the PSX2 library from the arduino playground then you need to go into the PSX2.h file and change WProgram.h to Arduino.h and save it. This will allow the library to compile and you can start with the example sketch it came with. The sketch shows you how to read the buttons and analog sticks.

I use the library myself, so I can help you get started.

HazardsMind:
Did you try the example that came with the library? If you downloaded the PSX2 library from the arduino playground then you need to go into the PSX2.h file and change WProgram.h to Arduino.h and save it. This will allow the library to compile and you can start with the example sketch it came with. The sketch shows you how to read the buttons and analog sticks.

I use the library myself, so I can help you get started.

Okay awesome ! l'll give that a try when I get home. I ran a program I found online that will send text to the serial monitor indicating which buttons are being pressed. The library seems to function fine; what exactly do you mean when you say compile? Are you just referring to the examples?

Also can the controller inputs be attached to any of the digital pins?

Thanks for the response!

Walter

Check out this sketch I made for my robot.

#include <PS2X_lib.h>  //for v1.6

PS2X ps2x; // create PS2 Controller Class

int error = 0; 
byte type = 0;
byte vibrate = 0;

byte speed1 =128, speed2 = 128;

byte M1L = 5;// PWM
byte M1R = 3;// PWM
byte M2L = 6;// PWM
byte M2R = 9;// PWM

void setup()
{
  Serial.begin(115200);

  //**************PAY ATTENTION*************
  pinMode(M1L, OUTPUT);                                // Establishes LEDPin as an output so the LED can be seen
  pinMode(M1R, OUTPUT);
  pinMode(M2L, OUTPUT);                                // Establishes LEDPin as an output so the LED can be seen
  pinMode(M2R, OUTPUT);
  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("Controller found! You may now send commands");

  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. ");

  type = ps2x.readType(); 
  switch(type) 
  {
  case 0:
    Serial.println("Unknown Controller type");
    break;
  case 1:
    Serial.println("DualShock Controller Found");
    break;
  }
}

void loop()
{
  if(error == 1) //skip loop if no controller found
    return;
    
  else  //DualShock Controller
  {
    ps2x.read_gamepad(false, vibrate);          //read controller and set large motor to spin at 'vibrate' speed

    if(ps2x.Button(PSB_L1))//open claw manual
    {
      // rotate turret left
    } 
    else if(ps2x.Button(PSB_R1))//close claw manual
    { 
      // rotate turret right
    }
    else 
    {
      // do nothing
    }

    // My sketch is designed to use both joysticks, Left joystick controls the left motor and right joystick does the right motor.
   // I can condense these two into just one IF / ELSE IF / ELSE statement, but here I separated them to show how one joystick controls its motor.
    if(ps2x.Analog(PSS_LY) >= 136 && ps2x.Analog(PSS_LY) <= 255)//real center value is 128, but 140 is needed because controller is HIGHLY sensitive
    {
      speed1 = map(ps2x.Analog(PSS_LY),136 , 255, 0 , 255);
      analogWrite(M1L, speed1);
      digitalWrite(M1R, LOW);
    }
    else if(ps2x.Analog(PSS_LY) >= 0 && ps2x.Analog(PSS_LY) <= 120) //Same as above
    {
      speed1 = map(ps2x.Analog(PSS_LY),0 ,120 , 255 , 0);// create a set range for values and set output values respectively
      digitalWrite(M1L, LOW);
      analogWrite(M1R, speed1);
    }  
    else {
      digitalWrite(M1L, LOW);// all off
      digitalWrite(M1R, LOW);
    } 
    //--------------------Right side motor-----------------------   
    if(ps2x.Analog(PSS_RY) >= 136 && ps2x.Analog(PSS_RY) <= 255)
    {
      speed2 = map(ps2x.Analog(PSS_RY),136 , 255, 0 , 255);
      analogWrite(M2L, speed2);
      digitalWrite(M2R, LOW);
    }

    else if(ps2x.Analog(PSS_RY) >= 0 && ps2x.Analog(PSS_RY) <= 120)
    {
      speed2 = map(ps2x.Analog(PSS_RY),0 ,120 , 255 , 0);
      digitalWrite(M2L, LOW);
      analogWrite(M2R, speed2);
    }

    else 
    {
      digitalWrite(M2L, LOW);
      digitalWrite(M2R, LOW);
    }  
  }
  delay(50); // not needed, but give the robot some time to finish inputted commands   
}

Oh Wow Thanks! This will be quite helpful. This is pretty much what I was hoping to achieve. Thanks for Sharing!

Walter

Here is some code I adapted from bits of yours. Problem is, the value of Signal1 and Signal2 stay the same regardless of the PS2 stick position. What did I do wrong?

Thanks,
Walter

#include <Servo.h>
#include <PS2X_lib.h>  //for v1.6

PS2X ps2x; // create PS2 Controller Class

int error = 0; 
byte type = 0;
byte vibrate = 0;
Servo Signal1; 
Servo Signal2; 
int Input1 = 1500;// creates servo object
int Input2 = 1500;



void setup()
{
  Serial.begin(57600);
  
 Signal1.attach(6);  //the pin for the servo control 
 Signal2.attach(7);
  
  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("Controller found! You may now send commands");

  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. ");

  type = ps2x.readType(); 
  switch(type) 
  {
  case 0:
    Serial.println("Unknown Controller type");
    break;
  case 1:
    Serial.println("DualShock Controller Found");
    break;
  }
}
//My sabortooth motordriver can use the two signals 1000us-2000us to control the two motors
void loop()
{

      Input1 = map(ps2x.Analog(PSS_LY), 0, 255, 1000, 2000);
     //Signal1.writeMicroseconds(Input1);
     Serial.print (Input1);
      
      Input1 = map(ps2x.Analog(PSS_LX), 0, 255, 1000, 2000);
     // Signal2.writeMicroseconds(Input1);
      Serial.print (Input2);
      delay(1000);
   
    }

Is the little center button pressed(red light), the one below the start and select buttons?

Input1 = map(ps2x.Analog(PSS_LY), 0, 255, 1000, 2000);
//Signal1.writeMicroseconds(Input1);
Serial.print (Input1);

Input1 = map(ps2x.Analog(PSS_LX), 0, 255, 1000, 2000);
// Signal2.writeMicroseconds(Input1);
Serial.print (Input2);
delay(1000);

You should really add a comma to separate them, like so.

Serial.print(Input1); Serial.print(", "); Serial.print(Input2); // I wrote it like this so you can see what I'm trying to do.
Output: yyyy, xxxx

I added the comma and it makes it much easier to read :stuck_out_tongue: Is there a way I can tell it to kick the next set of values down to the next line on the serial monitor?

Also I noticed I was mapping Input1 twice and not mapping Input2 at all. However I made the correction and no it just prints 1501,1501,etc.
Is there something wrong with how I used/ setup the map function?

It makes no difference whether the red light is on or off on the controller; it still prints the same thing.

Thanks for all the help

Walter

I added the comma and it makes it much easier to read smiley-razz Is there a way I can tell it to kick the next set of values down to the next line on the serial monitor?

Yea, that was my fault, change the last one to Serial.println(Input2);

1501,1501,etc.
Is there something wrong with how I used/ setup the map function?

The joysticks work exactly like a potentiometer, so full up is 255 and full down is 0, so in between is 128, and when you map 128, that equals to ~1500. Those values should increase and decrease when you move the stick, if it doesn't then there may be a problem with the wiring or the controller itself.

How much voltage is the controller getting, 3.3 or 5V? I have a regular and a wireless controller and they only seem to work at 3.3V.

When I run the Example sketch for the library the values come back as expected so I doubt it is a wiring issue...
Any other possible issues I should check?

the values come back as expected so I doubt it is a wiring issue...

What values, the buttons?
Can you post a picture of your setup?

Both the buttons and the analog sticks return the expected values when I run the example program.

Here is a picture of the wiring:

I looked over your code and compared it to mine and it seems your missing this function.
ps2x.read_gamepad(false, 0);

Add that function in your loop().

Oh I totally missed that!

I got it working using the following code:

#include <Servo.h>
#include <PS2X_lib.h>  //for v1.6

PS2X ps2x; // create PS2 Controller Class

int error = 0; 
byte type = 0;
byte vibrate = 0;
Servo Signal1; 
Servo Signal2; 
int Input1 = 1500;// creates servo object
int Input2 = 1500;



void setup()
{
  Serial.begin(57600);

  Signal1.attach(6);  //the pin for the servo control 
  Signal2.attach(7);

  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("Controller found! You may now send commands");

  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. ");

  type = ps2x.readType(); 
  switch(type) 
  {
  case 0:
    Serial.println("Unknown Controller type");
    break;
  case 1:
    Serial.println("DualShock Controller Found");
    break;
  }
}
//My sabortooth motordriver can use the two signals 1000us-2000us to control the two motors
void loop()
{
ps2x.read_gamepad(false, 0);


  Input1 = map(ps2x.Analog(PSS_LY), 0, 255, 2000, 1000);
  Signal1.writeMicroseconds(Input1);
 // Serial.print (Input1);
  // Serial.print (",");


  Input2 = map(ps2x.Analog(PSS_LX), 0, 255, 2000, 1000);
  Signal2.writeMicroseconds(Input2);
  //Serial.println (Input2);
  delay(25);

}

The controller will not bind to the receiver without the 25 millisecond delay. The robot responds sluggishly compared to the response time of radio control system I previously used. Is this due to the delay? How can I eliminate this delay?

Thanks again for all the help and guidance

You would need to learn about the Bink Without Delay sketch and how it works.

Using an 8 millisecond delay I don't notice any lag. If it becomes an issue I will try out the blink withought delay concept!

How can I decrease the sensitivity of my bot? Right now any tiny stick movement sends the 12 lb bot wheelieing across the room!

Also most times when I push the stick right, the right motor just spins at full speed and will not cease until the power is shut off. This is quite fiasco when I am not test on the work stand! Any idea what might be causing this?

Thanks!!

Walter

What are you using to move your robot, 360 servos or DC motors?

Post a picture of your robot and if possible the connections too.

Okay. Here are some pictures of the robot and the wiring. There is also a video of the bot malfunctioning. I am using to Rs550 motors with 16:1 banebots gearboxes.

I added 2.2k Ohm pull down resisters to both the output pins, but it seemed to have no effect.
Weirdly enough, the issue only seems to occurs if the arduino is not plugged into the computer via usb. Any idea the reason for this?

For testing the right motor is being directly controlled by the X axis of the joystick and the left motor is directly controlled by the y axis of the joy stick. When it goes haywire both motors are thrown into full reverse as if both Signal1 and Signal2 assume a value of 1000us. I can't confirm this as the issue doesn't occur when it is connected to the computer.

Thanks!!

Walter

Having to post one at a time because of file size

And the Video!

IMG_4146.MOV (2.42 MB)