Arduino Playstation 2 Controller Library Troubleshooting Guide

Posted in Arduino Libraries by Bill
27 Mar 2011
Arduino Playstation 2 Controller Library Troubleshooting Guide

Ok, if you are here, you are having trouble getting your Arduino talking to your PlayStation 2 Controller via my Handy Dandy PS2X Library. Well, never fear, I stand by my leet coding abilities (Ha! who am I kidding? Really though, the library works, there’s tons of examples using it.) and I’m here to help. The problem is there’s not much I can really do unless you live near North Florida and want to come pay me a visit. It’s hard giving help over the internet! But maybe I can guide you in the right direction with this troubleshooting guide.

I’ll walk you through some debugging steps, and you should follow through with me with DEBUG off until I tell you to enable it and using the example sketch unmodified. In-between attempts, power off the Arduino and controller for 10 seconds before testing it again.  I’ll bold the quick steps if you want to skim through.

A little background first. I have not personally reverse engineered the communications protocol a PS2 controller uses. That has been done by a few other cool guys like this one.  I used what they reported in writing the PS2X library. As far as I know Sony has never official published the communications protocol to the public, so reverse engineering efforts is all we have to go on. This has lead to a few problems; for example some controllers just don’t behave like others. From the various sources around the web, the best chance of success comes from using ‘Official’ Sony controllers, and not the cheap knock-offs, 3rd  party controllers. There’s also some links with wireless controllers not working well either. Personally I have tried a wired Sony controller, and a few wireless Guitar Hero Controllers all with success, powered at 5V and no resistors.

Therefore the first thing to consider is what controller are you using? Can you try another brand, model?

Ok, now that we are past history of controllers, I’ll tell you this: 90% of the problems people have end up being related to wiring. I can’t look at your setup, so you are going to have to use your best judgment. Does the wiring look sound? Controller wires are thin and small and tend to break easily. During prototyping, I cut the ends off my wired controllers, stripped 1/4″ insulation off and heavily tinned the wires to create solid ‘pins’ that could be pushed into the female pinheader on the Arduino. This method worked, but was fragile. Later on I bought a few $5 PS2 controller extension cables and cut off the female receptacle end. I soldered the wires from the plug to PCB board and that worked well also.

 

Don’t trust the color scheme on the wiring picture. It can vary! Instead, use a voltmeter and test continuity between pin positions in the connector and the bare wires. I’ve had a few people report odd color schemes, and a few not realize what end of the connector they were looking at and got the wiring completely backwards. A quick check is to power up the controller, and pushing the ‘Analog’ button. Either the LED should have been on when it powered up, or it should light up when you press the button. If not, the controller isn’t getting power and you probably have the wiring reversed.

Alright, so you trust the wiring job, what next?

There are discussions over whether or not the controllers are tolerant of 5V logic. I’ve never had one burn out, so I believe they can handle “receiving’ 5V, but they still won’t ‘send’ 5V to the Arduino. It seems to me the one fix that seems to work the most is adding a 10k resistor between DATA (brown wire, or pin 1 on the controller port) and VCC (try both 3.3V and 5V in that order) on the Arduino.

This will help ‘pull-up’ the data line. Also there’s disagreement on what voltage to use to power the controller. A PlayStation powers the controller at 3.4V. I have always powered my controllers at 5V and had no problems, but it is risky. Controllers are so cheap on ebay though, why not try it? Try different voltages for power, switch between 3.3V and 5V, and for each voltage try it with and without the pull-up resistor on the DATA line .

One person claimed his controller wouldn’t work without level shifting all his wires, which means he just added resistors inbetween the controller’s pins and the Arduino.

The numbers he reported success with is as follow:

  1. 5V = 180 ohm, voltage drop of 1.85V (3.15v to the controller)
  2. ATT = 5.6K ohm, voltage drop of 1.08V (3.92 to the controller)
  3. CLK = 5.6K ohm, voltage drop of 1.15V (3.85 to the controller)
  4. CMD = 860K ohm, voltage drop of 1.39V (3.61 to the controller)

so you can give that a try as well. Though really, ignore the resistor on 5V and just connect the red power wire to 3.3V.

Some people report issues using pin 13 on the Arduino for CLK. Try moving the CLK line to another pin, and editing the example sketch to match.

If you have gotten this far and still no luck, you might just be out of luck. Controllers can go bad and some people just aren’t any good at wiring. But, there’s one more thing we can try messing with.

There’s a value in the ‘PS2X_lib.h’ file that governs the speed of the bus to the controller. It’s called ‘CTRL_CLK’ and you can find it by looking for this line:

#define CTRL_CLK        4

The PlayStation 2 talks to its controllers at 500kHz, or a value of ’2′ in my library. Arduino tends to have issues setting a value that low, so by default I have it set at 4. You can try using 2 instead, and I’d also try using some higher number for a slower bus speed. Go from 2-20 and even 200 to see if you can get the controller talking. Remember to save the .h file every time you edit it, and re-compile the sketch.

Still no luck? Man you are killing me. I’ve dropped all my suggestions into this guide, so there’s not much else I can say even if you ask really nicely. Florida is nice year round, so feel free to come visit me and I will help you in person. Otherwise, you can try to enable debug. It won’t really help diagnosing wiring problems (or bad controllers) because all you will see is all FF’s or 0′s. But if you are getting some values, they may be something else going on. Drop the output in the Support Forum and I’ll see if I can help.

My last fleeting thoughts include removing the checks in the example. At the end of the setup function (after the switch statement and before the closing curly bracket ‘}’ ), add the following code:

error = 0;

type = 1;

This will bypass the error checking and run the code anyway. What do you get? Try pressing reset on the Arduino without disconnecting the controller. Anything?

Still need help?

Use the Support Forum to ask for help. Please don’t use the comments below.


If you found this post interesting or helpful, please consider sending in a donation or disabling any ad-block plugin on my site. Proceeds go to my various education outreach efforts, towards repairing museum exhibits, or to my beer fund.


Share

Trackbacks / Pingbacks

  1. PlayStation 2 Controller Arduino Library v1.0 « The Mind of Bill Porter
  2. DIY Arduino Intervalometer : DIYfilm
  1. 158 Comments.

    • Can you fix code
      #include
      #include
      #include

      //#define LED_PIN 13
      //#define DELAY(wait) digitalWrite(LED_PIN,LOW); delay(wait); digitalWrite(LED_PIN,HIGH);

      /* These are AVR PORTB pins, +8 to convert to Arduino pins */
      #define PS2clk 5//13
      #define PS2cmd 3//11
      #define PS2att 2//10
      #define PS2dat 4//12
      #define PS2PORT PORTB
      #define PS2IN PINB
      #define CTRL_CLK 20
      #define CTRL_BYTE_DELAY 20

      //These are our button constants
      #define PSB_SELECT 0×01
      #define PSB_L3 0×02
      #define PSB_R3 0×04
      #define PSB_START 0×08
      #define PSB_PAD_UP 0×10
      #define PSB_PAD_RIGHT 0×20
      #define PSB_PAD_DOWN 0×40
      #define PSB_PAD_LEFT 0×80

      #define PSB_L2 0×100
      #define PSB_R2 0×200
      #define PSB_L1 0×400
      #define PSB_R1 0×800
      #define PSB_GREEN 0×1000
      #define PSB_RED 0×2000
      #define PSB_BLUE 0×4000
      #define PSB_PINK 0×8000

      #define SET(x,y) (x|=(1<<y))
      #define CLR(x,y) (x&=(~(1<<y)))
      #define CHK(x,y) (x & (1<<y))
      #define TOG(x,y) (x^=(1<= 0×100) {
      byte = 4;
      button = button >> 8;
      }
      if (PS2data[byte] & button)
      return true;
      else
      return false;
      }
      unsigned char _gamepad_shiftinout (char byte) {
      unsigned char tmp = 0;
      for(i=0;i<8;i++) {
      if(CHK(byte,i)) SET(PS2PORT,PS2cmd);
      else CLR(PS2PORT,PS2cmd);
      CLR(PS2PORT,PS2clk);
      delayMicroseconds(CTRL_CLK);
      if(CHK(PS2IN,PS2dat)) SET(tmp,i);
      SET(PS2PORT,PS2clk);
      }
      SET(PS2PORT,PS2cmd);
      delayMicroseconds(CTRL_BYTE_DELAY);
      return tmp;
      }
      void _gamepad_shiftout (char byte) {
      for(i=0;i<8;i++) {
      if(CHK(byte,i)) SET(PS2PORT,PS2cmd);
      else CLR(PS2PORT,PS2cmd);
      CLR(PS2PORT,PS2clk);
      delayMicroseconds(CTRL_CLK);
      SET(PS2PORT,PS2clk);
      //delayMicroseconds(CTRL_CLK);
      }
      SET(PS2PORT,PS2cmd);
      delayMicroseconds(CTRL_BYTE_DELAY);
      }
      unsigned char _gamepad_shiftin() {
      unsigned char tmp = 0;
      for(i=0;i<8;i++) {
      CLR(PS2PORT,PS2cmd);
      CLR(PS2PORT,PS2clk);
      delayMicroseconds(CTRL_CLK);
      if(CHK(PS2IN,PS2dat)) SET(tmp,i);
      SET(PS2PORT,PS2clk);
      delayMicroseconds(CTRL_CLK);
      }
      SET(PS2PORT,PS2cmd);
      delayMicroseconds(CTRL_BYTE_DELAY);
      return tmp;
      }
      void read_gamepad() {
      SET(PS2PORT,PS2cmd);
      SET(PS2PORT,PS2clk);
      CLR(PS2PORT,PS2att); // low enable joystick
      delayMicroseconds(CTRL_BYTE_DELAY);
      char dword[9] = {0×01,0×42,0,0,0,0,0,0,0};
      for (int i = 0; i<9; i++) {
      PS2data[i] = _gamepad_shiftinout(dword[i]);
      }
      SET(PS2PORT,PS2att); // HI disable joystick
      }
      unsigned char get_gamepad_mode() {
      SET(PS2PORT,PS2cmd);
      SET(PS2PORT,PS2clk);
      CLR(PS2PORT,PS2att); // low enable joystick
      _gamepad_shiftout(0×01);
      unsigned char x = _gamepad_shiftin();
      SET(PS2PORT,PS2att); // HI disable joystick
      return x;
      }
      void config_gampad() {
      SET(PS2PORT,PS2cmd);
      SET(PS2PORT,PS2clk);
      CLR(PS2PORT,PS2att); // low enable joystick
      _gamepad_shiftout(0×01);
      _gamepad_shiftout(0×43);
      _gamepad_shiftout(0×00);
      _gamepad_shiftout(0×01);
      _gamepad_shiftout(0×00);
      // Lock to Analog Mode on Stick
      _gamepad_shiftout(0×01);
      _gamepad_shiftout(0×44);
      _gamepad_shiftout(0×00);
      _gamepad_shiftout(0×01);
      _gamepad_shiftout(0×03);
      _gamepad_shiftout(0×00);
      _gamepad_shiftout(0×00);
      _gamepad_shiftout(0×00);
      _gamepad_shiftout(0×00);
      // Vibration
      /*
      _gamepad_shiftout(0×01);
      _gamepad_shiftout(0x4D);
      _gamepad_shiftout(0×00);
      _gamepad_shiftout(0×00);
      _gamepad_shiftout(0×01);
      */
      _gamepad_shiftout(0×01);
      _gamepad_shiftout(0x4F);
      _gamepad_shiftout(0×00);
      _gamepad_shiftout(0xFF);
      _gamepad_shiftout(0xFF);
      _gamepad_shiftout(0×03);
      _gamepad_shiftout(0×00);
      _gamepad_shiftout(0×00);
      _gamepad_shiftout(0×00);
      _gamepad_shiftout(0×01);
      _gamepad_shiftout(0×43);
      _gamepad_shiftout(0×00);
      _gamepad_shiftout(0×00);
      _gamepad_shiftout(0x5A);
      _gamepad_shiftout(0x5A);
      _gamepad_shiftout(0x5A);
      _gamepad_shiftout(0x5A);
      _gamepad_shiftout(0x5A);
      SET(PS2PORT,PS2att);
      }

      void readkey ()
      {

      if(PSButton(PSB_PAD_UP))
      {
      Serial.println("1");
      }
      else if(PSButton(PSB_SELECT))
      {
      Serial.println("x");
      }
      else if(PSButton(PSB_PAD_DOWN))
      {
      Serial.println("2");
      }
      else if(PSButton(PSB_PAD_RIGHT))
      {
      Serial.println("4");
      }
      else if(PSButton(PSB_PAD_LEFT))
      {
      Serial.println("3");
      }

      else if(PSButton(PSB_L3))
      {
      Serial.println("L3\n");
      }
      else if(PSButton(PSB_R3))
      {
      Serial.println("R3\n");
      }

      else if(PSButton(PSB_L1))
      {
      Serial.println("a");
      }
      else if(PSButton(PSB_R1))
      {
      Serial.println("c");
      }
      else if(PSButton(PSB_L2))
      {
      Serial.println("b");
      }
      else if(PSButton(PSB_R2))
      {
      Serial.println("d");
      }
      else if(PSButton(PSB_GREEN))
      {
      Serial.println("5");
      }
      else if(PSButton(PSB_RED))
      {
      Serial.println("8");
      }
      else if(PSButton(PSB_PINK))
      {
      Serial.println("7");
      }
      else if(PSButton(PSB_BLUE))
      {
      Serial.println("6");
      }
      else if(PSButton(PSB_START))
      {
      Serial.println("z");
      }
      else{ Serial.println("PLS control JOY");}

      }

    • ShaileshNo Gravatar says:

      There is a problem with rumble in dualshock ps2 controller.It works sometimes.I have wired vibration pin to 9v ,Can u plz mail the code for vibrating motors??

    • ayushiNo Gravatar says:

      I want to run a robot vehicle using arduino mega2560 and ps2 controller .I hav changed wiring as u said but i always get error”no controller found,check wiring”

      • dipesh mulaniNo Gravatar says:

        @ayushi same problem was with me if you are wiring correctly then connect 10k resister to clock ,att and cmd wires sepratly it should work then

    • Rob RNo Gravatar says:

      I thought I would share my experience. First I put it together and got the “controller not recognized error”

      I put in the pullup resistor and it worked like a charm. It’s fully functional now. Thanks Bill Porter!

    • FabianNo Gravatar says:

      hello, i am Fabian from argentina
      Nice work, i make this proyect and its Works good, only change the pin 13 of the clock and i put this in the pin 9. i want to make work 1 servo and move it progressive to 180 with button up y then go progressive to 0 degress with button down, and only i can do is go to one degress to other degrees because i am not programer and i am learning. please if anyone can help me thanks so much. oeste24@hotmail.com

    • MichaelNo Gravatar says:

      I’m having trouble with the connection of the controller and the BotBoarduino, I have connected it properly before and the controller worked and got the signal, also I would use the Serial Monitor (COM4) and it would read the buttons being pressed. However now it stopped working and keeps saying “No controller found, check wiring, see readme.txt to enable debug. visit http://www.billporter.info for troubleshooting tips
      Unknown Controller type”
      And the wiring has not changed at all. So I have no idea what to do. I am using the BotBoarduino and the PS2 Robot Controller (v2. I would greatly appreciate anyone’s help, thank you for your time.

      • Rob RNo Gravatar says:

        I would try 3 things. Add the 10k pullup resistor between data and Vcc. Also and try a different controller. Another idea is to try 3.3V if you are using 5.

        Are you using a wireless controller?

    • ViniciusNo Gravatar says:

      It is necessary to have a 9V battery in Arduino for everything work? I have a new controller, all wiring ok, but nothing happens when I plug it in. I did not connected a 12V nor a 9V battery, only the USB cable.
      Thanks and sorry for asking

    • dipesh mulaniNo Gravatar says:

      Hello guys am new to adruino and actually I want to make a simple two wheel bot and actually I connected my adruino to a ps2 wireless controller and it worked great each keys are working but now I have a question and that is how should I control two moters using ps2 controller ?
      Can anyone please help ! :’(

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Current day month ye@r *

Notify me of followup comments via e-mail. You can also subscribe without commenting.