52

I am trying to run some code that will allow the user to control with an Xbox Controller. I have it working with the Xbox 360 controller using Pygame. Then when I try to use the Xbox one controller and it is able to read the as "connected" but it doesn't read the actual button presses.

I tried running the joystick analyzer found on the Pygame website and it shows it connected again but no button input is taken.

enter image description here

The code for this can be found at the bottom of this documentation page: https://www.pygame.org/docs/ref/joystick.html

import pygame


# Define some colors.
BLACK = pygame.Color('black')
WHITE = pygame.Color('white')


# This is a simple class that will help us print to the screen.
# It has nothing to do with the joysticks, just outputting the
# information.
class TextPrint(object):
    def __init__(self):
        self.reset()
        self.font = pygame.font.Font(None, 20)

    def tprint(self, screen, textString):
        textBitmap = self.font.render(textString, True, BLACK)
        screen.blit(textBitmap, (self.x, self.y))
        self.y += self.line_height

    def reset(self):
        self.x = 10
        self.y = 10
        self.line_height = 15

    def indent(self):
        self.x += 10

    def unindent(self):
        self.x -= 10


pygame.init()

# Set the width and height of the screen (width, height).
screen = pygame.display.set_mode((500, 700))

pygame.display.set_caption("My Game")

# Loop until the user clicks the close button.
done = False

# Used to manage how fast the screen updates.
clock = pygame.time.Clock()

# Initialize the joysticks.
pygame.joystick.init()

# Get ready to print.
textPrint = TextPrint()

# -------- Main Program Loop -----------
while not done:
    #
    # EVENT PROCESSING STEP
    #
    # Possible joystick actions: JOYAXISMOTION, JOYBALLMOTION, JOYBUTTONDOWN,
    # JOYBUTTONUP, JOYHATMOTION
    for event in pygame.event.get(): # User did something.
        if event.type == pygame.QUIT: # If user clicked close.
            done = True # Flag that we are done so we exit this loop.
        elif event.type == pygame.JOYBUTTONDOWN:
            print("Joystick button pressed.")
        elif event.type == pygame.JOYBUTTONUP:
            print("Joystick button released.")

    #
    # DRAWING STEP
    #
    # First, clear the screen to white. Don't put other drawing commands
    # above this, or they will be erased with this command.
    screen.fill(WHITE)
    textPrint.reset()

    # Get count of joysticks.
    joystick_count = pygame.joystick.get_count()

    textPrint.tprint(screen, "Number of joysticks: {}".format(joystick_count))
    textPrint.indent()

    # For each joystick:
    for i in range(joystick_count):
        joystick = pygame.joystick.Joystick(i)
        joystick.init()

        try:
            jid = joystick.get_instance_id()
        except AttributeError:
            # get_instance_id() is an SDL2 method
            jid = joystick.get_id()
        textPrint.tprint(screen, "Joystick {}".format(jid))
        textPrint.indent()

        # Get the name from the OS for the controller/joystick.
        name = joystick.get_name()
        textPrint.tprint(screen, "Joystick name: {}".format(name))

        try:
            guid = joystick.get_guid()
        except AttributeError:
            # get_guid() is an SDL2 method
            pass
        else:
            textPrint.tprint(screen, "GUID: {}".format(guid))

        # Usually axis run in pairs, up/down for one, and left/right for
        # the other.
        axes = joystick.get_numaxes()
        textPrint.tprint(screen, "Number of axes: {}".format(axes))
        textPrint.indent()

        for i in range(axes):
            axis = joystick.get_axis(i)
            textPrint.tprint(screen, "Axis {} value: {:>6.3f}".format(i, axis))
        textPrint.unindent()

        buttons = joystick.get_numbuttons()
        textPrint.tprint(screen, "Number of buttons: {}".format(buttons))
        textPrint.indent()

        for i in range(buttons):
            button = joystick.get_button(i)
            textPrint.tprint(screen,
                             "Button {:>2} value: {}".format(i, button))
        textPrint.unindent()

        hats = joystick.get_numhats()
        textPrint.tprint(screen, "Number of hats: {}".format(hats))
        textPrint.indent()

        # Hat position. All or nothing for direction, not a float like
        # get_axis(). Position is a tuple of int values (x, y).
        for i in range(hats):
            hat = joystick.get_hat(i)
            textPrint.tprint(screen, "Hat {} value: {}".format(i, str(hat)))
        textPrint.unindent()

        textPrint.unindent()

    #
    # ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
    #

    # Go ahead and update the screen with what we've drawn.
    pygame.display.flip()

    # Limit to 20 frames per second.
    clock.tick(20)

# Close the window and quit.
# If you forget this line, the program will 'hang'
# on exit if running from IDLE.
pygame.quit()

Does anyone have any insight into why this is?

robni
  • 904
  • 2
  • 6
  • 20
Rjbeckwith
  • 720
  • 8
  • 16
  • @Pygasm This is the code found on the pygame documentation page. https://www.pygame.org/docs/ref/joystick.html. I thought I would start there because this test code has always worked for my Xbox 360 controller but now won't work for the Xbox One. – Rjbeckwith Apr 18 '18 at 04:31
  • Well to me it seems that the joystick code was designed not for an xbox one controller, most likely pygame is trying to read from gates or pins that arent exactly there anymore and ends up reading the wrong input, you could try reading from serial manually and detecting the output of the controller, although that may a bit advanced for you. – Mercury Platinum Apr 18 '18 at 16:30
  • @Pygasm That is what I was thinking too. The strange thing is that there are other posts about specific things with Xbox One controllers and Pygame out there. For Example: https://stackoverflow.com/questions/28132156/how-can-i-set-the-range-for-xbox-one-controller-triggers-using-pygame So it seems some people are getting it to work out there. – Rjbeckwith Apr 19 '18 at 04:07
  • @Rjbeckwith From the question you mentioned I managed to track down the code he used to get this working at https://github.com/ryanvade/robotproject/blob/master/xboneControllerTest.py. I can't see what changes he has made for his to work and yours to not though. Try running his code on pygame 1.9.2 and see what you get??? – Ben Jul 12 '18 at 19:41
  • 4
    have you installed the controller drivers for x-box one? – Glitch__ Jun 11 '20 at 07:34
  • @Rjbeckwith I have used the Xbox One Controller in pygame many times. Can you display the code? – SamTheProgrammer May 03 '21 at 10:42
  • 1
    @PythonProgrammer This isn't a pressing issue for me anymore. But in case others are interested in getting a solution I added the code. The code was just the example code from the link I provided previously. – Rjbeckwith May 12 '21 at 18:18
  • 1) Does it work in any other context? 2) Is it USB or BT? 3) In what order do you connect the controller and start the program? – firelynx Oct 05 '21 at 08:02
  • in [that code](https://gitlab.com/nicolalandro/tello_code_sample/-/blob/master/joystik_controller/joystick_and_video.py) the Xbox One joystick work, the class used is JoystickXONE at line 147, maybe it can be usefull. – Nicola Landro Dec 25 '21 at 16:55
  • Check out this answer - https://stackoverflow.com/a/53991551/2570277 – Nick May 11 '22 at 11:59
  • For older linux kernel versions I had to use xboxdrv https://github.com/xboxdrv/xboxdrv – Luiz Amaral Aug 25 '22 at 10:10
  • have you installed pygame2 ? – NoBlockhit Aug 25 '22 at 11:07

3 Answers3

1

Bluetooth may not be enabled yet try enabling it or checking the controllers batteries!

1

I have tried this same script with an Xbox One Series 2 Controller and can confirm that it works flawlessly. I connected the controller to the PC with the charging cable, not wirelessly (because I have an Xbox in the same room).

You should try the same first and be able to open the Xbox Game Bar by holding down the mainXbutton button, otherwise check your Xbox settings on the PC and update your drivers from the device manager (while wired).

Also, make sure that you have the last Pygame version, I tried with 2.1.2 on Windows 10. Hope this give you a hint.

CreepyRaccoon
  • 826
  • 1
  • 9
  • 19
0

try running a controller testing tool if it doesn't work there then it is probably a problem with the controller also try reinstalling pygame and checking if you have drivers correctly installed

pi_py_pie
  • 1
  • 1