Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Buttons not working on 2nd PS2 controller. #35

Closed
takeriveter28 opened this issue Mar 18, 2025 · 7 comments
Closed

Buttons not working on 2nd PS2 controller. #35

takeriveter28 opened this issue Mar 18, 2025 · 7 comments

Comments

@takeriveter28
Copy link

As the title says,

I've connected two dualshock 2 controllers to a pro micro.

The 1st controller works flawlessly, including analog sticks.

The 2nd controller's buttons do not work, only the analog sticks work.

Here's my code:

#include <PsxControllerBitBang.h>
#include <Joystick.h>

// Pin assignments for the first controller
const byte PIN_PS2_ATT1 = 6;
const byte PIN_PS2_CMD1 = 7;
const byte PIN_PS2_DAT1 = 8;
const byte PIN_PS2_CLK1 = 5;

// Pin assignments for the second controller
const byte PIN_PS2_ATT2 = 15;
const byte PIN_PS2_CMD2 = 14;
const byte PIN_PS2_DAT2 = 16;
const byte PIN_PS2_CLK2 = A0;

const unsigned long POLLING_INTERVAL = 1000U / 50U;
#define ENABLE_SERIAL_DEBUG

#define JOYSTICK_COUNT 2  // We are working with two PS2 controllers

// Declare Joystick array for two controllers
Joystick_ Joystick[JOYSTICK_COUNT] = {
  Joystick_(0x03, JOYSTICK_TYPE_JOYSTICK, 16, 0, true, true, false, true, true, false, false, false, false, false, false),  // First PS2 controller
  Joystick_(0x04, JOYSTICK_TYPE_JOYSTICK, 16, 0, true, true, false, true, true, false, false, false, false, false, false)   // Second PS2 controller
};

PsxControllerBitBang<PIN_PS2_ATT1, PIN_PS2_CMD1, PIN_PS2_DAT1, PIN_PS2_CLK1> psx1;
PsxControllerBitBang<PIN_PS2_ATT2, PIN_PS2_CMD2, PIN_PS2_DAT2, PIN_PS2_CLK2> psx2;

#ifdef ENABLE_SERIAL_DEBUG
  #define dstart(spd) do {Serial.begin (spd); while (!Serial) {digitalWrite (LED_BUILTIN, (millis () / 500) % 2);}} while (0);
  #define debug(...) Serial.print (__VA_ARGS__)
  #define debugln(...) Serial.println (__VA_ARGS__)
#else
  #define dstart(...)
  #define debug(...)
  #define debugln(...)
#endif

boolean haveController1 = false;
boolean haveController2 = false;

void setup() {
  // Initialize each joystick
  for (int i = 0; i < JOYSTICK_COUNT; i++) {
    Joystick[i].begin(false);  // Set to false for manual mode
    Joystick[i].setXAxisRange(ANALOG_MIN_VALUE, ANALOG_MAX_VALUE);
    Joystick[i].setYAxisRange(ANALOG_MIN_VALUE, ANALOG_MAX_VALUE);
    Joystick[i].setRxAxisRange(ANALOG_MIN_VALUE, ANALOG_MAX_VALUE);
    Joystick[i].setRyAxisRange(ANALOG_MIN_VALUE, ANALOG_MAX_VALUE);
  }

  pinMode(LED_BUILTIN, OUTPUT);
  dstart(115200);  // Start serial communication for debugging
  debugln(F("Ready!"));
}

void loop() {
  static unsigned long last = 0;

  if (millis() - last >= POLLING_INTERVAL) {
    last = millis();

    // Handle first controller (psx)
    if (!haveController1) {
      if (psx1.begin()) {
        debugln(F("Controller 1 found!"));
        if (!psx1.enterConfigMode()) {
          debugln(F("Cannot enter config mode"));
        } else {
          if (!psx1.enableAnalogSticks()) {
            debugln(F("Cannot enable analog sticks"));
          }
          if (!psx1.exitConfigMode()) {
            debugln(F("Cannot exit config mode"));
          }
        }
        haveController1 = true;
      }
    } else {
      if (!psx1.read()) {
        debugln(F("Controller 1 lost"));
        haveController1 = false;
      } else {
        byte x, y;
        // Update button states for controller 1
        Joystick[0].setButton(0, psx1.buttonPressed(PSB_TRIANGLE));
        Joystick[0].setButton(1, psx1.buttonPressed(PSB_CROSS));
        Joystick[0].setButton(2, psx1.buttonPressed(PSB_SQUARE));
        Joystick[0].setButton(3, psx1.buttonPressed(PSB_CIRCLE));
        Joystick[0].setButton(4, psx1.buttonPressed(PSB_L1));
        Joystick[0].setButton(5, psx1.buttonPressed(PSB_R1));
        Joystick[0].setButton(6, psx1.buttonPressed(PSB_L2));
        Joystick[0].setButton(7, psx1.buttonPressed(PSB_R2));
        Joystick[0].setButton(8, psx1.buttonPressed(PSB_SELECT));
        Joystick[0].setButton(9, psx1.buttonPressed(PSB_START));
        Joystick[0].setButton(10, psx1.buttonPressed(PSB_L3));
        Joystick[0].setButton(11, psx1.buttonPressed(PSB_R3));
        Joystick[0].setButton(12, psx1.buttonPressed(PSB_PAD_UP));
        Joystick[0].setButton(13, psx1.buttonPressed(PSB_PAD_DOWN));
        Joystick[0].setButton(14, psx1.buttonPressed(PSB_PAD_LEFT));
        Joystick[0].setButton(15, psx1.buttonPressed(PSB_PAD_RIGHT));

        // Update axes for controller 1
        if (psx1.getLeftAnalog(x, y)) {
          Joystick[0].setXAxis(x);
          Joystick[0].setYAxis(y);
        }
        if (psx1.getRightAnalog(x, y)) {
          Joystick[0].setRxAxis(x);
          Joystick[0].setRyAxis(y);
        }

        // Send the state for controller 1
        Joystick[0].sendState();
      }
    }

    // Handle second controller (psx2)
    if (!haveController2) {
      if (psx2.begin()) {
        debugln(F("Controller 2 found!"));
        if (!psx2.enterConfigMode()) {
          debugln(F("Cannot enter config mode"));
        } else {
          if (!psx2.enableAnalogSticks()) {
            debugln(F("Cannot enable analog sticks"));
          }
          if (!psx2.exitConfigMode()) {
            debugln(F("Cannot exit config mode"));
          }
        }
        haveController2 = true;
      }
    } else {
      if (!psx2.read()) {
        debugln(F("Controller 2 lost"));
        haveController2 = false;
      } else {
        byte x, y;
        // Update button states for controller 2
        Joystick[1].setButton(0, psx2.buttonPressed(PSB_TRIANGLE));
        Joystick[1].setButton(1, psx2.buttonPressed(PSB_CROSS));
        Joystick[1].setButton(2, psx2.buttonPressed(PSB_SQUARE));
        Joystick[1].setButton(3, psx2.buttonPressed(PSB_CIRCLE));
        Joystick[1].setButton(4, psx2.buttonPressed(PSB_L1));
        Joystick[1].setButton(5, psx2.buttonPressed(PSB_R1));
        Joystick[1].setButton(6, psx2.buttonPressed(PSB_L2));
        Joystick[1].setButton(7, psx2.buttonPressed(PSB_R2));
        Joystick[1].setButton(8, psx2.buttonPressed(PSB_SELECT));
        Joystick[1].setButton(9, psx2.buttonPressed(PSB_START));
        Joystick[1].setButton(10, psx2.buttonPressed(PSB_L3));
        Joystick[1].setButton(11, psx2.buttonPressed(PSB_R3));
        Joystick[1].setButton(12, psx2.buttonPressed(PSB_PAD_UP));
        Joystick[1].setButton(13, psx2.buttonPressed(PSB_PAD_DOWN));
        Joystick[1].setButton(14, psx2.buttonPressed(PSB_PAD_LEFT));
        Joystick[1].setButton(15, psx2.buttonPressed(PSB_PAD_RIGHT));

        // Update axes for controller 2
        if (psx2.getLeftAnalog(x, y)) {
          Joystick[1].setXAxis(x);
          Joystick[1].setYAxis(y);
        }
        if (psx2.getRightAnalog(x, y)) {
          Joystick[1].setRxAxis(x);
          Joystick[1].setRyAxis(y);
        }

        // Send the state for controller 2
        Joystick[1].sendState();
      }
    }
  }
}

I'm using Arduino IDE v2.3.4.
I'm using the latest git version of all 3 libraries: PsxNewLib, DigitalIO, ArduinoJoystick

I got my first pro micro and arduino UNO yesterday, so I'm an absolute newb at this.
Any help or suggestions regarding this is much appreciated :D

@SukkoPera
Copy link
Owner

At a first glance I don't see anything that could cause that behaviour, the code looks correct to me.

I suggest that you print psx2.getButtonWord() in order to see if the button values are correct in there, in which case the problem would lie in the Joystick library.

You might also try using JOYSTICK_TYPE_GAMEPAD.

Oh, and I assume you have already tried to swap the controllers and made sure that the problem is not in the controller itself.

On a side note, there is no need to use different pins for the two controllers. The CMD, DAT and CLK can be shared among all the controllers, only the ATT line must be different for every controller.

@takeriveter28
Copy link
Author

takeriveter28 commented Mar 19, 2025

I followed your advice and changed to using shared pins and JOYSTICK_TYPE_GAMEPAD. This did mess up my button mapping (Tested with psx1, since psx2's buttons don't work). Tested here: https://www.onlinemictest.com/controller-tester
What's the difference between JOYSTICK_TYPE_JOYSTICK, JOYSTICK_TYPE_GAMEPAD, JOYSTICK_TYPE_MULTIAXIS ?
My button mapping is same on _JOYSTICK & _MULTIAXIS but changes when _GAMEPAD is used.

I also tested each controller separately and they both worked on psx1 interface.
Though, one of my controllers is the H variant, and the other one is the A variant.
I don't know if that's a factor or not.

Do you have an easy way to map each of the buttons or atleast know which number from 0-15 corresponds to which buttons on the dualshock 2 controller ?
(I previously mapped all the buttons mostly by trial and error.)

Now, for the psx2.getButtonWord() command, I can confirm that even when the controller buttons do not work on the pc, their data does show up in the serial monitor !

Code Snippet:

debug(F("Controller 2 Button States: "));
debugln(psx2.getButtonWord(), BIN);

 // Send the state for controller 2
 Joystick[1].sendState();
}

Output Snippet:

Controller 2 Button States: 0
Controller 2 Button States: 0
Controller 2 Button States: 0
Controller 2 Button States: 0
Controller 2 Button States: 0
Controller 2 Button States: 110000000
Controller 2 Button States: 110000000
Controller 2 Button States: 110000000
Controller 2 Button States: 110000000
Controller 2 Button States: 110000001
Controller 2 Button States: 110000001
Controller 2 Button States: 110000001
Controller 2 Button States: 110000001
Controller 2 Button States: 110000001
Controller 2 Button States: 110000001
Controller 2 Button States: 110000001
Controller 2 Button States: 10000001
Controller 2 Button States: 10000001
Controller 2 Button States: 10000001
Controller 2 Button States: 10000001
Controller 2 Button States: 10000000
Controller 2 Button States: 10000000
Controller 2 Button States: 10000000
Controller 2 Button States: 0
Controller 2 Button States: 1000000100000000
Controller 2 Button States: 1000000000000000
Controller 2 Button States: 1000000000000000
Controller 2 Button States: 1000000000000000
Controller 2 Button States: 1000000000000000
Controller 2 Button States: 1000000000010000
Controller 2 Button States: 1000000000010000

@SukkoPera
Copy link
Owner

SukkoPera commented Mar 20, 2025

That means that PsxNewLib is doing the right thing, so the problem either lies in the Joystick library or somewhere else.

Now I cannot remember exactly why I picked that particular joystick library, but I'm sure there are many others around, so you might try to switch to a different one and adapt the code.

Although, maybe there is something else to try first: have a look here (maybe also here and/or here). I had to do something similar for another private board that creates several USB joystick devices.

Please report back your findings!

@takeriveter28
Copy link
Author

Yes, I talked with ArduinoJoystickLibrary maintainer too. Seems like this might be the cause of the issue. I'll look into it and report my findings.

BTW, I just successfully tested the rumble feature, it works well (though with some delay in starting the rumble after pressing the button).

How do I add this functionality to the psx2usb code ? I'm searching for any example sketches on the internet and I'd appreciate your input.

@takeriveter28
Copy link
Author

Update:

The issue has been solved !
It was the usb quirks feature.
I enabled it and now I can connect even 5 controllers simultaneously (though the inputs get a little choppy, probably because I used the same 3 signal lanes for all 5 controllers).

Thanks for the help ! :D

@takeriveter28
Copy link
Author

BTW, I'm having trouble with the level shifter.
The 1k pull-up resistors should be on ATT, CMD, DAT and CLK lines right ?

@SukkoPera
Copy link
Owner

SukkoPera commented Mar 23, 2025

Glad you solved the issue!

There is no problem in sharing the signal lines even among 1000 controllers, as only one is read at a time anyway and the others are in high-impedence. If they seem a bit sloppy, you probably have to check the time interval at which you are reading them and make sure that you do it at least 50-60 times per second per controller. Using Hardware SPI might help a bit and is the recommended way, in any case.

Make sure to also cable the ACK pin, as that will be used one day and will make readings faster.

No idea about rumble, sorry. I am not very interested in that.

For the level shifter, check out the schematics of PsxControllerShield. It can be simplified, but that is definitely working. Also note that only a few MOSFETs will work, you can't just use a random one in that configuration. Stick to BSS138.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants